根据 python 中的属性对 xml 进行排序

sort xml based on attribute in python

我正在尝试根据字段标记中的代码对 xml 进行排序。

下面是我试过的代码实现,但它只打印一个字段

排序主要针对代码属性

import xml.etree.ElementTree as ET
xmlData = '''<data>
<values>
<field code="6">rst</field>
<show>qwerty6</show>
<chip/>
<normal/>
</values>
<values>
<field code="5">opq</field>
<show>qwerty5</show>
<chip/>
<normal/>
</values>
<values>
<field code="4">klm</field>
<show>qwerty4</show>
</values>
<values>
<field code="3">hij</field>
<show>qwerty3</show>
<chip/>
<normal/>
</values>
<values>
<field code="2">efg</field>
<show>qwerty2</show>
<chip/>
<normal/>
</values>
<values>
<field code="1">abc</field>
<show>qwerty1</show>
</values>
</data>'''

tree = ET.fromstring(xmlData)
myvalues = tree.find('values')

for el in myvalues:
    el[:] = sorted(el, key=lambda e: (e.tag, e.attrib['code']))
tree[:] = myvalues

xmlstr = ET.tostring(tree, encoding="utf-8", method="xml")
print(xmlstr.decode("utf-8"))

您可以删除冗余循环并将 myvalues 直接传递给 sorted。当你调用 sorted 时,它会遍历 data Element.

lambda 应该是这样的:

lambda value: value[0].get("code")

这将从 values 和 return 中获取第一个 child (field) 作为排序键。

然后,您可以直接从 myvalues 重新生成 XML - 无需将任何内容分配回 tree

以下应该适合您:

import xml.etree.ElementTree as ET

xmlData = """
<data>
<values>
<field code="6">rst</field>
<show>qwerty6</show>
<chip/>
<normal/>
</values>
<values>
<field code="5">opq</field>
<show>qwerty5</show>
<chip/>
<normal/>
</values>
<values>
<field code="4">klm</field>
<show>qwerty4</show>
</values>
<values>
<field code="3">hij</field>
<show>qwerty3</show>
<chip/>
<normal/>
</values>
<values>
<field code="2">efg</field>
<show>qwerty2</show>
<chip/>
<normal/>
</values>
<values>
<field code="1">abc</field>
<show>qwerty1</show>
</values>
</data>
"""

tree = ET.ElementTree(ET.fromstring(xmlData))
myvalues = tree.getroot()
myvalues[:] = sorted(myvalues, key=lambda value: value[0].get("code"))
xmlstr = ET.tostring(myvalues, encoding="utf-8", method="xml")
print(xmlstr.decode("utf-8"))

给出输出:

<data>
<values>
<field code="1">abc</field>
<show>qwerty1</show>
</values>
<values>
<field code="2">efg</field>
<show>qwerty2</show>
<chip />
<normal />
</values>
<values>
<field code="3">hij</field>
<show>qwerty3</show>
<chip />
<normal />
</values>
<values>
<field code="4">klm</field>
<show>qwerty4</show>
</values>
<values>
<field code="5">opq</field>
<show>qwerty5</show>
<chip />
<normal />
</values>
<values>
<field code="6">rst</field>
<show>qwerty6</show>
<chip />
<normal />
</values>
</data>