紧接着前兄弟的xpath

时间:2016-09-05 13:09:19

标签: python xml xpath lxml

XML

<root>
  <p>nodea text 1</p>
  <p>nodea text 2</p>
  <nodea>
  </nodea>
  <p>nodeb text 1</p>
  <p>nodeb text 2</p>
  <nodeb>
  </nodeb>
</root>

我想获得nodea或nodeb的前一个兄弟p标签,如果有的话。例如,对于上面的xml,各节点的前一个兄弟是

nodea 兄弟姐妹之前

<p>nodea text 1</p>
<p>nodea text 2</p>

nodeb 兄弟姐妹之前

<p>nodeb text 1</p>
<p>nodeb text 2</p>

我已经尝试了下面的xpath但是它给了我前面的nodea标签而不是nodeb。

nodeb = xml.find('nodeb')
nodeb.xpath('preceding-sibling::p[not(preceding-sibling::nodea)][1]')

如果节点之前没有前面的p标记,那么它应该返回空列表。例如,对于下面的xml,nodeb没有前面的兄弟p标记。

<root>
  <p>nodea text 1</p> 
  <nodea>
  </nodea>
  <nodeb>
  </nodeb>
</root>

如果有人能解释为什么我的xpath不起作用以及在编写xpath时我应该记住什么呢?

1 个答案:

答案 0 :(得分:5)

如果它是preceding-sibling::*[1][self::p]元素,您可以选择p来选择前一个兄弟元素。

至于您的尝试,我认为如果您选择nodeb元素,则需要选择preceding-sibling::p[preceding-sibling::nodea][1],因为您要查看p之间的兄弟nodeb {1}}和nodea元素。您的条件preceding-sibling::p[not(preceding-sibling::nodea)][1]确实选择了p没有前一个nodea兄弟的兄弟姐妹,这些是文档顺序中的前两个p元素。