LXML – Orden de etiqueta de clasificación

Tengo un formato de archivo heredado que estoy convirtiendo a XML para su procesamiento. La estructura se puede resumir como:

 X Y Z  

La parte numérica de las tags puede ir de 01 a 99 y puede haber espacios. Como parte del procesamiento, ciertos registros pueden tener tags adicionales agregadas. Una vez que se completa el procesamiento, estoy convirtiendo el archivo nuevamente al formato heredado por iterwalking the tree. Los archivos son razonablemente grandes (~ 150,000 nodos).

Un problema con esto es que algún software que usa el formato heredado asume que las tags (o más bien los campos para el momento en que se convierta) estarán en orden alfanumérico, pero de manera predeterminada se agregarán nuevas tags al final de la twig que luego hace que salgan del iterador en el orden incorrecto.

¿Puedo usar xpath para encontrar al hermano precedente en función del nombre de la etiqueta cada vez que vengo a agregar una nueva, pero mi pregunta es si hay una forma más sencilla de ordenar el árbol a la vez justo antes de exportar?

Editar:

Creo que he resumido la estructura.

Un registro puede contener varios niveles como se describe anteriormente para dar algo como:

  1 2 3  X Y Z   Z X C   

Es posible escribir una función auxiliar para insertar un nuevo elemento en el lugar correcto, pero sin saber más sobre la estructura es difícil convertirla en genérica.

Aquí hay un breve ejemplo de cómo clasificar elementos secundarios en todo el documento:

 from lxml import etree data = """ 3 2  Y X Z  1  Z X C  """ doc = etree.XML(data,etree.XMLParser(remove_blank_text=True)) for parent in doc.xpath('//*[./*]'): # Search for parent elements parent[:] = sorted(parent,key=lambda x: x.tag) print etree.tostring(doc,pretty_print=True) 

Flexible:

   X Y Z   Z X C  1 2 3  

Puedes ordenar tus elementos xml de esta manera:

 from operator import attrgetter from lxml import etree root = etree.parse(xmlfile) children = list(root) sorted_list = sorted(children, key=attrgetter('tag')) 

Si esto se ejecuta demasiado lento, puede ordenar los nombres de las tags y obtener el nodo mediante xpath:

 tag_list = [item.tag for item in root] sorted_taglist = sorted(tag_list)