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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19457502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:47:51  来源:igfitidea点击:

Xpath to select only direct siblings with matching attributes

pythonxpath

提问by Jens

I have the following example document:

我有以下示例文档:

<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>

I am looking for an xpath expression which selects all directsiblings of a given node with matching class attributes, not any sibling. In above example, the first two <p class="b">A-B should be selected; likewise the two <p class="a">C-D, likewise the fifth single <p class="b">E as it has no directsiblings; likewise the single <p class="b">F inside of <x>. Note that in this context B and C are not direct siblings because they have different class attribute valued!

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

What I have is this:

我有的是这个:

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.

The last expression selects the fifth sibling as well, although there are non-matching siblings inbetween.

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

How do I select only direct siblings with the same classvalue?

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

EditTo clarify: note how the last two are individual selections, not siblings!

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

EditI have saved an example here. The Xpath expression based on /root/p[1]is supposed to select A, B, C, D.

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

回答by Justin Ko

To get the very next sibling, you can add the position - 1 meaning right beside.

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

following-sibling::*[1]

To ensure that the next sibling is of a specific node type, you can add the following filter, where p is the node type we want to match.

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

[self::p]

If you only want ones with the same attribute, you would also need to specify the attribute on the first p element.

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

So if you just want class b p elements that are immediately after a class b p element, you can do the following. This would just give you the second p element.

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

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

It sounds like you might actually want any class b element which is adjacent to another class b element. In that case, you can check the following and preceding sibling. The following would give you the first 2 p elements.

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

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

回答by rokras

How about something like this:

这样的事情怎么样:

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

It returns all following siblings that are @class='b'and them self have following siblings with @class='a'. Though it would not work for last <p>as it does not have following siblings.

它返回所有以下兄弟姐妹,@class='b'并且他们自己有以下兄弟姐妹@class='a'。尽管它不会持续到最后,<p>因为它没有以下兄弟姐妹。