ancestor::foo[bar[@attr="val"]]
我认为这会奏效,但事实并非如此.我需要foo
在树中找到最近的元素bar
,该元素具有子元素,而子元素的attr
属性为val
.
Gor*_*don 37
这应该工作:
//*[ancestor::foo[bar[@attr="val"]]]
Run Code Online (Sandbox Code Playgroud)
或者
root/foo/bar[ancestor::foo[bar[@attr="val"]]]
Run Code Online (Sandbox Code Playgroud)
匹配第二个<bar>
元素
<root>
<foo>
<bar attr="xxx"></bar>
</foo>
<foo>
<bar attr="val"></bar>
</foo>
<foo>
<bar attr="zzz"></bar>
</foo>
</root>
Run Code Online (Sandbox Code Playgroud)
san*_*ton 14
更新以反映OP打算的解决方案.
见@ David的回答
对于下面的xml示例,
<root>
<foo id="0">
<bar attr="val"/>
<foo id="1">
<bar attr="xxx"/>
</foo>
<foo id="2">
<bar attr="val">
<one>1</one>
<two>
<three>3</three>
</two>
</bar>
</foo>
</foo>
Run Code Online (Sandbox Code Playgroud)
反向轴上的有效xpath,其中<3>作为上下文节点,有效的解决方案是
./ancestor::foo[bar[@attr='val']][position() = 1]
Run Code Online (Sandbox Code Playgroud)
"./"是可选的.position()= 1不是可选的,否则foo
也将返回满足谓词的祖先.
老答案:忽略
这是一个老问题.但是任何有兴趣的人,下面的内容都应该让你了解原始问题的意图.
反转轴
//bar[@attr='val']/ancestor::*[position()=1]
Run Code Online (Sandbox Code Playgroud)
前轴
//*[child::bar[@attr='val']]
Run Code Online (Sandbox Code Playgroud)
在我看来,最好的答案是由提出问题的人提供的。他的解决方案应该返回所有祖先 foos。他只想要最近的那个,即position()=1的那个,所以他的xpath表达式需要稍微修改为:
ancestor::foo[bar[@attr="val"] and position() = 1]
Run Code Online (Sandbox Code Playgroud)
如果他写道ancestor::foo[bar[@attr="val"]]
没有返回任何内容,那么他的 xml 中或关于 XPath 求值上下文的当前元素的假设中存在其他问题。
其他答案(以 // 开头)并没有真正回答问题,即使它们碰巧满足了某人的需求,所以它们效率不高:它们选择 xml 文件中的所有元素,然后对它们应用过滤器。虽然我或提出这个问题的人提出的相对 xpath 只是搜索从当前节点开始到父节点及其父节点等的几个元素 - 即使对于大型 XML 文件,它也会非常有效。