使用XDocument读取带命名空间XML需显式注册XmlNamespaceManager;.NET 6+中SelectNodes已过时,应改用XPathNavigator或Descendants+LINQ;访问属性须用?.Value ?? 默认值防空引用。
用
+
读取带命名空间的 XML 属性会失败
直接调用
在多数情况下能工作,但只要 XML 声明了命名空间(比如
),默认就查不到任何东西——XPath 查询器不会自动绑定前缀,也不会把无前缀的查询当作默认命名空间处理。
解决办法是显式注册命名空间管理器:
必须用
注册前缀(哪怕只是临时起个
)
对象不能直接传给 XPath 方法,必须通过
如果 XML 有多个命名空间,每个都要
,且 XPath 中必须使用对应前缀
和
在 .NET 6+ 已被标记为过时
很多老教程还在用
,但在 .NET 6 及以后,这些方法已标为
,编译会警告,且底层依赖已逐步移除。继续用可能在后续版本彻底失效。
替代路径只有两条:
坚持用 DOM 模型:改用
+
+
组合(适合简单条件)
需要 XPath 表达能力:用
获取
,再调用其
或
例如按属性筛选节点:
注意:
不支持 LINQ 链式调用,也不返回
,需手动提取值。
用
替代 XPath 查询更安全、更易调试
当查询逻辑不复杂(比如“找第一个
下的
属性”),硬写 XPath 反而容易出错:斜杠漏写、大小写不一致、属性名拼错,错误信息又只报“未找到节点”,没上下文。
C知道
CSDN推出的一款AI技术问答工具
下载
用 LINQ to XML 更直白:
每一步都可单独打断点验证是否为空
编译器能检查元素名、属性名是否存在(拼错会直接报错)
不需要处理命名空间前缀或
性能差异在千级节点内几乎不可测
仅当需要通配符(
)、轴步(
)或函数(
)时,才值得切回 XPath。
读取空属性或不存在属性时,别直接调
像
这种写法,一旦属性缺失,会抛
,而不是返回
或空字符串。
正确姿势只有两种:
用空合并操作符:
用
的安全封装(.NET 6+ 推荐):
本身已是可空引用,配合
最简洁
不要写
——
对
返回空字符串,掩盖了属性缺失的事实,后期排查配置遗漏会非常麻烦。
XDocumentXPathSelectElementXElement.XPathSelectElement("//node/@attr")xmlns="http://example.com/ns"XDocument doc = XDocument.Load("data.xml");
XNamespace ns = "http://example.com/ns";
var manager = new XmlNamespaceManager(new NameTable());
manager.AddNamespace("x", ns.NamespaceName);
var element = doc.XPathSelectElement("/x:root/x:item", manager);
string value = element?.Attribute("id")?.Value;
XmlNamespaceManager"x"XNamespacemanagerAddNamespaceSelectNodesSelectSingleNodeXmlDocument.SelectNodes("//book[@category='fiction']")[Obsolete]XDocumentDescendants()Where()XDocument.CreateNavigator()XPathNavigatorSelect()SelectSingleNode()XDocument doc = XDocument.Load("books.xml");
XPathNavigator nav = doc.CreateNavigator();
XPathNodeIterator iter = nav.Select("//book[@category='fiction']");
while (iter.MoveNext())
{
string title = iter.Current.SelectSingleNode("title")?.Value;
string isbn = iter.Current.GetAttribute("isbn", "");
}
XPathNavigatorXElementDescendants().FirstOrDefault()configtimeoutXDocument doc = XDocument.Load("app.config");
string timeout = doc
.Descendants("config")
.Elements("connection")
.Attributes("timeout")
.FirstOrDefault()?.Value;
XmlNamespaceManager//following-sibling::contains(@class, 'active').Valueelement.Attribute("retryCount").ValueNullReferenceExceptionnullelement.Attribute("retryCount")?.Value ?? "0"Attribute().Valueelement.Attribute("retryCount")?.Value??element.Attribute("retryCount").ToString()ToString()null