Python xmltodict 在 XML 数组中显示不一致的行为

Python xmltodict shows inconsistent behaviour in XML arrays

恕我直言,我在 Python xmltodoct.parse 函数中看到了一些不一致的行为。

参见下面的示例:

import xmltodict

if __name__ == "__main__":
    xml01 = """
            <A>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
            </A>
    """

    xd = xmltodict.parse(xml01)
    print(xd)
    for x in xd['A']['C']:
        print(f"xml01: {x}")

    xml02 = """
            <A>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
            </A>
    """

    xd = xmltodict.parse(xml02)
    for x in xd['A']['C']:
        print(f"xml02: {x}")

输出为:

xml01: D
xml01: E
xml02: OrderedDict([('D', 'DDDD'), ('E', 'EEEE')])
xml02: OrderedDict([('D', 'DDDD'), ('E', 'EEEE')])

我希望第一个迭代器的输出是:

xml01: OrderedDict([('D', 'DDDD'), ('E', 'EEEE')])

现在您需要对迭代器的返回值进行一些类型检查,以了解是否有一个或多个元素。 对于更多元素,您需要进行新循环。

我很好奇 Python 专家对此有何看法以及他们的解决方案是什么。

你是对的。

如果您要问我的意见,那么我认为应该将其更改为 xml01 return 一个包含 child.

的列表

虽然根据 https://github.com/martinblech/xmltodict/issues/14,开发人员知道这一点但不会修复它。

可接受的解决方法是将 force_list 作为参数添加到解析中,从而强制 child 元素的列表为 OrderedDict

在你的情况下,这看起来像这样:

import xmltodict

if __name__ == "__main__":
    xml01 = """
            <A>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
            </A>
    """

    xd = xmltodict.parse(xml01, force_list=set('C'))
    for x in xd['A']['C']:
        print(f"xml01: {x}")

    xml02 = """
            <A>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
                    <C>
                        <D>DDDD</D>
                        <E>EEEE</E>
                    </C>
            </A>
    """

    xd = xmltodict.parse(xml02, force_list=set('C'))
    for x in xd['A']['C']:
        print(f"xml02: {x}")´

也有人提议用defaultdict覆盖dict_constructor

但是如果您愿意的话,您可以浏览这个问题。