通过 XPath 在任意深度选择 XML 节点

2024-01-02

拥有一个 XML 文档,我想要获取具有特定名称的第一个节点,无论它包含在哪个嵌套深度中。

我尝试了几件事但没有成功:

var node1 = doc.SelectSingleNode(@"//Shortcut");
var node2 = doc.SelectSingleNode(@"/*/Shortcut");
var node3 = doc.SelectSingleNode(@"//*/Shortcut");
var node4 = doc.SelectSingleNode(@"*/Shortcut");
...

每次调用都会产生一个NULL node.

我认为这应该是一些简单的 XPath 语法。你能帮助我吗?

(如果这很重要:XML 文档是一个输入文件WiX http://wix.sourceforge.net/项目,因此可能涉及一些命名空间问题?!?)。

Edit

我还尝试了以下方法:

var nsm = new XmlNamespaceManager(doc.NameTable);
nsm.AddNamespace(string.Empty, @"http://schemas.microsoft.com/wix/2006/wi");
nsm.AddNamespace(@"ns", @"http://schemas.microsoft.com/wix/2006/wi");

和...一起:

var node1 = doc.SelectSingleNode(@"//Shortcut", nsm);
var node2 = doc.SelectSingleNode(@"/*/Shortcut", nsm);
var node3 = doc.SelectSingleNode(@"//*/Shortcut", nsm);
var node4 = doc.SelectSingleNode(@"*/Shortcut", nsm);
...

导致相同的结果。

编辑 2 - 解决方案

我找到了解决方案:

var nsm = new XmlNamespaceManager(doc.NameTable);
nsm.AddNamespace(string.Empty, @"http://schemas.microsoft.com/wix/2006/wi");
nsm.AddNamespace(@"ns", @"http://schemas.microsoft.com/wix/2006/wi");

and then

var node1 = doc.SelectSingleNode(@"//ns:Shortcut", nsm);

这成功了。


精确选择所需节点(并且没有其他任何内容)的 XPath 表达式是:

(//x:Shortcut)[1]

所以,使用:

doc.SelectNodes("(//x:Shortcut)[1]", someNamespaceManager)

where

前缀"x"绑定到命名空间"http://schemas.microsoft.com/wix/2006/wi"

in someNamespaceManager

这比建议的解决方案(使用SelectSingleNode()),因为可以轻松调整它以选择 XML 文档中的第 N 个想要的节点.

例如:

   (//x:Shortcut)[3]

选择第三个(按文档顺序)x:Shortcut元素,以及

   (//x:Shortcut)[last()]

选择最后一个(按文档顺序)x:ShortcutXML 文档中的元素。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 XPath 在任意深度选择 XML 节点 的相关文章

随机推荐