检测元素的直接兄弟是lxml中的文本还是其他元素

时间:2016-05-04 09:15:21

标签: python xml python-2.7 lxml

我使用lxml库和Python 2.7来解析xml文件。我需要检测兄弟元素之间是否有任何文本。例如,在以下xml部分中:

<cross-ref> [t1] </cross-ref> ***some text*** <cross-ref> [t2] </cross-ref>  
<cross-ref> [t3] </cross-ref><cross-ref> [t4] </cross-ref>

说我检测到所有带有交叉引用标签的元素,我需要一种只检测第二行上的交叉引用元素的方法,第二个元素位于第一个元素之后,它们之间没有文本。所以我猜想需要循环才能进行循环,但很明显这段代码同时打印了[t1][t3]

for c in cross_refs:
  # detect ***some text*** or do something else here
  if c.getnext().tag == "cross-ref":
     print c.text

我需要对其进行修改,以使输出仅为[t3]

2 个答案:

答案 0 :(得分:2)

您的答案中的三重嵌套if也可以在XPath中表示如下:

following-sibling::node()[1][self::cross-ref]

简而言之,只有当cross-ref元素时,XPath才会返回最近的兄弟节点。请注意, node 在这里表示文本节点或元素节点。 XPath可以如下使用:

for c in cross_refs:
    if c.xpath('boolean(following-sibling::node()[1][self::cross-ref])'):
        print c.text

如果您愿意,或者您首先只能获得符合此条件的cross-ref元素:

cross_refs = tree.xpath('//cross-ref[following-sibling::node()[1][self::cross-ref]]')
for c in cross_refs:
    print c.text

答案 1 :(得分:0)

我使用tail属性解决了这个问题。当c.tail为None时,我可以说元素附加在它们之间没有文本。代码是这样的:

for c in cross_refs:
    if c.getnext() != None:
        if c.getnext().tag == c.tag:
            if c.tail == None:
                print c.text