Ich suche ein Windows-basiertes Diff-Tool, das mir die Unterschiede zwischen zwei XML-Dateien anzeigt, dies jedoch baumbasiert und nicht zeilenbasiert macht .
Das heißt, wenn ein Abschnitt an eine völlig andere Stelle in der Datei verschoben wurde, sollte er keine Unterschiede melden.
Diese beiden Dateien sollten als "gleich" gemeldet werden:
<soapenv:Body>
<mes:GetItem>
<mes:ItemShape>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:BodyType>Text</typ:BodyType>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Subject" />
<typ:FieldURI FieldURI="item:Categories" />
</typ:AdditionalProperties>
</mes:ItemShape>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
</mes:GetItem>
</soapenv:Body>
<soapenv:Body>
<mes:GetItem>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
<mes:ItemShape>
<typ:BodyType>Text</typ:BodyType>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Categories" />
<typ:FieldURI FieldURI="item:Subject" />
</typ:AdditionalProperties>
</mes:ItemShape>
</mes:GetItem>
</soapenv:Body>
Und natürlich sollten alle Unterschiede markiert werden, vorzugsweise in einer Seite-an-Seite-Ansicht mit Indikatoren oder Linien, die die unterschiedlichen Abschnitte verbinden.
Kostenlos wäre schön.
Optional Namensräume zu ignorieren wäre nett.
Technisch gesehen sind XMLs anders
aber natürlich können Sie entscheiden, ob Sie dies ignorieren oder nicht, basierend auf den semantischen Informationen, die ein XML nicht hat.
Microsoft hat für diesen Zweck das Tool XML Diff and Patch entwickelt, das Sie in Ihre eigenen Anwendungen integrieren können .
Hinweis: Das Tool wird als "SQLXML Bulkload in .NET Code Sample" installiert und enthält eine Visual Studio-Lösung XmlDiffView.sln
, die Sie selbst kompilieren müssen. Einige grundlegende Programmierkenntnisse in C# und Visual Studio Community Edition sollten in Ordnung sein.
Wie in einer der Antworten auf Stack Overflow erwähnt , wurde es jedoch kompiliert und auf Bitbucket verfügbar gemacht .
Danach kommt es mit einer Benutzeroberfläche, mit der Sie die verschiedenen XML-Vergleichsoptionen auswählen können:
Wenn ich es auf die 2 XMLs Ihrer Fragen anwende, wird eine Ausnahme ausgelöst. Das liegt an den nicht definierten Namespaces. Nach dem Entfernen der Namespaces heißt es:
Die Konzentration auf den Teil, dass verschobene Abschnitte gemeldet werden sollten, da kein Unterschied vorhanden war, ließ mich an https://semanticmerge.com/ denken , das keine XML-Dateien, sondern C#- und C-Code vergleicht. Und da es diese Sprachen versteht, kann es anzeigen, ob der Code verschoben und nicht geändert wurde.
Dies führt zu einem alternativen Ansatz für diese Frage: Könnte es möglich sein, das XML in C#-Klassen zu übersetzen und dann eine semantische Zusammenführung des resultierenden Codes durchzuführen?
Ein möglicher Ansatz, falls dieses Tool noch nicht geschrieben wurde, könnte darin bestehen, jedes einzelne Element in Klassen und jedes Attribut (und den Haupttext) in eine Zeichenfolgeneigenschaft innerhalb dieser Klasse zu übersetzen. Wenn Sie Namensräume ignorieren möchten, lassen Sie sie von Ihrem Übersetzer im Übersetzungsprozess entfernen.
Ich habe das als Proof of Concept angegebene XML-Beispiel übersetzt und Folgendes erhalten:
class soapenv__Body {
class mes__GetItem {
class mes__ItemShape {
class typ__BaseShape {
string body="IdOnly";
}
class typ__BodyType {
string body="Textus";
}
class typ__AdditionalProperties {
class typ__FieldURI {
string FieldURI="item:Subject";
}
class typ__FieldURI {
string FieldURI="item:Categories";
}
}
}
class mes__ItemIds {
class typ__ItemId {
string Id="AAMYAAA=";
}
}
}
}
Dann habe ich das mes:ItemIds
und mes:ItemShape
vertauscht und den Text in geändert Textus
. Verglich die folgenden zwei Dateien in Semantic Merge und erhielt das folgende Bild:
In diesem Bild kann man die Bewegung sehen, die durch das M
Symbol angezeigt wird, und die Textänderung, die durch das C
Symbol angezeigt wird. Linien zeigen an, wo sich die verschiedenen Teile bewegt/geändert haben, und es ist möglich, die Unterschiede tatsächlich zu sehen, falls vorhanden.
Beachten Sie, dass Semantic Merge, obwohl es C#-Code versteht, nicht zu streng auf die identischen Klassennamen von typ__FieldURI
ist, was ein nettes Feature sein könnte, da XML mehrere Knoten mit demselben Namen enthalten kann.
Summa summarum: Semantic Merge kann XML korrekt als identisch (oder nicht) identifizieren, obwohl Elemente verschoben werden, wenn Sie das XML in eine C#-Klassenstruktur konvertieren können.
typ:FieldUri
Elemente zu verschieben, und Semantic Merge hat sie korrekt als verschoben identifiziert. So wird die Reihenfolge korrekt erkannt und Sie können die Reihenfolge der Attribute verfolgen, wenn Sie dies wünschen.Technisch gesehen sind diese nicht gleich (zumindest in XML), die Reihenfolge spielt eine Rolle, es sei denn, dies ist im Schema explizit angegeben.
Eine Kombination aus xmlstarlet und normalen zeilenbasierten Dienstprogrammen kann das Problem viel besser handhabbar machen.
Das Folgende vergleicht nur die Struktur, könnte aber erweitert werden, um die Attribute, ihre Werte und den Text zu betrachten
xmlstarlet el snippet1-with-namespaces.xml | sort > structure1.txt
xmlstarlet el snippet2-with-namespaces.xml | sort > structure2.txt
diff structure.txt structure2.txt
Nachdem Sie dies auf Ihren Snippets ausgeführt haben, zeigt der Diff keine Unterschiede, aber es gab einen Fehlertext zu Namespaces (der sicher ignoriert werden kann).
Ich würde ein Tool XiMpLe empfehlen, das in erster Linie der XML-Editor ist, aber auch XML-Dateien auf übersichtliche Weise vergleichen (und zusammenführen) kann. Ihr Beispiel wird verglichen und als identisch bewertet. Es besteht auch die Möglichkeit, Namespaces aufzulösen.
Aktuell versuche ich ein ganz ähnliches Problem für mich zu lösen. Leider habe ich keine Bibliothek gefunden, die meinen Anforderungen entspricht, um eine SVG-Visualisierung eines XML-Vergleichs zu erstellen.
Deshalb habe ich eine Open-Source-Bibliothek gestartet, die vom X-Diff- Algorithmus inspiriert ist. Also nur zum Spaß und in der Hoffnung, jemanden zu finden, der die XmlXdiff- Bibliothek unterstützt. Bis jetzt ist es keine kugelsichere Bibliothek und noch im Aufbau, aber hier ist das Ergebnis für Ihr Beispiel-Snippet:
Code, der dieses Ergebnis erzeugt:
from XmlXdiff.XReport import DrawXmlDiff
_xml1 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
<soapenv:Body>
<mes:GetItem>
<mes:ItemShape>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:BodyType>Text</typ:BodyType>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Subject" />
<typ:FieldURI FieldURI="item:Categories" />
</typ:AdditionalProperties>
</mes:ItemShape>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
</mes:GetItem>
</soapenv:Body>
</frame>"""
_xml2 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
<soapenv:Body>
<mes:GetItem>
<mes:ItemIds>
<typ:ItemId Id="AAMYAAA="/>
</mes:ItemIds>
<mes:ItemShape>
<typ:BodyType>Text</typ:BodyType>
<typ:BaseShape>IdOnly</typ:BaseShape>
<typ:AdditionalProperties>
<typ:FieldURI FieldURI="item:Categories" />
<typ:FieldURI FieldURI="item:Subject" />
</typ:AdditionalProperties>
</mes:ItemShape>
</mes:GetItem>
</soapenv:Body>
</frame>"""
_path1 = '{}\\..\\..\\tests\\simple\\xml1.xml'.format(getPath())
_path2 = '{}\\..\\..\\tests\\simple\\xml2.xml'.format(getPath())
_out = '{}\\..\\..\\tests\\simple\\xdiff.svg'.format(getPath())
with open(_path1, "w") as f:
f.write(_xml1)
with open(_path2, "w") as f:
f.write(_xml2)
x = DrawXmlDiff(_path1, _path2)
x.draw()
x.saveSvg(_out)
Zusammenfassend zu Ihren Anforderungen:
XML Compare , entwickelt von DeltaXML, ist ein strukturbewusstes XML-Vergleichstool, das unter Windows sowie Linux und Mac mit Java ausgeführt werden kann. XML Compare kann über die Befehlszeile, die REST-API und die Java-API verwendet werden .
Die Diff-Ausgaben von XML Compare sind gültiges XML, was bedeutet, dass sie problemlos von anderen Anwendungen verarbeitet und über die Nachbearbeitungskonfiguration in andere Ausgabeformate umgewandelt werden können. Änderungen werden durch das Hinzufügen neuer Attribute in der Diff-Ausgabe identifiziert, die angeben, ob der Inhalt oder die Struktur in der A-Eingabe vorhanden war, in der B-Eingabe vorhanden war und ob er in beiden gleich ist oder sich geändert hat. Es folgt einem einfachen „A!=B“-Format, siehe das Beispiel-Snippet unten.
<height deltaxml:deltaV2="A!=B">
<deltaxml:textGroup deltaxml:deltaV2="A!=B">
<deltaxml:text deltaxml:deltaV2="A">up to 1.4 meters</deltaxml:text>
<deltaxml:text deltaxml:deltaV2="B">up to 1.3 meters</deltaxml:text>
</deltaxml:textGroup>
</height>
In Bezug auf Ihre Anforderungen an die Berücksichtigung verschobener Inhalte ist XML Compare in hohem Maße konfigurierbar. Es gibt Dutzende von vorkonfigurierten Eingabe- und Ausgabeprozessoren und Filtern, und mit XSLT können benutzerdefinierte Pipelines und Filter erstellt werden.
Speziell für Ihre Anforderungen gibt es vorkonfigurierte Funktionen zum Vergleichen ordnungsloser Elemente im Falle eines Vergleichs, bei dem die Reihenfolge der Elemente nicht signifikant ist, zum Erkennen und Handhaben von Bewegungen und zum Ignorieren von Änderungen , wenn sie erwartet werden und nicht hervorgehoben werden müssen.
Schließlich ist eines der verfügbaren vorkonfigurierten Ausgabeformate ein Side-by-Side-HTML-Diff-Bericht , der auf der Delta-Ausgabe aufbaut. In Fällen, in denen Sie jedoch eine spezifischere Ausgabe benötigen, können Sie die Ausgabe erneut mit XSLT oder den vorhandenen Konfigurationsoptionen konfigurieren und verarbeiten. Unten ist ein Screenshot des Side-by-Side-Diff-Berichts:
Offenlegung: Ich bin ein Mitarbeiter von DeltaXML.
rrirower
Frank Dernoncourt
RockPaperLz- Maskiere es oder Casket
Dr. Moishe Pippik
James
Ira Baxter
Knut
Wassermann-Kraft
Mast
Benutzer416
Benutzer416