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



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

  • 当一个数组只有1个元素时,它会返回一个带有子元素的迭代器
  • 当一个数组有多个元素时,它会返回一个迭代器,其中包含OrderedDict中的元素

请参阅下面的示例:

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返回一个有一个孩子的列表。

尽管根据https://github.com/martinblech/xmltodict/issues/14,开发人员已经意识到了这一点,但不会修复它

公认的解决方法是将force_list作为参数添加到解析中,从而强制为子元素创建一个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}")´

还有一种建议是覆盖dict_constructor以使用defaultdict

但如果你想这样做的话,你可以浏览这个问题。

最新更新