使用lxml一次对一个.xml项目(及其子项)执行功能操作

时间:2012-10-01 00:26:17

标签: python xml-parsing lxml

只是抬头,我使用像这样导入的lxml:from lxml import etree

我试图让一些工作代码更灵活。我的脚本采用输入.xml文件,其中包含按名称排序的所有项目,引用包含项目ID号和项目名称的字典,以根据该.xml文件生成项目ID列表,然后轮询Web服务器然后用于输出总成本的那些项目ID的价格数据。我的问题不是任何这些步骤。

相反,我的问题是如何处理解析包含多个订单的.xml文件。

到目前为止,我的示例.xml文件可能如下所示:

<?xml version="1.0" ?>
    <cars>
        <order="This is a test order">
            <description value=""/>
            <carType value="Model1"/>
            <upgrade slot="interior 0" type="Leather Seats"/>
            <upgrade slot="interior 1" type="6-Disc CD Player"/>
        </order>
    </cars>

我可以将其解析为包含基本商品carType(汽车型号)和各种升级的列表:

for element in root.iterchildren('carType'):
    modlist.append ("%s" % (element.get('value')))

for element in root.iter('upgrade'):
    modlist.append ("%s" % str.upper((element.get('type'))))

它会给我一个名为modlist的列表,如['Model1', 'Leather Seats', '6-Disc CD Player'],我可以通过我的其他功能来获取这些项目的ID号,然后从中获取价格信息并将其总计为了解这款带有真皮座椅升级和6碟CD播放器升级的Model1车的价格是多少。

这是我遇到困难的地方。如何在一个.xml文件中放置多个汽车?示例可能如下所示:

<?xml version="1.0" ?>
    <cars>
        <order="This is a test order">
            <description value=""/>
            <carType value="Model1"/>
            <upgrade slot="interior 0" type="Leather Seats"/>
            <upgrade slot="interior 1" type="6-Disc CD Player"/>
        </order>
        <order="This is a 2nd order">
            <description value=""/>
            <carType value="Model3"/>
            <upgrade slot="interior 0" type="Vinyl Seats"/>
            <upgrade slot="wheels 0" type="Chrome Wheels"/>
            <upgrade slot="wheels 1" type="8 Ply Tires"/>
        </order>
        <order="This is a 3rd order">
            <description value=""/>
            <carType value="Model7"/>
            <upgrade slot="engine 0" type="V8"/>
            <upgrade slot="interior 0" type="Leather Seats"/>
            <upgrade slot="interior 1" type="Sunroof"/>
        </order>
    </cars>

我想一次在一个订单上运行我的功能,这样这个例子就会输出3个数字 - 这个Model1汽车的升级总价,升级后的Model3汽车的总价,以及具有升级功能的Model7汽车的总价格。

如何告诉我的功能一次只运行一个订单?我正在考虑iterchild(),但我无法正常工作。

1 个答案:

答案 0 :(得分:1)

使用root.iterchildren而不是调用order.iterchildren,其中order遍历<order>元素:

for order in root.xpath('//order'):
    modlist = []
    for element in order.iterchildren('carType'):
        modlist.append ("%s" % (element.get('value')))

    for element in order.iter('upgrade'):
        modlist.append ("%s" % str.upper((element.get('type'))))
    # report grand total for order