2017-06-23 16 views
0

私はこのXMLファイルを含んでいます。私は最初のものだけを得ていますが、私はそれらをループすることはできません。ここでは、XMLの構造とコードは次のとおりです。データを抽出するPythonでXML - > DICT

from lxml import objectify as xml_objectify 
contents = open('/home/conacons/Documents/order.xml').read() 
def xml_to_dict(xml_str): 
""" Convert xml to dict, using lxml v3.4.2 xml processing library """ 
    def xml_to_dict_recursion(xml_object): 
     dict_object = xml_object.__dict__ 
     if not dict_object: 
      return xml_object 
     for key, value in dict_object.items(): 
      dict_object[key] = xml_to_dict_recursion(value) 
     return dict_object 
    return xml_to_dict_recursion(xml_objectify.fromstring(xml_str)) 
xml_dict = xml_to_dict(contents) 
#print xml_dict 
for item,v in xml_dict['item']['items'].items(): 
    print item,v 
<Order> 
<item> 
<customer></customer> 
<status>no</status> 
<amount_untaxed>7315.0</amount_untaxed> 
<name>Test/001</name> 
<confirmation_date>False</confirmation_date> 
<order_id>8</order_id> 
<items> 
<item><list_price>16.5</list_price><description>False</description><weight>0.0</weight><default_code/><id>18</id><uom>Unit(s)</uom> <name>iPod</name></item><item><list_price>12.5</list_price><description>False</description><weight>0.0</weight><default_code>M-Wir</default_code><id>19</id><uom>Unit(s)</uom><name>Mouse, Wireless</name>  </item> 

私は一つだけのアイテムを取得していますこのコードを実行するWhrn。アイテムのすべてのアイテムを取得するループを作成するにはどうすればよいですか?おかげ (出力): アイテム{ 'LIST_PRICE':16.5、 '説明': '偽'、 '体重':0.0、 'DEFAULT_CODE': ':18' UOM Uは、ID ' '''「ユニット( ')'、 '名前': 'iPod'}

+0

有効なXML文書を投稿できますか?これにはいくつかのエラーがあります。例えば、何の終了タグは、注文のために、最初の「項目」タグなどはありません。ここ –

+0

がフルorder.xmlドキュメント あるhttps://pastebin.com/sUsbRqAz –

+0

あなたは、XMLを使用し、XMLライブラリを経由して、それを処理するか、またはjsonを使い、処理のためにdictに変換してください。処理のためにxmlをdictに変換することは、通常は悪い考えです。 – marbu

答えて

0

あなたのアプローチに問題があります。 XMLオブジェクトはdictに変換されません。dictオブジェクトは重複キーを持つことができないためです。たとえば、あなたのケースでは、あなたは、いくつかのitem子どもたちとxml_objectためxml_object.__dict__を呼び出すとき、それは一つだけitemキーでdictを返しタグ。したがって__init__の代わりにgetchildrenメソッドを使用する必要があります。しかし、別の問題があります。あなたの例から、次のコードでも正しく動作しませんitemsタグに対応するxml_objectについて:

for child in xml_object.getchildren(): 
    dict_object[child.tag] = xml_to_dict_recursion(child) 

あなたが理解した理由は、すべてのループ反復で同じ値を持つchild.tagということです。

これらの問題を解決するには、collections.defaultdictを使用します。コードは次のようになりされることがあります。

{'uom': ['Unit(s)'], 'default_code': [''], 'description': ['False'], 'name': ['iPod'], 'weight': [0.0], 'list_price': [16.5], 'id': [18]} 
{'uom': ['Unit(s)'], 'default_code': ['M-Wir'], 'description': ['False'], 'name': ['Mouse, Wireless'], 'weight': [0.0], 'list_price': [12.5], 'id': [19]} 

しかし、私の意見では、このアプローチは非常にconvinientで、より快適な方法はただでXML文書自体を解析しているではありません。

from collections import defaultdict 
from lxml import objectify 


def xml_to_dict(xml_str): 
    def xml_to_dict_recursion(xml_object): 
     dict_object = defaultdict(list) 
     if not xml_object.__dict__: 
      return xml_object 
     for child in xml_object.getchildren(): 
      dict_object[child.tag].append(xml_to_dict_recursion(child)) 
     return dict_object 
    return xml_to_dict_recursion(objectify.fromstring(xml_str)) 


if __name__ == "__main__": 
    contents = open('input.xml').read() 
    xml_dict = xml_to_dict(contents) 
    for value in xml_dict['item'][0]['items'][0]['item']: 
     print(dict(value)) 

この場合、出力されましたlxml.objectifydocs参照)。例:

tree = objectify.parse('input.xml') 
order = tree.getroot() 
order_items = order.getchildren() 
for order_item in order_items: 
    print(order_item['amount_untaxed']) 
    customer = order_item['customer'] 
    print(customer['item']['city']) 
    for item in order_item['items'].getchildren(): 
     print(item['list_price']) 
+0

これは素晴らしい作品です。これは、複数の注文インポート・システムとなりますので、今、私はと、ここで別のに1つの以上のアイテムを持っています。#print value ['list_price'] print(dict(value)) [xml_dict [item '] [0] [' items ']] [item '] [0] [' item ']: #print value [' list_price '] print(dict(value)) ' しかし、すべてをループするそれらのうちxml_dict ['item'] [1] [xml_dict ['item'] [2] [xml_dict ['item'] [3] [?前もってありがとう –

+0

xmlオブジェクトを辞書に変換するのに本当に必要ですか?私の意見では、 'lxml'メソッドの使用がより便利です。 –

+0

いいえ、要するに、xmlをdictに変換せずに、オーダー内のすべての注文とアイテムにどのようにアクセスすればよいでしょうか?ありがとうございました –

関連する問題