使用标记上的值将xml转换为字典

时间:2016-06-20 14:47:02

标签: python xml dictionary elementtree

我有一个XML,其中包含每个标记的属性,如下所示:

<?xml version= "1.0" encoding="ISO-8859-1" ?>
<month xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="my.xsd">
    <day Day="2016-1-01">
        <hour Hour="00:00">
            <Variables>
                <a>211.3</a>
                <b>78.94</b>
                <c>0.6</c>
            </Variables>
        </hour>
        <hour Hour="12:00">
            <Variables>
                <a>155.5</a>
                <b>85.5</b>
                <c>0.42</c>
            </Variables>
        </hour>
    </day>
</month>

我希望解析XML并转换为字典,但不能使用带有属性值的标记。

我的意思是,如何能够做出类似的事情:

>>> print d['2016-1-01']['12:00']['b']
>>> 85.5

真正的XML有更多的日子和时间。这可能吗?

我能够解析它的唯一方法就是这个,但是如果你想在不同的时间寻找几个不同的变量那么很难:

# Day
for child_day in root:
    print child_day.tag, child_day.attrib

    # Hour
    for child_hour in child_day:
        print '\t', child_hour.tag, child_hour.attrib

        # Variables
        for child_Variables in child_hour:
            print '\t\t', child_Variables.find('b').text

是否有任何与this answer类似的功能与属性案例相同而不是标签?

2 个答案:

答案 0 :(得分:4)

您关联的答案是使用名为dict comprehension的内容。它是一个非常简单和优雅的解决方案,因为它会在ElementTree的每个级别执行相同的操作以生成dict的该级别,以便该函数可以递归地调用自身。

但是,如果我理解正确,您将会抓取每个代码的不同属性,具体取决于您在ElementTree的结构中所处的级别dict。{{1} }键,然后您将在底层将其切换为使用标记名称作为键,将文本作为值。因此,我无法提出一个与您所链接的答案中的解决方案一样优雅的解决方案。

我们也可以使用字典理解,但我们必须使用它几次(至少对于我提出的解决方案)。

听起来你好像希望得到一个dict看起来像这样(给出你的样本XML):

{
    "2016-1-01": {
        "12:00": {
            "a": "155.5",
            "b": "85.5",
            "c": "0.42",
        },
        "00:00": {
            "a": "211.3",
            "b": "78.94",
            "c": "0.6",
        },
    },
}

要做到这一点,你需要3个功能; 1用于处理dict(天,小时和变量)的每个级别的创建。这是他们的样子:

def month_etree_to_dict(month):
    d_list = month.getchildren()
    d_dict = {d.attrib["Day"]: day_etree_to_dict(d) for d in d_list}
    return d_dict

def day_etree_to_dict(day):
    h_list = day.getchildren()
    h_dict = {h.attrib["Hour"]: hour_etree_to_dict(h) for h in h_list}
    return h_dict

def hour_etree_to_dict(hour):
    v_list = hour.getchildren()[0].getchildren()
    v_dict = {v.tag: v.text for v in v_list}
    return v_dict

函数month_etree_to_dict生成dict,其中键是每天的日期。值是使用day_etree_to_dict函数生成的字典。 day_etree_to_dict函数通过调用hour_etree_to_dict函数为每小时执行相同的操作。 hour_etree_to_dict函数在ElementTree中向下跳过一个额外的级别会有所不同,因此它可以遍历<Variables> Element个孩子({{1} }},<a><b>)使用其标记名称作为<c>的关键字及其值的文本。

我希望这是有道理的,对你有用。

答案 1 :(得分:1)

在将XML转换为dict时,我经常使用递归defaultdict,如下所示:

import xml.etree.ElementTree as ET
from collections import defaultdict


def Tree():
    return defaultdict(Tree)

tree = ET.parse('x.xml')
root = tree.getroot()
d = Tree()
for day in root.findall('day'):
    for hour in day.findall('hour'):
        for v in hour.findall('./Variables/*'):
            d[day.attrib['Day']][hour.attrib['Hour']][v.tag] = v.text

print d['2016-1-01']['12:00']['b']

参考: