首页 文章

Xpath只选择具有匹配属性的直接兄弟

提问于
浏览
8

我有以下示例文档:

<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"> A-B;同样是两个C-D,同样也是第五单曲,因为它没有直接的兄弟姐妹;同样是 <x> 中的单个 <p class="b"> . 请注意,在此上下文中,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 值的直接兄弟姐妹?

Edit 澄清:注意最后两个是如何选择,而不是兄弟姐妹!

Edit 我保存了一个例子here . 基于 /root/p[1] 的Xpath表达式应该选择 A, B, C, D .

2 回答

  • 13

    为了获得下一个兄弟,你可以添加位置 - 1意思就在旁边 .

    following-sibling::*[1]
    

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

    [self::p]
    

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

    因此,如果您只想要紧跟在类b p元素之后的类b p元素,则可以执行以下操作 . 这只会给你第二个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]]
    
  • 1

    这样的事情怎么样:

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

    它返回所有以下兄弟姐妹 @class='b' 并且他们自己跟随 @class='a' 的兄弟姐妹 . 虽然它不适用于最后 <p> ,因为它没有跟随兄弟姐妹 .

相关问题