我有以下示例文档:
<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;同样是两个<p class="a">
C-D,同样是第五个单<p class="b">
E,因为它没有直接兄弟姐妹;同样是<p class="b">
内的单<x>
F。请注意,在此上下文中,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
值的直接兄弟姐妹?
编辑澄清:注意最后两个是如何选择,而不是兄弟姐妹!
修改我保存了一个示例here。基于/root/p[1]
的Xpath表达式应该选择A, B, C, D
。
答案 0 :(得分:14)
要获得下一个兄弟,您可以添加位置 - 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 :(得分:1)
这样的事情怎么样:
//p[@class='b']/following-sibling::p[following-sibling::p[@class='a'] and @class='b']
它会返回@class='b'
以下的所有兄弟姐妹,并且他们自己跟随@class='a'
的兄弟姐妹。虽然它不适用于最后<p>
,因为它没有跟随兄弟姐妹。