ElementTree 的 findall '或' 操作符
如果我有一个这样的xml文件:
<root>
<item>
<prop>something</prop>
</item>
<test>
<prop>something</prop>
</test>
<test2>
<prop>something</prop>
</test2>
</root>
我可以用
xmlTree.getroot().findall("item")
来获取所有的'item'元素。
那么我该怎么才能获取所有的'item'或者'test'元素呢?我想要的效果是这样的:
xmlTree.getroot().findall("item or test")
在文档的例子里我没有看到类似的用法。有没有什么想法呢?
2 个回答
0
大数据集的“通配符”解决方案
这里有一个方法,你不需要指定“A | B | ...”。你可以用“*”作为通配符,然后通过索引来过滤掉不需要的部分,下面的代码就展示了这个方法(比如,在这个问题中,最后一个标签“test2”可以通过使用 lst[:-1] 来排除)。
import xml.etree.ElementTree as ET
data='''
<root>
<item>
<prop>something1</prop>
</item>
<test>
<prop>something2</prop>
</test>
<test2>
<prop>something3</prop>
</test2>
</root>'''
root = ET.fromstring(data)
lst = root.findall('*')
for x in lst[:-1]:
print(x.find('prop').text)
输出结果:
something1
something2
14
因为标准库里的 ElementTree 只支持有限的 xpath,所以如果你想用 |
这个 xpath 的“或”运算符,就必须使用 lxml
这个库:
from lxml import etree as ET
data = """<?xml version="1.0"?>
<data>
<item>1</item>
<test>2</test>
</data>"""
tree = ET.fromstring(data)
for element in tree.xpath('//item|//test'):
print element.text
这段代码会输出:
1
2
如果你用的是 xml.etree.ElementTree
,你可以把两个单独的 findall()
调用的结果结合起来:
for element in tree.findall('.//item') + tree.findall('.//test'):
print element.text
或者,在循环里检查标签名:
for element in tree.iter():
if element.tag in ('item', 'test'):
print element.text