使用xpath查找重复的兄弟

Enr*_*que 2 xpath duplicates siblings xpath-2.0

如何使用Xpath仅查找至少具有相似/相等的兄弟节点的节点?

例如:

<root>
  <parent>
    <node>...</node>
    <node_unique>...</node_unique>
    <node>...</node>
    <another_one>...</another_one>
    <another_one>...</another_one>
  </parent>
</root>
Run Code Online (Sandbox Code Playgroud)

在示例中,xpath shold仅选择<node>,<another_one>因为它们出现的次数不止一次.

我试图找到一个解决方案几个小时没有成功(现在我认为XPath不可能...).

Dim*_*hev 5

使用单个XPath 1.0表达式无法选择这些(由于XPath 1.0中缺少范围变量).

一种可能的解决方案是选择所有/*/*/*元素,然后获取每个元素的名称,使用name()off元素,然后进行评估/*/*/*[name() = $currentName][2]($currentName应该用刚刚获得的名称替换.如果最后一个表达式选择一个元素,那么这currentName是一个名称至少发生两次 - 因此你保留了那个元素.使用所有元素及其名称这样做.作为一个辅助步骤,人们可以通过将它们放在哈希表中来重复删除名称(和所选元素).

在Xpath 2.0中,使用单个XPath表达式选择给定父级的所有子级是至关重要的,这些子级至少有一个具有相同名称的其他兄弟:

/*/*/*
   [name() = following-sibling::*/name()
  and
    not(name() = preceding-sibling::*/name())
   ]
Run Code Online (Sandbox Code Playgroud)

一个更紧凑的表达:

/*/*/*[index-of(/*/*/*/name(), name())[2]]
Run Code Online (Sandbox Code Playgroud)

基于XSLT 2.0的验证:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*/*/*[index-of(/*/*/*/name(), name())[2]]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

在提供的XML文档上应用此转换时:

<root>
  <parent>
    <node>...</node>
    <node_unique>...</node_unique>
    <node>...</node>
    <another_one>...</another_one>
    <another_one>...</another_one>
  </parent>
</root>
Run Code Online (Sandbox Code Playgroud)

将评估上述XPath表达式,并将从此评估元素中选择的值复制到输出中:

<node>...</node>
<another_one>...</another_one>
Run Code Online (Sandbox Code Playgroud)

注意:有关相关问题/答案,请参阅此处.