优先用XDocument解析小到中等XML(新手推荐),XmlDocument适用于老项目或XPath需求,大文件用XmlReader流式处理,结构固定时用XmlSerializer反序列化。

直接说结论:用 XmlDocument 或 XDocument,别碰 XmlTextReader 手动解析——除非你真在处理 GB 级流式 XML 且内存受限。
用 XDocument 解析小到中等 XML(推荐新手)
这是最直观、LINQ 支持好、语法干净的方式,适合配置文件、API 返回体、本地数据文件等常见场景。
- 加载方式简单:
XDocument.Load("config.xml")或XDocument.Parse(xmlString) - 查节点用
.Descendants("item")或.Root.Element("name"),支持链式调用 - 取值别直接用
.Value——空元素会抛NullReferenceException,改用.Element("id")?.Value或(string)elem.Element("id")(后者对 null 安全) - 注意命名空间:如果 XML 带
xmlns="http://example.com/ns",必须用XNamespace ns = "http://example.com/ns"; doc.Root.Element(ns + "data")
用 XmlDocument 解析但需兼容老项目或 XPath
如果你维护的是 .NET Framework 4.0 以前的代码,或者必须用 XPath 查询(比如 //book[@category='web']),XmlDocument 更合适。
- 加载后用
doc.SelectNodes("//user"),返回XmlNodeList,遍历时要判空:if (node.Attributes["id"] != null) -
GetElementsByTagName("name")不递归,只查直接子节点;要全树匹配得用SelectNodes(".//name") - 修改后保存:必须调用
doc.Save("out.xml"),否则只是内存操作 - 性能上比
XDocument略低,DOM 树更重,但 XPath 功能更成熟
反序列化 XML 到对象(当结构固定时最快)
如果你的 XML 是规范的、和 C# 类一一对应(比如来自 WebService 或自定义配置),XmlSerializer 能省掉 80% 的解析胶水代码。
- 类必须加
[XmlRoot("root")]、字段加[XmlElement("id")]或[XmlAttribute("type")] - 反序列化:
var serializer = new XmlSerializer(typeof(Config)); using var reader = new StringReader(xmlString); var config = (Config)serializer.Deserialize(reader);
- 不支持复杂逻辑(如字段名映射不一致、条件忽略),遇到
XmlIgnore或XmlArrayItem要小心类型匹配 - 不能处理含混合内容(text + element)的节点,会报
InvalidOperationException
常见崩溃点和绕过方法
这些不是“不会写”,而是上线后突然炸掉的典型原因:
-
XmlException: Data at the root level is invalid→ XML 开头有 BOM 或空白符,用File.ReadAllText(path, Encoding.UTF8)显式指定编码,或先xmlString.TrimStart() - 中文乱码:确认 XML 声明是
<?xml version="1.0" encoding="utf-8"?>,且读取时用的Encoding.UTF8,别依赖系统默认 - 大文件 OOM:别用
XDocument.Load()加载几百 MB 的 XML,换XmlReader.Create()流式读取,配合ReadToFollowing()跳过无关节点 - XML 中有
:XDocument会自动转成文本节点,但XmlDocument需要判断node.NodeType == XmlNodeType.CDATA才能安全取值
真正难的不是选哪个 API,而是拿到 XML 后第一眼先看有没有命名空间、编码声明、CDATA、注释嵌套——这些细节不确认,写一百行 LINQ 也可能在第 101 行崩掉。


















