return 同一级别所有元素的 XPath
XPath to return all elements on the same level
我正在尝试从 <a id='me'>match</a>
计算出 XPath,它将匹配同一级别的元素。 IE。兄弟姐妹、表兄弟姐妹、二表兄弟姐妹等...
使用以下 XML,来自第一个 <a id='me'>match</a>
的 XPath 表达式 return 是同一级别上具有 id 属性 'me' 的所有元素:-
<alpha>
<beta>
<gamma1>
<a id='me'>match</a>
<a id='me'>match me too</a>
<b id='me'>no match</b>
</gamma1>
<gamma2>
<a id='notme'>no match</a>
<a id='me'>match</a>
</b>
</gamma2>
</beta>
<delta>
<epsilon>
<a id='notme'>no match</a>
<a id='me'>match</a>
</b>
<foo>
<a id='me'>no match</a>
</foo>
</epsilon>
</delta>
<bar>
<a id='me'>no match</a>
</bar>
</alpha>
.\..\a[@id='me']
将 return <gamma1>
和 .\..\..\*\a[@id='me']
中的两个元素 return <gamma1>
和 [=18 中的匹配元素=].但是,我正在尝试做一个 XPath,它将 return 文档中同一级别的所有匹配元素,与它们的深度无关。
我可以在代码中循环,通过构建动态 xpath 上下移动,但这不是很优雅,可能需要很长时间才能 运行..
有人有什么想法吗?
怎么样:
(../../*/a[@id = 'me'])[position() != 1]
在这里,xpath 选择上下文节点的父节点的父节点的所有孙节点,并使用 position() != 1
,它删除上下文节点本身(假设上下文节点是列表中的第一个节点,因为您在你的问题中提到过)。
Lingamurthy 已经给出的答案是完全有效的,但我想指出另一种看待问题的方式。您解释说您正在评估以某个节点为起点的 XPath 表达式,/alpha/beta/gamma1/a[1]
。因此,我假设您知道该节点的准确位置,即使对该文档一无所知。
如果这在您的情况下成立,您可以简单地计算该节点的祖先(沿着 ancestor::*
轴)并且只有 select a
个具有相同数量的元素祖先:
//a[@id = 'me' and count(ancestor::*) = count(/alpha/beta/gamma1/a[1]/ancestor::*)]
结果将是(各个结果由 ---------
分隔):
<a id="me">match</a>
-----------------------
<a id="me">match me too</a>
-----------------------
<a id="me">match
</a>
-----------------------
<a id="me">match
</a>
同样,使用另一个答案 (...)[position() != 1]
中显示的技术排除此列表中的第一个结果,如果这对您很重要。
顺便提一下:您输入的XML无效,有两个a
元素没有正确关闭。
我正在尝试从 <a id='me'>match</a>
计算出 XPath,它将匹配同一级别的元素。 IE。兄弟姐妹、表兄弟姐妹、二表兄弟姐妹等...
使用以下 XML,来自第一个 <a id='me'>match</a>
的 XPath 表达式 return 是同一级别上具有 id 属性 'me' 的所有元素:-
<alpha>
<beta>
<gamma1>
<a id='me'>match</a>
<a id='me'>match me too</a>
<b id='me'>no match</b>
</gamma1>
<gamma2>
<a id='notme'>no match</a>
<a id='me'>match</a>
</b>
</gamma2>
</beta>
<delta>
<epsilon>
<a id='notme'>no match</a>
<a id='me'>match</a>
</b>
<foo>
<a id='me'>no match</a>
</foo>
</epsilon>
</delta>
<bar>
<a id='me'>no match</a>
</bar>
</alpha>
.\..\a[@id='me']
将 return <gamma1>
和 .\..\..\*\a[@id='me']
中的两个元素 return <gamma1>
和 [=18 中的匹配元素=].但是,我正在尝试做一个 XPath,它将 return 文档中同一级别的所有匹配元素,与它们的深度无关。
我可以在代码中循环,通过构建动态 xpath 上下移动,但这不是很优雅,可能需要很长时间才能 运行..
有人有什么想法吗?
怎么样:
(../../*/a[@id = 'me'])[position() != 1]
在这里,xpath 选择上下文节点的父节点的父节点的所有孙节点,并使用 position() != 1
,它删除上下文节点本身(假设上下文节点是列表中的第一个节点,因为您在你的问题中提到过)。
Lingamurthy 已经给出的答案是完全有效的,但我想指出另一种看待问题的方式。您解释说您正在评估以某个节点为起点的 XPath 表达式,/alpha/beta/gamma1/a[1]
。因此,我假设您知道该节点的准确位置,即使对该文档一无所知。
如果这在您的情况下成立,您可以简单地计算该节点的祖先(沿着 ancestor::*
轴)并且只有 select a
个具有相同数量的元素祖先:
//a[@id = 'me' and count(ancestor::*) = count(/alpha/beta/gamma1/a[1]/ancestor::*)]
结果将是(各个结果由 ---------
分隔):
<a id="me">match</a>
-----------------------
<a id="me">match me too</a>
-----------------------
<a id="me">match
</a>
-----------------------
<a id="me">match
</a>
同样,使用另一个答案 (...)[position() != 1]
中显示的技术排除此列表中的第一个结果,如果这对您很重要。
顺便提一下:您输入的XML无效,有两个a
元素没有正确关闭。