Python:遍历xmltodict创建的所有嵌套键值对

时间:2016-04-12 17:17:59

标签: python xml recursion

根据xml文件的布局获取特定值非常简单。 (见:StackOverflow

但是当我不知道xml元素时,我无法解决它。 因为xmltodoc在OrderedDicts中嵌套OrderedDicts。这些嵌套的OrderedDicts以Python为典型类型:' unicode'。而不是(仍然)作为OrderedDicts。因此,像这样循环,doens工作:

def myprint(d):
    for k, v in d.iteritems():
        if isinstance(v, list):
            myprint(v)
        else:
            print "Key :{0},  Value: {1}".format(k, v)

我基本上想要的是递归整个xml文件,其中显示了每个键值对。当一个键的值是另一个键值对列表时,它应该递归到它中。

将此xml文件作为输入:

<?xml version="1.0" encoding="utf-8"?>
<session id="2934" name="Valves" docVersion="5.0.1">
    <docInfo>
        <field name="Employee" isMandotory="True">Jake Roberts</field>
        <field name="Section" isOpen="True" isMandotory="False">5</field>
        <field name="Location" isOpen="True" isMandotory="False">Munchen</field>
    </docInfo>
</session>

以及上面列出的代码,会话中的所有数据都作为值添加到密钥会话中。

示例输出:

Key :session,  Value: OrderedDict([(u'@id', u'2934'), (u'@name', u'Valves'), (u'@docVersion', u'5.0.1'), (u'docInfo', OrderedDict([(u'field', [OrderedDict([(u'@name', u'Employee'), (u'@isMandotory', u'True'), ('#text', u'Jake Roberts')]), OrderedDict([(u'@name', u'Section'), (u'@isOpen', u'True'), (u'@isMandotory', u'False'), ('#text', u'5')]), OrderedDict([(u'@name', u'Location'), (u'@isOpen', u'True'), (u'@isMandotory', u'False'), ('#text', u'Munchen')])])]))])

这显然不是我想要的。

1 个答案:

答案 0 :(得分:2)

如果您在数据中遇到一个列表,那么您只需要在列表的每个元素上调用> nul 2>&1 forfiles /D +01-12-2015 /C "forfiles forfiles /M @file /D -31-12-2105 /C 0x22cmd /C if 00x7840isdir==FALSE > con echo 00x7840fdate 00x7840file0x22"

forfiles /C "forfiles forfiles"

然后你会得到类似的输出:

myprint

虽然我不确定这是多么有用,因为你有很多重复的密钥,比如def myprint(d): if isinstance(d,dict): #check if it's a dict before using .iteritems() for k, v in d.iteritems(): if isinstance(v, (list,dict)): #check for either list or dict myprint(v) else: print "Key :{0}, Value: {1}".format(k, v) elif isinstance(d,list): #allow for list input too for item in d: myprint(item) ,我想提供一个我刚才创建的函数来遍历嵌套的{{ 1}}嵌套... Key :@name, Value: Employee Key :@isMandotory, Value: True Key :#text, Value: Jake Roberts Key :@name, Value: Section Key :@isOpen, Value: True Key :@isMandotory, Value: False Key :#text, Value: 5 ... @name s:

的数据
json

然后您可以使用以下内容遍历数据:

dict

使用listdef traverse(obj, prev_path = "obj", path_repr = "{}[{!r}]".format) if isinstance(obj,dict): it = obj.items() elif isinstance(obj,list): it = enumerate(obj) else: yield prev_path,obj return for k,v in it: for data in traverse(v, path_repr(prev_path,k), path_repr): yield data 的默认值,它会提供如下输出:

for path,value in traverse(doc):
    print("{} = {}".format(path,value))

虽然您可以为prev_path编写一个函数来获取path_repr的值(通过递归调用obj[u'session'][u'@id'] = 2934 obj[u'session'][u'@name'] = Valves obj[u'session'][u'@docVersion'] = 5.0.1 obj[u'session'][u'docInfo'][u'field'][0][u'@name'] = Employee obj[u'session'][u'docInfo'][u'field'][0][u'@isMandotory'] = True obj[u'session'][u'docInfo'][u'field'][0]['#text'] = Jake Roberts obj[u'session'][u'docInfo'][u'field'][1][u'@name'] = Section obj[u'session'][u'docInfo'][u'field'][1][u'@isOpen'] = True obj[u'session'][u'docInfo'][u'field'][1][u'@isMandotory'] = False obj[u'session'][u'docInfo'][u'field'][1]['#text'] = 5 obj[u'session'][u'docInfo'][u'field'][2][u'@name'] = Location obj[u'session'][u'docInfo'][u'field'][2][u'@isOpen'] = True obj[u'session'][u'docInfo'][u'field'][2][u'@isMandotory'] = False obj[u'session'][u'docInfo'][u'field'][2]['#text'] = Munchen 确定)和新密钥,例如,如果您想获取索引作为一个元组,你可以这样做:

path_repr

然后输出将是:

prev_path

我发现这在处理我的json数据时特别有用,但我不确定你想用你的xml做什么。