xml保存无缩进是因xmlwritersettings默认indent=false,需显式设置indent=true并传入xmlwriter;缩进、换行、编码、空白处理四者须协同一致。

保存 XML 时没缩进?用 XmlWriterSettings 控制格式
默认用 XDocument.Save() 写文件,XML 是一行到底的——不是 bug,是默认关闭格式化的。真正起作用的是底层 XmlWriter 的设置,XDocument 自己不带“美化开关”。
必须显式构造 XmlWriter 并传入带缩进配置的 XmlWriterSettings:
var settings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\n",
NewLineHandling = NewLineHandling.Replace
};
using var writer = XmlWriter.Create("output.xml", settings);
doc.Save(writer);
-
Indent = true是必要条件,不设这个,其他都白搭 -
IndentChars建议用空格(" "或"\t"),别用混合或中文全角空格 -
NewLineChars设成"\n"更通用;Windows 默认"\r\n",跨平台读写可能出空行异常 - 别直接对
XDocument.ToString()格式化后再写文件——它不保证格式稳定,且会丢弃原始声明编码
Save() 直接写文件 vs XmlWriter 手动写:行为差异在哪
调用 doc.Save("path.xml") 实际内部用了最简 XmlWriterSettings(Indent=false),相当于跳过了格式化逻辑。而手动传 XmlWriter,你完全掌控序列化过程。
经过一段时间的开发,以及内部测试,同程网联盟景区新版程序正式发布推出,感谢广大联盟会员一直以来的支持与关注! 同程网联盟景区新版程序新功能介绍:1.统一的页面风格。页面风格将与随后推出的度假线路、酒店、机票以及融合版联盟程序风格保持一直;2.新增后台管理系统。可更加方便快捷的对网站进行个性化设置;3.动态与伪静态切换。后台操作,简单便捷;4.缓存管理。新增缓存,提高网站访问速度,后台可定期清理;5
- 直接
Save(string)无法指定编码(默认 UTF-8 无 BOM),但XmlWriter.Create(Stream, settings)可配合StreamWriter精确控制 - 如果 XML 里有
(CR)或混合换行符,NewLineHandling = Replace能统一归一化,否则缩进可能错位 - 大文件慎用
ToString()+File.WriteAllText():会把整个树转成字符串再写,内存翻倍,还可能触发OutOfMemoryException
中文内容乱码?检查 XmlWriterSettings.Encoding 和 BOM
即使设置了缩进,中文变问号或方块,大概率是编码没对齐。XML 声明里的 encoding="utf-8" 和实际字节流编码必须一致。
- 不要依赖
XmlWriterSettings.Encoding = Encoding.UTF8就万事大吉——.NET 6+ 默认 UTF-8 无 BOM,但某些老编辑器/系统认 BOM 才当 UTF-8 - 真要兼容旧工具,得用
new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)构造编码对象再传入XmlWriterSettings - 如果 XML 已含
<?xml version="1.0" encoding="gb2312"?>,但Settings.Encoding设了 UTF-8,保存后声明和内容编码就矛盾,解析器可能报Invalid character in the given encoding
为什么 PreserveWhitespace = true 有时反而让缩进失效
XDocument 加载时若设了 PreserveWhitespace = true,会把原始空白字符(包括换行、缩进)当作文本节点保留。后续再保存,XmlWriter 的缩进逻辑会被这些“残留空白”干扰,导致嵌套层级错乱或空行爆炸。
- 除非你明确需要保留用户手写的空格/换行(比如 XML 配置中内联的 SQL 或 JSON 片段),否则加载时别设
PreserveWhitespace = true - 已加载且开启了该选项的文档,可在保存前调用
doc.Descendants().Where(e => e.Nodes().All(n => n is XText t && string.IsNullOrWhiteSpace(t.Value))).Remove();清理冗余空白节点(谨慎使用,可能误删有意义的空文本) - 更稳妥的做法:加载时不用
PreserveWhitespace,靠XmlWriterSettings统一控制输出格式
缩进只是表象,真正要盯住的是三层一致性:加载时的空白策略、内存中节点结构的干净度、写出时 XmlWriterSettings 的编码与格式参数——漏掉任何一层,XML 文件看着就别扭。









