寻找根节点x节点的第n个实例

问题描述:

假设我有以下XML寻找根节点x节点的第n个实例

<root> 
    <x> 
     <y /> 
     <z> 
      <y /> 
     </z> 
     <n> 
      <m> 
       <y />* 
      </m> 
     </n> 
    </x> 
    <x> 
     <y /> 
     <z> 
      <y /> 
     </z> 
     <y />* 
    </x> 
</root> 

我想找回那些被随后与*

Ÿ节点所以它始终是第三个节点在X祖先节点

我想是这样的:

//x//y[3] 

但是它不工作时I g只有当y节点处于同一水平时,它才会起作用。

所以,我想 (//x//y)[3]但整个文档中检索只有一个节点(第三个)

所以,我想是这样的:

//x(//y)[3] 
//x(//y[3]) 
//x//(y[3]) 

等,但我得到解析错误

有什么办法来检索我需要使用xpath?

使用:

//x/descendant::y[3] 

此选择文档中的每一个第三y后代每个x的。有时候写出一个扩展的表达式来看看真正发生了什么。在这种情况下,如下:

//x//y[3] 

等同于:

/descendant-or-self::node()/child::x/descendant-or-self::node()/child::y[3] 

写这样,为什么它不会做你想要的东西,可以很明显(即它在寻找任何y这是第三孩子x元素和没有一个)。你真正想要的是每三分之一y后裔。这完全展开:

/descendant-or-self::node()/child::x/descendant::y[3] 

这里最重要的教训是,就得知道什么XPath的abbreviated syntax真的做得。该规范实际上非常可读。我建议看看。

更新:这两个示例都只是XPath 2.0。

在XPath 1.0:

/row//y/(ancestor::x//y)[3] 

在XPath 2.0:

for $x in /row//x 
return ($x//y)[3] 
+0

XPath 1.0片段给出'无效表达式' – hek2mgl

+0

您使用的是哪种XPath引擎?我在Saxon 9.5中测试了这个表达式,并且它工作正常。它在旧版本的Saxon或Xalan中失败。 Saxon 9.5可能将表达式评估为XPath 2.0 ... – joemfb

+0

看起来您正在确认XPath 1.0问题。首先,当我看到这个问题时,它看起来像“易于解决”。但是,我只有xpath 1.0,我找不到方法......疯狂,没想到!但是,您的调查+1。可以等待XPath 2.0最终得到更广泛的部署。 (或事实上的标准) – hek2mgl