0

它应该返回所有第一次出现的具有相同名称的节点,即使子节点和属性不同。

例如

<Data>
  <A>
    <X randomattr="1"/>
    <Y randomattr="1"/>
    <Z/>
  </A>
  <B>
    <X/>
    <X randomattr="3"/>
    <Z/>
  </B>
</Data>

它应该返回 3 个节点,第一个是 X、Y 和 Z,因为下面的节点将有一个重复的名称。如果 X 元素之一没有 randomattr 或者另一个元素具有不同的值,请不要介意。

我不想要 name() 中的不同值,我想返回整个节点。就像是

/Data/*/*[distinct-values(name())]

我也知道我可以用双循环遍历所有节点,但我问自己是否有一个简单的单行或函数,或者像 distinct[1] 这样的特殊 Xpath 语法谢谢你!

4

2 回答 2

0

我想这就是你可能正在寻找的。使用了一些简单的测试:

  • (Xpath 2.0)/Data/*/*[not((preceding-sibling::*/name(.)=name(.)) or (../preceding-sibling::*/*/name(.)=name(.)))]
  • (Xpath 1.0)/Data/*/*[not((name(preceding-sibling::*)=name(.)) or (name(../preceding-sibling::*/*)=name(.)))]

在请求使其工作到任何深度之后......我不熟悉您的架构,但从示例中我假设您正在寻找的节点是底层节点。以下使用后代轴在进行名称检查时搜索没有子节点的节点。

  • /Data/descendant::*[not(name() = preceding::*[not(child::*)]/name())][not(child::*)]
于 2012-07-16T19:10:52.360 回答
0

我会接受 alwaysWrong 的问题,但我从他那里学到的东西和我刚刚学到的 AXES 东西研究后回答了另一种可能性。

/Data/*/*[not(name() = preceding::*[name(../..)='Data']/name())]

(First name() 也可以是 self::*/name() 以下语法)

对于任何情况,这将是我认为更容易和最好的路线,因为当叶级别很深时,它不会以指数方式增长。只需更改先例的条件以匹配“从根”同级,例如 [name(../..)='Data'] 或定义此层次结构级别的所有节点的条件,或者如果它们共享,则为前面的::name_node相同的qname

于 2012-07-17T09:37:11.440 回答