我刚刚开始深入研究Python和XML,我遇到了解析(可能)非标准XML的问题(如果我错了,请纠正我)。
我想通过先前根据其Attribute的值识别Element来解析Element的值。
更多细节:
我有两个元素'Name'
,我想解析具有属性language == 'en-US'
的元素的值。
在我的XML文件中,<'Name' language == 'en-US'>
始终显示在<'Name' language == 'es-ES'>
之后,我无法获得前者的值(例如B
),我只能得到后者(例如A
)。
XML文件:
<Eways>
<Products>
<Operator>
<Name language="es-ES">A</Name>
<Name language="en-US">B</Name>
</Operator>
</Products>
</Eways>
Python脚本:
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
for prod in root.findall('Products'):
for op in prod.findall('Operator'):
print op.find('Name').text ### <- Testing, here I would expect to print both A and B, but only A is printed.
for names in op.iter(tag='Name'): ### Here I iterate over Element 'Name' trying to get the values anyways.
l_name = names.get('language')
if l_name == 'en-US': ### My objective is to print out the value of Element 'Name' where Attribute language == en-US.
print 'OK en-US', names.find('Name') ### I can not get the values (neither A nor B)
else:
print 'KO en-US', names.find('Name')
答案 0 :(得分:4)
element.find()
方法只找到第一个匹配元素。如果您希望找到两个元素,则必须使用element.findall()
。
你不需要在这里做很多循环;只需使用XPath expression:
for nametag in tree.findall('./Products/Operator/Name[@language]'):
print nametag.attrib['language'], nametag.text
XPath查询在这里非常具体;仅找到Name
元素内language
内Operator
属性的Products
个元素。
此处的.text
属性为您提供了内容。
演示:
>>> from xml.etree import ElementTree as ET
>>> tree = ET.fromstring('''\
... <Eways>
... <Products>
... <Operator>
... <Name language="es-ES">A</Name>
... <Name language="en-US">B</Name>
... </Operator>
... </Products>
... </Eways>
... ''')
>>> for nametag in tree.findall('./Products/Operator/Name[@language]'):
... print nametag.attrib['language'], nametag.text
...
es-ES A
en-US B
如果您只想要<Name language="en-US">
标签,请调整XPath查询:
for nametag in tree.findall("./Products/Operator/Name[@language='en-US']"):
print nametag.attrib['language'], nametag.text
[@language='en-US']
部分将搜索范围限制为具有特定属性值的那些标记。
答案 1 :(得分:1)
Name
元素本身不包含其他元素,因此find
会提供None
。相反,您只需要元素的text
:
>>> for p in tree.findall("Products"):
for op in p.findall("Operator"):
for n in op.findall("Name"):
print n.get('language'), n.text
es-ES A
en-US B