1

I am trying to sort the xml based on code in the field tag.

Below is the code implementation I tried but it is printing only one field

Sorting should be mainly done on code attribute

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"))

1 Answer 1

1

You can remove the redundant loop and pass myvalues directly to sorted. When you call sorted, it will iterate over data Element.

The lambda should look like this:

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

which will get the first child (field) from the values and return the code to use as a sorting key.

Then, you can just regenerate the XML from myvalues directly - there's no need to assign anything back to tree.

The following should work for you:

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"))

Which gives the output:

<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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.