Skip to main content
 首页 » 编程设计

python之使用 lxml 一次对一个 .xml 项(及其子项)执行函数操作

2025年05月04日14jackei

请注意,我正在使用这样导入的 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() 的一些事情,但我什么也做不了。

请您参考如下方法:

而不是调用 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