xmltodict does not return a list for one element

断了今生、忘了曾经 提交于 2021-01-19 14:14:42

问题


The following Code produces an error, if there is only one "car" in "garage":

import xmltodict

mydict = xmltodict.parse(xmlstringResults)    
for carsInGarage in mydict['garage']['car']:
    # do something...

The Reason is that mydict['garage']['car'] is only a list if there is more than one element of "car". So I did something like this:

import xmltodict

mydict = xmltodict.parse(xmlstringResults)
if isinstance(mydict['garage']['car'], list):
    for carsInGarage in mydict['garage']['car']:
        # do something for each car...
else:
    # do something for the car

to get the code to run. But for more advanced operations this is no solution.

Does someone know some kind of function to use, even if there is only one element?


回答1:


This problem is discussed in this issue on Github. The xmltodict package now supports

d = xmltodict.parse(s, force_list={'car'})

Although this still doesn't create an empty list if the field is absent.




回答2:


This is of course not an elegant way, but this is what i have done to get the code run (if someone hase the same probleme an found this via google):

import xmltodict

def guaranteed_list(x):
    if not x:
        return []
    elif isinstance(x, list):
        return x
    else:
        return [x]

mydict = xmltodict.parse(xmlstringResults)    
for carsInGarage in guaranteed_list(mydict['garage']['car']):
    # do something...

but i thing i will write my code again and "use XML directly" as one of the comments said.




回答3:


I am using the combination of

1)

json_dict = xmltodict.parse(s, force_list={'item'})

And

2)

# Removes a level in python dict if it has only one specific key
# 
# Examples: 
# recursive_skip_dict_key_level({"c": {"a": "b"}}, "c")  # -> {"a", "b"}
# recursive_skip_dict_key_level({"c": ["a", "b"]}, "c") # -> ["a", "b"]
#
def recursive_skip_dict_key_level(d, skipped_key):
    if issubclass(type(d), dict):
        if list(d.keys()) == [skipped_key]:
            return recursive_skip_dict_key_level(d[skipped_key], skipped_key)
        else:
            for key in d.keys():
                d[key] = recursive_skip_dict_key_level(d[key], skipped_key)
            return d
    elif issubclass(type(d), list):
        new_list = []
        for e in d: 
            new_list.append(recursive_skip_dict_key_level(e, skipped_key))
        return new_list
    else: 
        return d

# Removes None values from a dict
# 
# Examples: 
# recursive_remove_none({"a": None})  # -> {}
# recursive_remove_none([None]) # -> []
#
def recursive_remove_none(d):
    if issubclass(type(d), dict):
        new_dict = {}
        for key in d.keys():
            if not (d[key] is None):
                new_dict[key] = recursive_remove_none(d[key])
        return new_dict
    elif issubclass(type(d), list):
        new_list = []
        for e in d: 
            if not (e is None):
                new_list.append(recursive_remove_none(e))
        return new_list
    else: 
        return d       

json_dict = recursive_skip_dict_key_level(json_dict, "item")
json_dict = recursive_remove_none(json_dict)

to interpret any "item" XML-elements as lists.



来源:https://stackoverflow.com/questions/37207353/xmltodict-does-not-return-a-list-for-one-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!