2016-11-14 88 views
0

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

<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似乎不可行。

回答

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")}) 
0

也许你想所有的数据存储在一个字典,用child.attrib方法?

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 }

然后,你可以处理的字典,这可能是更容易

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 

是如果不预先定义的变量(或具有新的值,如果所定义的)。