寻找根节点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]
XPath 1.0片段给出'无效表达式' – hek2mgl
您使用的是哪种XPath引擎?我在Saxon 9.5中测试了这个表达式,并且它工作正常。它在旧版本的Saxon或Xalan中失败。 Saxon 9.5可能将表达式评估为XPath 2.0 ... – joemfb
看起来您正在确认XPath 1.0问题。首先,当我看到这个问题时,它看起来像“易于解决”。但是,我只有xpath 1.0,我找不到方法......疯狂,没想到!但是,您的调查+1。可以等待XPath 2.0最终得到更广泛的部署。 (或事实上的标准) – hek2mgl