Weiß jemand, wie ich eine DOM-Instanz (Baum) von einer XML-Datei in Python erhalten würde. Ich versuche, zwei XML-Dokumente miteinander zu vergleichen, die Elemente und Attribute in unterschiedlicher Reihenfolge haben können. Wie würde ich dies tun?
Antworten
Zu viele Anzeigen?Ich persönlich würde, wann immer möglich, mit Elementbaum (vorzugsweise die C-Implementierung, die in der Standardbibliothek von Python enthalten ist, oder die lxml Umsetzung, aber das ist im Wesentlichen nur eine Frage der höheren Geschwindigkeit). Es ist kein standardkonformes DOM, enthält aber dieselben Informationen auf eine pythonischere und handlichere Weise. Sie können beginnen mit dem Aufruf von xml.etree.ElementTree.parse
die die XML-Quelle nimmt und einen Elementbaum zurückgibt; tun Sie das für beide Quellen, verwenden Sie getroot
auf jeden Elementbaum, um sein Wurzelelement zu erhalten, und vergleicht dann rekursiv die Elemente ausgehend von den Wurzelelementen.
Kinder eines Elements bilden eine Sequenz, im Elementbaum genau wie im Standard-DOM, was bedeutet, dass ihre Reihenfolge als wichtig erachtet wird; aber es ist einfach, Python-Sets aus ihnen zu machen (oder mit etwas mehr Aufwand "Multi-Sets" irgendeiner Art, wenn Wiederholungen in Ihrem Anwendungsfall wichtig sind, obwohl die Reihenfolge nicht wichtig ist) für einen laxeren Vergleich. Noch einfacher ist es bei Attributen für ein bestimmtes Element, wo die Eindeutigkeit gewährleistet ist und die Reihenfolge semantisch nicht relevant ist.
Gibt es einen bestimmten Grund, warum Sie einen Standard-DOM und nicht einen alternativen Container wie einen Elementbaum benötigen, oder verwenden Sie nur den Begriff DOM in einem allgemeinen Sinne, so dass Elementbaum OK wäre?
In der Vergangenheit habe ich auch gute Ergebnisse erzielt mit PyRXP , das eine noch deutlichere und einfachere Darstellung als ElementTree verwendet. Allerdings ist das schon viele Jahre her; ich habe keine aktuellen Erfahrungen damit, wie PyRXP heute im Vergleich zu lxml oder cElementTree abschneidet.
Für den Vergleich von XML-Dokumenteninstanzen funktioniert ein naiver Vergleich der geparsten DOM-Bäume nicht. Sie müssen wahrscheinlich Ihren eigenen NodeComperator implementieren, der einen Knoten und seine Kindknoten rekursiv mit einem anderen Knoten und seinen Kindknoten vergleicht, und zwar auf der Grundlage Ihrer spezifischen Kriterien, wie z. B.:
- Wann ist die Reihenfolge der untergeordneten Elemente von Bedeutung?
- Wann ist Leerraum in Textinhalten von Bedeutung?
- Gibt es für einige Elemente Standardwerte und werden diese von Ihrem Parser angewendet?
- Sollten Entitätsreferenzen zum Vergleich erweitert werden
Minidom ist ein guter Ausgangspunkt für das Parsen der Dateien und ist einfach zu benutzen. Die eigentliche Implementierung der Vergleichsfunktion für Ihre spezifische Anwendung müssen Sie jedoch selbst vornehmen.