我有一些xml;
<root>
<parent>
<child>foo987654</child>
</parent>
<parent>
<child>bar15245</child>
</parent>
<parent>
<child>baz87742</child>
</parent>
<parent>
<child>foo123456</child>
</parent>
</root>
我正在使用python和etree模块,我想选择孩子以“foo”开头的所有<parent>
个节点。我知道etree有限的xpath支持,但我是一个xpath菜鸟,所以我很难找到最好的解决方案。我想到了这个效果
parent[(contains(child,'foo'))]
但我想拒绝包含foo但不以foo开头的父节点(即<child>125456foo</child>
),所以我不确定这会起作用。此外,我不确定etree是否支持此级别的xpath ...
编辑:
另一个可接受的解决方案是选择孩子的文本在列表中的父母。 伪代码 parent =&gt; child [text =“foo1”|| “bar1”|| “BAR2”]
这可能吗?
答案 0 :(得分:4)
这将得到你想要的:
[elem for elem in root.findall('parent') if elem.find('child').text.startswith('foo')]
观看它的实际操作:
s = """<root>
<parent>
<child>foo987654</child>
</parent>
<parent>
<child>bar15245</child>
</parent>
<parent>
<child>baz87742</child>
</parent>
<parent>
<child>foo123456</child>
</parent>
</root>"""
import xml.etree.ElementTree as ET
root = ET.fromstring(s)
elems = [elem for elem in root.findall('parent') if elem.find('child').text.startswith('foo')]
检查数据:
for elem in elems:
print elem.find('child').text
>>>
foo987654
foo123456
答案 1 :(得分:0)
从xml.etree
documentation可以看出,此库不支持XPath中的contains()
运算符。我的建议是选择所有具有XPath /parent
的子项,然后迭代每个结果以删除不以 foo 开头的子项内容。
答案 2 :(得分:0)
使用xpath
import lxml.html
doc = lxml.html.document_fromstring(s)
for e in doc.xpath(".//child[starts-with(text(), 'foo')]"):
print e.text