python - lxml: Erzwingt eine bestimmte Reihenfolge für Attribute

9

Ich habe ein XML-Schreibskript, das XML für ein bestimmtes Drittanbieterwerkzeug ausgibt.

Ich habe den ursprünglichen XML-Code als Vorlage verwendet, um sicherzustellen, dass ich alle korrekten Elemente erstelle, aber das endgültige XML erscheint nicht wie das Original.

Ich schreibe die Attribute in der gleichen Reihenfolge, aber lxml schreibt sie in einer eigenen Reihenfolge.

Ich bin mir nicht sicher, aber ich vermute, dass das dritte Teilwerkzeug erwartet, dass Attribute in einer bestimmten Reihenfolge erscheinen, und ich möchte dieses Problem lösen, damit ich sehen kann, ob es die Attributzuordnung ist, die es scheitern lässt etwas anderes.

Quellelement:

%Vor%

Mein Quellskript:

%Vor%

Mein resultierendes XML:

%Vor%

Gibt es eine Möglichkeit, die Reihenfolge zu beschränken, in der sie geschrieben sind?

    
Jay Gattuso 17.02.2013, 04:20
quelle

3 Antworten

5

Attributreihenfolge und Lesbarkeit Wie die Kommentatoren erwähnt haben, hat die Reihenfolge der Attribute in XML keine semantische Bedeutung, dh sie ändert nicht die Bedeutung eines Elements:

%Vor%

In SQL gibt es ein analoges Merkmal, bei dem sich die Spaltenreihenfolge nicht ändert die Bedeutung einer Tabellendefinition. XML-Attribute und SQL-Spalten sind eine Menge (nicht eine geordnete Menge ), und so kann all das "offiziell" über beides gesagt werden Eine davon ist, ob das Attribut oder die Spalte in der Menge vorhanden ist.

Das heißt, es macht definitiv einen Unterschied für die menschliche Lesbarkeit, welche Ordnung diese Dinge erscheinen in und in Situationen, in denen Konstrukte wie diese verfasst sind und im Text erscheinen (z. B. Quellcode) und interpretiert werden müssen, eine sorgfältige Ordnung macht für mich sehr viel Sinn.

Typisches Parserverhalten

Jeder XML-Parser, der die Attributreihenfolge als signifikant behandelt, würde den XML-Standard nicht einhalten. Das bedeutet nicht, dass es nicht passieren kann, aber nach meiner Erfahrung ist es sicherlich ungewöhnlich. Abhängig von der Bedeutung des Tools, das Sie erwähnen, ist es eine Möglichkeit, die es wert ist, getestet zu werden.

Soweit ich weiß, hat lxml keinen Mechanismus, um die Attribute der Bestellung in serialisiertem XML anzugeben, und ich wäre überrascht, wenn es so wäre.

Um das Verhalten zu testen, wäre ich sehr geneigt, einfach eine textbasierte Vorlage zu schreiben, um genug XML zu generieren, um es zu testen:

%Vor%     
scanny 17.02.2013, 22:58
quelle
13

Es sieht so aus, als ob lxml Attribute in der Reihenfolge serialisiert, in der Sie sie festgelegt haben:

%Vor%

Beachten Sie, dass Python beim Übergeben von Attributen mit dem ET.SubElement () -Konstruktor ein Wörterbuch mit Schlüsselwortargumenten erstellt und dieses Wörterbuch an lxml weiterleitet. Dadurch wird die Reihenfolge verloren, die Sie in der Quelldatei hatten, da die Wörterbücher von Python ungeordnet sind (oder ihre Reihenfolge durch String-Hash-Werte bestimmt wird, die sich von Plattform zu Plattform oder tatsächlich von Ausführung zu Ausführung unterscheiden können). p>     

Marius Gedminas 15.07.2013 12:43
quelle
12

OrderedDict von Attributen

Ab lxml 3.3.3 (vielleicht auch in früheren Versionen) können Sie ein OrderedDict <übergeben / a> von Attributen für den lxml.etree.(Sub)Element -Konstruktor und die Reihenfolge wird beibehalten, wenn lxml.etree.tostring(root) :

verwendet wird %Vor%

Beachten Sie, dass die ElementTree-API ( xml.etree.ElementTree ) nicht die Attributreihenfolge beibehält, selbst wenn Sie dem OrderedDict -Konstruktor xml.etree.ElementTree.(Sub)Element angeben!

UPDATE: Beachten Sie auch, dass die Verwendung des Parameters **extra des Konstruktors lxml.etree.(Sub)Element für die Angabe von Attributen nicht die Reihenfolge der Attribute berücksichtigt:

%Vor%     
Daniel 23.03.2014 19:38
quelle

Tags und Links