提取数据XML-->;Python中的DICT

提取数据XML-->;Python中的DICT,python,xml,python-2.7,Python,Xml,Python 2.7,我有一个包含和的xml文件。虽然我只得到第一个,但我无法循环通过它们。以下是xml结构和代码: 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 """

我有一个包含和的xml文件。虽然我只得到第一个,但我无法循环通过它们。以下是xml结构和代码:

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>
从lxml导入objectify作为xml\u objectify
contents=open('/home/conacons/Documents/order.xml')。read()
def xml_to_dict(xml_str):
“”“使用lxml v3.4.2 xml处理库将xml转换为dict”“”
定义xml到dict递归(xml对象):
dict\u object=xml\u object.\uu dict__
如果不是dict_对象:
返回xml\u对象
对于键,dict_object.items()中的值:
dict\u对象[key]=xml\u到dict\u递归(值)
返回dict_对象
返回xml_to_dict_递归(xml_objectify.fromstring(xml_str))
xml_dict=xml_to_dict(目录)
#打印xml文档
对于项,在xml_dict['item']['items']中为v。items()
打印项目,v
不
7315
测试/001
假的
8.
16.5False0.018单元iPod12.5False0.0M-WIR19单元无线鼠标
当我运行此代码时,我只得到其中一项。如何进行循环以获取项目中的所有项目?谢谢 (产出):
项目{'list_price':16.5,'description':'False','weight':0.0,'default_code':u'','id':18,'uom':'units','name':'iPod'}

您的方法存在问题。XML对象未转换为
dict
,因为
dict
对象不能有重复的键。例如,在您的例子中,当您调用
xml\u对象时,对于
xml\u对象
和多个
子标记,它返回一个
dict
,只有一个
键。因此,您应该使用
getchildren
方法,而不是
\uuuu init\uuu
。但还有另一个问题。对于示例中对应于
项的
xml\u对象
,下一个代码也无法正常工作:

for child in xml_object.getchildren():
    dict_object[child.tag] = xml_to_dict_recursion(child)
您理解的原因是,在所有循环迭代中,
child.tag
具有相同的值

解决这些问题的一种可能方法是使用
collections.defaultdict
。代码可能如下所示:

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))
在这种情况下,输出为:

{'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]}
但在我看来,这种方法并不那么方便,更舒适的方法是使用
lxml.objectify
(请参阅)。例如:

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'])

您可以发布有效的xml文档吗?这个有一些错误。例如,Order、first“item”标记等没有结束标记。这是完整的Order.xml文档,您可以使用xml并通过xml库进行处理,也可以使用json并将其转换为dict进行处理。将xml转换为dict进行处理通常是个坏主意。这不是一个副本吗?很酷,谢谢,伙计,这很管用。现在,因为这将是一个多订单导入系统,我将有一个以上的项目在这里和另一个。我可以使用'for value in xml.'dict['item'][0]['items'][0]['item']:#print value['list_price']print(dict(value))for value in xml.'dict['item'][1]['items'][0]['item']:#print value['list_price']print(dict(value))`来访问它们,但要在手动编写xml.[item'][或xml_dict['item'][2][或xml_dict['item'][3][?非常感谢您真的需要将xml对象转换为字典吗?我认为使用
lxml
方法更方便。好的,简而言之,我如何在不将xml转换为dict的情况下访问订单中的所有订单和项目呢?感谢您更新了我的评论,并提供了解析xml文件的示例。