发布于2026-07-18 阅读(0)
扫一扫,手机访问
在C#开发中,处理XML数据是家常便饭。但不少开发者一上来就踩坑,要么用XmlDocument这种老古董,要么硬写Elements()链式调用,结果遇到注释、空格或命名空间就挂掉。其实,XDocument搭配Descendants()才是稳妥的起点,它能穿透所有层级,跳过非元素节点,稳定可靠。

简单来说,XDocument + Descendants() 是最稳的起点,别碰 XmlDocument 或硬写 Elements() 链式调用——前者过时,后者一遇到注释、空格、命名空间就失效。
Descendants() 查任意层级节点,不依赖结构深度XML 常有注释、处理指令、换行文本节点,Elements() 只查直接子节点,一旦 Root 下多了一行空格或一个 ,doc.Root.Elements("Item") 就返回空。而 Descendants("Item") 会穿透所有层级,跳过非元素节点,结果稳定。
XDocument.Load("file.xml") 或 XDocument.Parse(xmlString) 开始,不是 XmlDocumentdoc.Root.Descendants("Product")——Root 可能为 null(比如 XML 声明后直接是注释),直接用 doc.Descendants("Product")Book),且确定结构干净,Elements() 略快;但日常开发中,容错比这点性能重要得多XNamespace像 这种,doc.Descendants("item") 永远为空——字符串匹配对不上命名空间隐式前缀。
XNamespace ns = doc.Root?.GetDefaultNamespace() ?? "";doc.Descendants(ns + "item")xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"),用 doc.Root?.GetNamespaceOfPrefix("xsi") 获取对应 XNamespaceElement()、Attribute()、Where() 都查不到东西,错误静默,极难排查Where() + Attribute() / Element() 写条件,别字符串匹配想查 ?别写 .Where(x => x.ToString().Contains("shipped"))——它会把整个节点序列化成字符串再搜,慢、不准、还可能误中子节点内容。
doc.Descendants("order").Where(x => x.Attribute("status")?.Value == "shipped")doc.Descendants("book").Where(x => x.Element("Author")?.Value == "Jon Skeet")doc.Descendants("book").Where(x => x.Element("Price") != null)Attribute() 和 Element() 返回 XAttribute / XElement?,安全调用 ?.Value,避免 NullReferenceExceptionValue 永远有值Element("Title").Value 在节点不存在时抛 NullReferenceException;Attribute("Id").Value 同理。LINQ to XML 不自动补默认值。
(string)node.Element("Title") —— 转换失败返回 null,不抛异常(int?)node.Attribute("Id"),null 表示缺失或解析失败.Any():if (doc.Descendants("Book").Any()) { ... },比 .Count() > 0 快(不用遍历全部)doc.Descendants("Book") 结果缓存为 IEnumerable 或 List,避免重复遍历命名空间和空值处理是实际项目里最常卡住人的两点,其他都好调——但一旦 XML 带了 xmlns,或者某条数据缺了 Author 字段,没做安全转换的代码就会在生产环境突然崩掉。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8