xmldocument.save() 默认不缩进,因底层未使用带 formatting.indented 的 xmlwriter;需手动创建 xmlwriter 并设置 indent 和 indentchars 才生效。

XmlDocument.Save() 不缩进?检查 XmlWriterSettings 是否传对了
默认调用 doc.Save(stream) 或 doc.Save(path) 时,XML 是紧凑格式(无换行、无缩进),不是 XmlDocument 没缩进功能,而是它底层没用带格式化的 XmlWriter。
真正控制缩进的是 XmlWriter,而 XmlDocument.Save() 的重载里只有接受 XmlWriter 那个才生效缩进设置。直接传文件路径或 Stream 的版本会创建默认 writer,忽略你的 Formatting.Indented。
- ✅ 正确做法:手动构造
XmlWriter,显式设Formatting = Formatting.Indented - ❌ 错误写法:
doc.Save("out.xml")后再指望它自动缩进 —— 它不会 - ⚠️ 注意:
XmlWriterSettings.IndentChars默认是两个空格,如需 Tab 需手动设IndentChars = "t"
为什么 XmlDocument.PreserveWhitespace = false 还是不缩进?
这个属性只影响「读入时是否保留原有空白」,和「保存时生成空白」完全无关。设成 true 反而可能破坏你想要的缩进效果,因为原始文本里的空格/换行会被原样保留,干扰 XmlWriter 的自动排版逻辑。
-
PreserveWhitespace是输入控制开关,不是输出格式开关 - 保存缩进与否,只取决于你用不用带
Formatting.Indented的XmlWriter - 如果源 XML 本身有大量手写空白,又设了
PreserveWhitespace = true,输出可能混杂人工空格和自动生成缩进,看起来错乱
缩进后中文标签名或属性值出现乱码?查 Encoding 是否匹配
用 XmlWriter 保存时,如果没指定编码,它默认用 UTF-8 —— 看似没问题,但 windows 记事本等工具常按系统 ANSI 编码打开 UTF-8 文件(无 bom),导致中文显示为乱码。
- 解决方法:在
XmlWriterSettings中设Encoding = new UTF8Encoding(true)(true表示写 BOM) - 或者改用
new StreamWriter(path, false) { Encoding = Encoding.UTF8 }包一层,再传给XmlWriter.Create() - 别依赖
doc.Save(String)的隐式编码行为,它不保证写 BOM
性能敏感场景下,缩进要不要关?
开启缩进会让 XmlWriter 多做层级跟踪、换行插入、空格拼接,实测大文档(>1MB)保存耗时可能增加 15–30%。但对绝大多数配置文件、中小数据交换场景,这点开销可忽略。
- CI/CD 自动化生成 XML?建议关缩进,加快构建速度,且机器读取不需要可读性
- 供人阅读的调试输出、导出配置?必须开,否则嵌套深了根本没法看
- 注意:
Indent = true本身不慢,慢的是配合IndentChars = "t"+ 深层嵌套(每层都拼字符串)
缩进不是“开了就一定好”,关键看谁在读 —— 人要可读性,机器只要合法 XML。漏掉这一点,容易在日志里看到一堆没换行的长行 XML,排查时多花三分钟找错位标签。