2016-11-14 85 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 

是如果不預先定義的變量(或具有新的值,如果所定義的)。