С использованием BeautifulSoup
:
data = '''
<annotation>
<object>
<name>medium</name>
<pose>Left</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>267</xmin>
<ymin>273</ymin>
<xmax>415</xmax>
<ymax>324</ymax>
</bndbox>
</object>
<object>
<name>medium</name>
<pose>Left</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>105</xmin>
<ymin>229</ymin>
<xmax>261</xmax>
<ymax>292</ymax>
</bndbox>
</object>
</annotation>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'xml')
soup.annotation.contents = sorted(soup.annotation.select('object'), key=lambda k: int(k.select_one('ymin').text))
# For XML pretty print, sorted XML is inside `soup`
from xml.dom import minidom
xmlstr = minidom.parseString(str(soup)).toprettyxml(indent=" ").replace('\n\n', '').strip()
print(xmlstr)
Печать:
<?xml version="1.0" ?>
<annotation>
<object>
<name>medium</name>
<pose>Left</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>105</xmin>
<ymin>229</ymin>
<xmax>261</xmax>
<ymax>292</ymax>
</bndbox>
</object>
<object>
<name>medium</name>
<pose>Left</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>267</xmin>
<ymin>273</ymin>
<xmax>415</xmax>
<ymax>324</ymax>
</bndbox>
</object>
</annotation>
РЕДАКТИРОВАНИЕ (с чтением / записью из / в файл XML):
from bs4 import BeautifulSoup
with open('file.xml', 'r') as f_in:
soup = BeautifulSoup(f_in.read(), 'xml')
soup.annotation.contents = sorted(soup.annotation.select('object'), key=lambda k: int(k.select_one('ymin').text))
# For XML pretty print, sorted XML is inside `soup`
from xml.dom import minidom
xmlstr = minidom.parseString(str(soup)).toprettyxml(indent=" ").replace('\n\n', '').strip()
with open('file_out.xml', 'w') as f_out:
f_out.write(xmlstr)