问题
I'm trying to locate an element that has certain text value in one of its child. For example,
<peers>
<peer>
<offset>1</offset>
<tag>TRUE</tag>
</peer>
<peer>
<offset>2</offset>
<tag>FALSE</tag>
</peer>
</peers>
from this XML document I would like to directly locate tag
in a peer
element whose offset
value is 1.
So for that purpose I have a XPath expression as follows:
./peers/peer[offset='1']/tag
however using such expression in ElementTree's Element.find()
method fails and gives None
rather than the "tag" element of my interest:
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
I'm being inclined to believe it's either my above XPath expression is wrong, or due to ElementTree's supporting only a subset of XPath according to its documentation. Looking for help. Thank you.
回答1:
Using lxml.etree
directly (the same should apply to ElementTree
), you can achieve the result like this:
doc = lxml.etree.fromstring(...)
tag_elements = doc.xpath("/peers/peer/offset[text()='1']/../tag")
tag_elements
will be the list of <tag>
elements belonging to <peer>
elements containing an <offset>
element containing 1.
Given input (I've added a <peer>
clause to emphasize tag_elements
being a list):
<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
will contain two elements:
for tag in tag_elements:
print tag.text
-> TRUE
-> OTHER
UPDATE:
doc.xpath("/peers/peer[offset=1]/tag")
also works fine.
But doc.xpath("./peers/peer[offset=1]/tag")
does not.
来源:https://stackoverflow.com/questions/22135250/python-elementtree-find-element-by-its-childs-text-using-xpath