XPATH:选择紧随特定节点之后的给定名称节点

16

最好通过一个简化的示例来展示:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <A name="wrong"></A>
    <B>not this</B>
    <A name="right">
      <subA></subA>
    </A>
    <B>yes, this</B>  <!-- I want only this one -->
    <A name="right">
      <subA></subA>
    </A>
    <C>dont want this</C>
    <B>not this either</B>  <!-- not immediately following -->
</root>

我想要获取所有在 <A> 节点中,具有 name 属性等于 "right" 的节点后紧随其后<B> 节点。

我的尝试:

//A[@name="right"]/following-sibling::*[1]

这个选择器选中了紧接在 "right" <A> 之后的任何节点(包括 <C>)。我不知道如何只选中 <B>。以下方式无法实现:

//A[@name="right"]/following-sibling::*[1 and B]
这个:

这个:

//A[@name="right"]/following-sibling::B[1]

将选择在“right” <A> 后的第一个<B>,但不一定是紧接着的那个。

3个回答

10

你离成功已经很近了:

//A[@name='right']/following-sibling::*[position()=1 and self::B]

给出了您样本中的一个节点。

为了在条件中引用元素name,您需要使用self。简单地使用[B]表示一个文本完全等于B的元素。


通常我会写成//A[@name='right']/following-sibling::*[1][self::B],部分原因是为了简洁,另一部分原因是在命名空间存在的情况下,self::B 是一个更准确的测试。 - Michael Kay

3

只是想指出您在问题中展示的第一个XPath还不太准确。

  //A[@name='right']/following-sibling::*[1][local-name()='B']

position() 在这里并不是必需的。


1
不用谢。这并不是真正的“链接”。您只是将谓词应用于所有选定节点中的__第一个__直接后续节点。这是选择相邻后续兄弟的常见方式。 - Emiliano Poggi

0
你可以尝试这个代码://B[preceding-sibling::A[1][@name='right']],它会返回你感兴趣的节点。
希望能对你有所帮助。

不强制要求前面的元素是 A,只需该元素具有适当的属性。我阅读后,您的答案未满足要求。 - MattH
这应该符合要求! - Vaman Kulkarni
//B[preceding-sibling::A[1][@name='right']] 是在查找第一个前面的 A 元素,而不是查找第一个前面的元素是 A - MattH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接