使用 xmldocument 中的 xpath 选择注释之间的节点

本文关键字:之间 节点 注释 选择 xmldocument 中的 xpath 使用 | 更新日期: 2023-09-27 18:36:41

我正在尝试在评论之间获取节点。

例:

<Name>
  <First>a</First>
  <Last>b</Last>
</Name>
<!-- family names -->
<Name>
  <First>c</First>
  <Last>d</Last>
</Name>
<Name>
  <First>e</First>
  <Last>f</Last>
</Name>
<Name>
  <First>g</First>
  <Last>h</Last>
</Name>
<!-- family ends -->
<!-- other names -->
<Name>
  <First>i</First>
  <Last>j</Last>
</Name>
<Name>
  <First>k</First>
  <Last>l</Last>
</Name>
<!-- other ends -->

我希望能够选择注释系列名称和系列末尾之间的节点。用 xpath 尝试了几种方法,但我无法进一步选择所有评论节点。当我想选择包含值 x 的评论节点时,我没有得到任何结果。所以我不确定如何继续。例如:

var x = xml.SelectSingleNode("//comment()[contains('family names')]");

提前谢谢。

使用 xmldocument 中的 xpath 选择注释之间的节点

你的尝试有什么问题?

像这样的表达式

//comment()[contains('family names')]

不是有效的 XPath。contains()函数需要两个参数,第一个参数是字符串(或者可以通过计算节点的字符串值强制转换为字符串),第二个参数也是字符串。以下方法将起作用:

//comment()[contains(.,'family names')]

但这还不能让你走得更远,因为一旦你确定了开始的评论,你就需要找到它后面的内容。

正确的 XPath 表达式

使用以下表达式:

//comment()[contains(.,'family names')]/following::*[not(preceding::comment()[contains(.,'family ends')])]

翻译为

//comment()                         Find comment nodes anywhere in the documents
[contains(.,'family names')]        but only select them if they contain the text
                                    "family names"
/following::*                       Select all element nodes that follow those comments
[not(preceding::comment()           but only return them if they are not preceded by
                                    a comment node...
[contains(.,'family ends')])]       ...that contains the text "family ends".

应用于格式正确且更合理的输入 XML 文档:

输入 XML

<root>
<Name>
  <First>NO</First>
  <Last>NO</Last>
</Name>
<!-- family names -->
<Name>
  <First>YES</First>
  <Last>YES</Last>
</Name>
<Name>
  <First>YES</First>
  <Last>YES</Last>
</Name>
<Name>
  <First>YES</First>
  <Last>YES</Last>
</Name>
<!-- family ends -->
<!-- other names -->
<Name>
  <First>NO</First>
  <Last>NO</Last>
</Name>
<Name>
  <First>NO</First>
  <Last>NO</Last>
</Name>
</root>
结果

将是(以 ------- 分隔的各个结果):

输出

<Name>
<First>YES</First>
<Last>YES</Last>
</Name>
-----------------------
<First>YES</First>
-----------------------
<Last>YES</Last>
-----------------------
<Name>
<First>YES</First>
<Last>YES</Last>
</Name>
-----------------------
<First>YES</First>
-----------------------
<Last>YES</Last>
-----------------------
<Name>
<First>YES</First>
<Last>YES</Last>
</Name>
-----------------------
<First>YES</First>
-----------------------
<Last>YES</Last>

设计

这个XML文档的人设计得不是很聪明,如果你原谅我的法语。依赖特定位置的特定文本的评论是非常危险的。