0

我正在使用 Python 和 ElementTree 来解析 XML 文件。我希望能够制作一个包含所有 CD 信息的字典列表。稍后我可以使用此列表来收集信息,例如显示来自美国的 CD 的标题。YEAR下面的代码可以正常工作,但如果标签不是 CD 的最后一个标签,则很容易被破坏。如何重写此代码以便标签可以按任何顺序排列?

from xml.etree.ElementTree import ElementTree

f = open("cd_catalog.xml")
tree = ElementTree()
tree.parse(f)

catalog = []
cd = {}
for node in tree.iter():
    if node.tag != "CD" and node.tag != "CATALOG":
        tagtext = (node.tag,node.text),
        cd.update(tagtext)
    if node.tag == "YEAR":
        catalog.append(cd)
        cd = {}

for cd in catalog:
    if cd["COUNTRY"] == "USA":
        print("The cd named {0} is from USA".format(cd["TITLE"]))

xml文件的2个条目:

<CATALOG>
    <CD>
        <TITLE>Empire Burlesque</TITLE>
        <ARTIST>Bob Dylan</ARTIST>
        <COUNTRY>USA</COUNTRY>
        <COMPANY>Columbia</COMPANY>
        <PRICE>10.90</PRICE>
        <YEAR>1985</YEAR>
    </CD>
    <CD>
        <TITLE>Hide your heart</TITLE>
        <ARTIST>Bonnie Tyler</ARTIST>
        <COUNTRY>UK</COUNTRY>
        <COMPANY>CBS Records</COMPANY>
        <PRICE>9.90</PRICE>
        <YEAR>1988</YEAR>
    </CD>
</CATALOG>
4

2 回答 2

2

以下是重写 XML 解析代码的一种方法。在此,我定义了一个生成器,它循环遍历CD根元素的所有元素(我不检查这是一个CATALOG元素,尽管您可以添加该检查)。此生成器将每个元素的所有子CD元素作为字典返回。

使用生成器比构建所有CD元素的字典更有效,特别是当您的 XML 文件非常大时,因为您只CD在内存中存储一​​个元素。

import xml.etree.ElementTree as etree

def get_cd(element):
    try:
        for el in element.iter(tag='CD')
            yield get_cd_info(el)
    except AttributeError:
        # Python < 2.7
        for el in element.getiterator(tag='CD')
            yield get_cd_info(el)

def get_cd_info(element):
    return {'title':element.findtext('TITLE'),
        'artist':element.findtext('ARTIST'),
        'country':element.findtext('COUNTRY'),
        'company':element.findtext('COMPANY'),
        'price':element.findtext('PRICE),
        'year':element.findtext('YEAR')}

以下是上述方法的实际效果:

s = '''<CATALOG>
    <CD>
        <TITLE>Empire Burlesque</TITLE>
        <ARTIST>Bob Dylan</ARTIST>
        <COUNTRY>USA</COUNTRY>
        <COMPANY>Columbia</COMPANY>
        <PRICE>10.90</PRICE>
        <YEAR>1985</YEAR>
    </CD>
    <CD>
        <TITLE>Hide your heart</TITLE>
        <ARTIST>Bonnie Tyler</ARTIST>
        <COUNTRY>UK</COUNTRY>
        <COMPANY>CBS Records</COMPANY>
        <PRICE>9.90</PRICE>
        <YEAR>1988</YEAR>
    </CD>
</CATALOG>
'''

e = etree.fromstring(s)

for cd in get_cd(e):
    if cd['country'] == 'USA':
        print('The cd "{0}" is from the USA.'.format(cd['title']))

# prints 'The cd "Empire Burlesque" is from the USA.'
于 2012-08-13T08:33:06.027 回答
1

未经测试:

....
for CD in tree.findall('cd'):
   for node in CD.finditer():
       print node.tag # TITLE, ARTIST, PRICE etc.

.....
于 2012-08-13T04:25:37.133 回答