C#使用XPathSelectElements解析带命名空间XML取值失败问题
问题原因
查询失败的核心问题是你没有处理XML中声明的默认命名空间。
你的XML根节点entry上声明了xmlns="http://www.w3.org/2005/Atom",这是默认命名空间,所有没有显式加前缀的节点(比如<entry>、<link>)都归属于这个命名空间。你只注册了前缀A对应的Autodesk命名空间,XPath语句里把entry、link当成了无命名空间的节点,自然匹配不到目标内容。
修复代码
只需要给默认命名空间也注册一个自定义前缀,再调整XPath路径里对应节点的前缀即可:
XDocument XprojectXMLfile = XDocument.Load(projectXMLfilePath); var nsMgr = new XmlNamespaceManager(new NameTable()); // 注册原有A前缀对应的Autodesk命名空间 nsMgr.AddNamespace("A", "urn:schemas-autodesk-com:partatom"); // 给默认Atom命名空间注册前缀,前缀名可以自定义,比如atom nsMgr.AddNamespace("atom", "http://www.w3.org/2005/Atom"); // XPath中属于默认命名空间的entry、link节点都加上atom前缀 var revitVersionNode = XprojectXMLfile.XPathSelectElement( "/atom:entry/atom:link/A:design-file/A:product-version", nsMgr ); // 取节点值即为目标结果2021,加空判断避免XML格式异常时触发报错 string revitVersion = revitVersionNode?.Value;
补充说明
- 你原来用的
XPathSelectElements会返回所有匹配节点的集合,这里目标节点只有一个,用XPathSelectElement取单个节点更方便。 - XML里只要声明了不带前缀的默认命名空间,所有未单独覆盖命名空间的子节点都会继承这个命名空间,XPath查询时必须给这类命名空间注册前缀才能正常匹配,这是带命名空间XML解析最常见的踩坑点。
内容的提问来源于stack exchange,提问作者wee hee
相关产品推荐
相关产品推荐

