I hope you are doing fine guys.
I am trying to sort the XML with a predefined order as a primary criteria and as a second criteria based on the "id" the XML file I am working on before exporting it. I am using "xml.etree.ElementTree", and I have added all the elements and subelements as it's required, the last portion I can't solve is the sorting.
The XML exported XML is as followed:
<List>
<Level1>
<LevelA id="zzz"/>
<DO name="Info01"/>
</LevelA >
<LevelB id="ccc"/>
<DO name="Info01"/>
</LevelB>
<LevelA id="aaa"/>
<DO name="Info01"/>
</LevelA >
<LevelC id="bbb"/>
<DO name="Info01"/>
</LevelC>
<LevelA id="ddd"/>
<DO name="Info01"/>
</LevelA>
<LevelB id="aaa"/>
<DO name="Info01"/>
</LevelB>
<LevelC id="aaa"/>
<DO name="Info01"/>
</LevelC>
</Level1>
</List>
The defined order is:
predefined_order = [ 'LevelA', 'LevelB', 'LevelC']
Expected:
<List>
<Level1>
<LevelA id="aaa"/>
<DO name="Info01"/>
</LevelA >
<LevelA id="ddd"/>
<DO name="Info01"/>
</LevelA>
<LevelA id="zzz"/>
<DO name="Info01"/>
</LevelA >
<LevelB id="aaa"/>
<DO name="Info01"/>
</LevelB>
<LevelB id="ccc"/>
<DO name="Info01"/>
</LevelB>
<LevelC id="aaa"/>
<DO name="Info01"/>
</LevelC>
<LevelC id="bbb"/>
<DO name="Info01"/>
</LevelC>
</Level1>
</List>
Please help me giving me some clues.
Thanks
D
CodePudding user response:
Try:
xml_doc = """
<List>
<Level1>
<LevelA id="zzz">
<DO name="Info01"/>
</LevelA>
<LevelB id="ccc">
<DO name="Info01"/>
</LevelB>
<LevelA id="aaa">
<DO name="Info01"/>
</LevelA>
<LevelC id="bbb">
<DO name="Info01"/>
</LevelC>
<LevelA id="ddd">
<DO name="Info01"/>
</LevelA>
<LevelB id="aaa">
<DO name="Info01"/>
</LevelB>
<LevelC id="aaa">
<DO name="Info01"/>
</LevelC>
</Level1>
</List>
"""
from xml.etree.ElementTree import fromstring, tostring
myxml = fromstring(xml_doc)
predefined_order = ["LevelA", "LevelB", "LevelC"]
level1 = myxml.find(".//Level1")
level1[:] = sorted(
level1,
key=lambda child: (predefined_order.index(child.tag), child.get("id")),
)
print(tostring(myxml).decode("utf-8"))
Prints:
<List>
<Level1>
<LevelA id="aaa">
<DO name="Info01" />
</LevelA>
<LevelA id="ddd">
<DO name="Info01" />
</LevelA>
<LevelA id="zzz">
<DO name="Info01" />
</LevelA>
<LevelB id="aaa">
<DO name="Info01" />
</LevelB>
<LevelB id="ccc">
<DO name="Info01" />
</LevelB>
<LevelC id="aaa">
<DO name="Info01" />
</LevelC>
<LevelC id="bbb">
<DO name="Info01" />
</LevelC>
</Level1>
</List>