带有 force_list 参数的 xmltodict returns 带有 None 元素的列表用于空 XML 列表

xmltodict with force_list argument returns a list with None element for empty XML list

我正在用 xmltodictforce_list=('xml_tag') 解析 XML 以获得 XML 列表中单个元素的列表。它有效!但是,如果 xml_tag 没有 child,它会 returns 一个 [None](列表只有一个 None object)。如何预防?

XML

<Something>
    <Guitar>
        <name>Walden</name>
        <strings>5</strings>
    </Guitar>
    <Pokemons>
    </Pokemons>
</Something>

PYTHON

res = xmltodict.parse(xml, force_list=('Pokemons',))

res = res['Something']['Guitar']['Pokemons']

pprint(res)

>>> [None]

有什么建议吗?

[更新]

抱歉,我没有说明我想要什么。 我想得到空列表,因为结果没有列出 None 元素

xmltodict.parse(使用 force_list arg)将 xml 转换为 OrderedDict 并将标签作为键,而不管节点是否为空(如果节点为空None 值存储在字典中)。

因此您必须自己过滤 None 的字典结果。

要过滤字典,您可以定义自定义方法:

def filter_dict(item):
    if not item:
        return ''
    elif isinstance(item, list):
        return [it for it in item if it]
    elif not hasattr(item, 'items'):
        return item
    else:
        return {key: filter_dict(value) for key, value in item.items()}


>>> res = xmltodict.parse(xml, force_list=('Pokemons',))
>>> res = filter_dict(res)
>>> pokemons = res['Something']['Pokemons']
>>> pokemons
>>> []

您可以将后处理函数传递给 xmltodict,它允许您修改字典值。
但是后处理需要 return 一个键和一个值:

import xmltodict
import json


def postprocessor(path, key, value):
    if key == 'Pokemons' and not value:
        return key, []
    return key, value

xml = """<Something>
    <Guitar>
        <name>Walden</name>
        <strings>5</strings>
    </Guitar>
    <Pokemons>
    </Pokemons>
</Something>"""


res = xmltodict.parse(xml, postprocessor=postprocessor)
print(json.dumps(res, indent=2, sort_keys=True))

输出:

{
  "Something": {
    "Guitar": {
      "name": "Walden",
      "strings": "5"
    },
    "Pokemons": []
  }
}