Python:如何使用动态数量的子节点解析XML?

时间:2016-11-14 06:34:26

标签: python xml lxml data-processing

我正在解析XML数据集并将其保存到mysql数据库中,以便使用python中的xml.etree模块进行进一步处理。有一个节点具有可变数量的子节点。例如,让我们说:

<cars>
   <car type="A" value=35 />
   <car type="B" value=42 />
   <car type="C" value=55 />
   <car type="D" value=23 />
</cars>

因此,在此示例中,每个文档中car个节点的数量会有所不同。我知道最多可以A - H,所以我在我的数据库中创建了从car_A到car_H的列。我通常会这样做一个循环来获取每辆车的value属性:

for car in root.findall("cars/car"):
    if car.get("type") == "A":
       car_A = car.get("value")
    elif car.get("type") == "B":
       car_B = car.get("value")
    ...

但这看起来效率有点低,而且我还需要让车辆类型不存在,比如汽车type=E为空。如果不使用所有if..elif语句,如何使其更具通用性和效率,我该怎么做?可能有其他此类节点具有更多类型的子节点,因此手动编写if...elif似乎不可行。

3 个答案:

答案 0 :(得分:0)

我还没有使用xml.etree,但如果您使用BeautifulSoup

,这很简单
markup = '<cars><car type="A" value=35 /><car type="B" value=42 /><car type="C" value=55 /><car type="D" value=23 /></cars>'
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup, 'lxml')
car_dict = {'car_'+car.get('type'): car.get('value') for car in soup.find('cars').findAll('car')}

以下是dict的样子:

print car_dict
4: {'car_A': '35', 'car_B': '42', 'car_C': '55', 'car_D': '23'}

我一直在使用[BeautifulSoup][1],它为其构建的服务提供了最好的服务! +文档很广泛!

编辑: 如果您只想使用xml.etree,我建议您使用类似的方法,即使用字典:

car_dict = {}
for car in root.findall("cars/car"):
    car_dict.update({'car_'+car.get("type"): car.get("value")}) 

或者如果你想更新局部变量而不是创建一个单独的字典,试试这个(我想这首先是你想要的):

car_dict = {}
for car in root.findall("cars/car"):
    locals().update({'car_'+car.get("type"): car.get("value")}) 

答案 1 :(得分:0)

也许您想使用child.attrib方法将所有数据存储在dict中?

xml_str = '''
<cars>
    <car type="A" value="32"/>
    <car type="B" value="42"/>
    <car type="C" value="55"/>
    <car type="D" value="23"/>
</cars>
'''

import xml.etree.ElementTree as ET
root = ET.fromstring(xml_str)

cars = {}
for child in root:
    cars[child.attrib['type']] = child.attrib['value']

输出是 { 'A': 32, 'B': 42, 'C': 55, 'D': 23 }

然后你可以处理dict,这可能更容易

答案 2 :(得分:0)

cars={}
for car in root.findall("cars/car"):
    car_type="car_"+car.get("type")
    cars[car_type]=car.get("value")

如果你有预定义的变量在其他地方(在你的代码中)使用它们,你可以使用这一行从字典键中创建变量(或覆盖值):

locals().update(cars)

然后

car_A

是先前未定义的变量(如果已定义则具有新值)。