Python ElementTree:使用XPath根据子文本查找元素

3 投票
1 回答
6464 浏览
提问于 2025-04-17 20:32

我想找到一个元素,这个元素的某个子元素里有特定的文本值。举个例子,

<peers>
    <peer>
        <offset>1</offset>
        <tag>TRUE</tag>
    </peer>
    <peer>
        <offset>2</offset>
        <tag>FALSE</tag>
    </peer>
</peers>

在这个XML文档中,我想直接找到一个peer元素里的tag,而这个peer元素的offset值是1。

为此,我写了一个XPath表达式,如下所示:

./peers/peer[offset='1']/tag

但是在使用ElementTree的Element.find()方法时,这个表达式没有成功,返回的是None,而不是我想要的“tag”元素:

from xml.etree.ElementTree import fromstring

doc = fromstring("<peers><peer><offset>1</offset><tag>TRUE</tag></peer><peer><offset>2</offset><tag>FALSE</tag></peer></peers>")

tag = doc.find("./peers/peer[offset='1']/tag")

print tag


=> None

我开始怀疑,是不是我上面的XPath表达式写错了,或者是因为ElementTree只支持部分XPath功能,这在它的文档中有说明。希望能得到帮助。谢谢。

1 个回答

5

直接使用 lxml.etree(同样的道理也适用于 ElementTree),你可以这样得到结果:

doc = lxml.etree.fromstring(...)
tag_elements = doc.xpath("/peers/peer/offset[text()='1']/../tag")

tag_elements 将会是一个包含 <peer> 元素中有一个 <offset> 元素且其值为 1 的 <tag> 元素的列表

给定的输入(我添加了一个 <peer> 的条件,以强调 tag_elements 是一个列表):

<peers>
    <peer>
        <offset>1</offset>
        <tag>TRUE</tag>
    </peer>
    <peer>
        <offset>1</offset>
        <tag>OTHER</tag>
    </peer>
    <peer>
        <offset>2</offset>
        <tag>FALSE</tag>
    </peer>
</peers>

tag_elements 将包含两个元素:

for tag in tag_elements:
    print tag.text
-> TRUE
-> OTHER

更新:

doc.xpath("/peers/peer[offset=1]/tag") 也能正常工作。

但是 doc.xpath("./peers/peer[offset=1]/tag") 就不行。

撰写回答