11

我有以下示例文档:

<root>
  <p class="b">A</p>
  <p class="b">B</p>
  <p class="a">C</p>
  <p class="a">D</p>
  <p class="b">E</p>
  <x>
    <p class="b">F</p>
  </x>
</root>

我正在寻找一个 xpath 表达式,它选择具有匹配类属性的给定节点的所有直接兄弟姐妹,而不是任何兄弟姐妹。<p class="b">在上面的例子中,应该选择前两个AB;同样是两张<p class="a">CD,同样是第五张单曲<p class="b">E,因为它没有直系兄弟姐妹;中的单个<p class="b">F也是如此<x>。请注意,在这种情况下,B 和 C 不是直接兄弟,因为它们具有不同的类属性值!

我所拥有的是:

xml.xpath("//p") # This selects all six <p> elements.
xml.xpath("//p[@class='b']") # This selects all four <p class="b"> elements.
xml.xpath("//p/following-sibling::p[@class='b']") # This selects all <p class="b"> sibling elements, even though not direct siblings.

最后一个表达式也选择了第五个兄弟姐妹,尽管中间有不匹配的兄弟姐妹。

如何仅选择具有相同class值的直接兄弟姐妹?

编辑澄清:注意最后两个是个人选择,而不是兄弟姐妹!

编辑我在这里保存了一个例子。基于的 Xpath 表达式/root/p[1]应该是 select A, B, C, D

4

2 回答 2

18

要获得下一个兄弟,您可以在旁边添加位置 - 1 表示。

following-sibling::*[1]

为确保下一个兄弟节点属于特定节点类型,您可以添加以下过滤器,其中 p 是我们要匹配的节点类型。

[self::p]

如果您只想要具有相同属性的那些,您还需要在第一个 p 元素上指定属性。

因此,如果您只想要紧跟在类 bp 元素之后的类 bp 元素,则可以执行以下操作。这只会给你第二个 p 元素。

//p[@class='b']/following-sibling::*[1][@class='b'][self:p]

听起来您实际上可能想要与另一个 b 类元素相邻的任何 b 类元素。在这种情况下,您可以检查以下和前面的兄弟姐妹。以下将为您提供前 2 p 个元素。

//p[@class='b'][following-sibling::*[1][@class='b'][self::p] 
                or preceding-sibling::*[1][@class='b'][self::p]]    
于 2013-10-18T20:31:31.233 回答
1

像这样的东西怎么样:

//p[@class='b']/following-sibling::p[following-sibling::p[@class='a'] and @class='b']

它返回所有跟随的兄弟姐妹,@class='b'他们自己有跟随的兄弟姐妹@class='a'。虽然它不会持续工作,<p>因为它没有以下兄弟姐妹。

于 2015-07-17T11:05:33.120 回答