xmlserializer序列化时需通过xmlwritersettings.omitxmldeclaration=true并配合xmlwriter.create()调用serialize重载才能去掉xml声明;同时需注意utf-8 bom问题,应使用utf8encoding(false)避免。

XmlSerializer序列化时怎么去掉这行
直接设 XmlWriterSettings.OmitXmlDeclaration = true,但关键在——你得用 XmlWriter 构造器传进去,XmlSerializer 本身没有 OmitXmlDeclaration 属性。
常见错误是翻文档看到 XmlWriterSettings 有这个开关,就以为 XmlSerializer 也有同名属性,结果编译不过或毫无效果。
-
XmlSerializer确实不提供OmitXmlDeclaration属性,这是XmlWriterSettings的字段 - 必须显式创建
XmlWriter,把XmlWriterSettings传给它,再喂给Serialize() - 如果用
StreamWriter直接写入字符串/文件,没走XmlWriter,声明行永远删不掉
正确写法:用XmlWriterSettings + XmlWriter包装序列化流
核心是绕过 XmlSerializer.Serialize(Stream) 的默认行为,改用接受 XmlWriter 的重载。
示例(写入字符串):
var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = false, // 避免缩进带来额外换行(可选) Encoding = Encoding.UTF8 }; using var stringWriter = new StringWriter(); using var xmlWriter = XmlWriter.Create(stringWriter, settings); serializer.Serialize(xmlWriter, obj); // ← 必须用这个重载 string xml = stringWriter.ToString(); // 没有声明行
- 别漏掉
using,XmlWriter必须被正确 dispose 才能刷出内容 -
Encoding要和StringWriter或底层Stream一致,否则可能乱码 - 如果目标是文件,把
XmlWriter.Create("path.xml", settings)传进去即可
为什么不用XmlTextWriter?它已被标记为过时
XmlTextWriter 在 .NET Core / .NET 5+ 中已废弃,且不支持 OmitXmlDeclaration 的细粒度控制。
- 它只有构造函数里传
bool控制是否写声明,但该构造函数本身已过时 - 即使强行用,.NET 6+ 会警告
XmlTextWriter不推荐,且某些编码场景下行为不可靠 -
XmlWriter.Create()是唯一受支持、可配置的入口,兼容所有现代 .NET 版本
注意XML声明和BOM的区别:删了声明不代表没BOM
很多人以为去掉声明就“干净了”,结果发现文件开头还是多两个字节(EF BB),那是 UTF-8 BOM。这不是 XML 声明,而是 Encoding.UTF8 默认带 BOM 导致的。
- 解决方法:用
new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)替换Encoding.UTF8 - 或者写入文件时用
File.OpenWrite()+XmlWriter.Create(stream, settings),避免StreamWriter插入 BOM - 字符串内容本身不会有 BOM,只有写入文件时才需警惕
真正干净的 XML 输出,要同时关掉声明和 BOM;这两者常被混为一谈,但控制点完全不同。