Python:如何使用动态数量的子节点解析XML?
问题描述:
我解析一个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
似乎不可行。
答
我没有用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")})
答
也许你想所有的数据存储在一个字典,用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 }
然后,你可以处理的字典,这可能是更容易
答
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
是如果不预先定义的变量(或具有新的值,如果所定义的)。