Einführung
Schnellstart
XTC im
Detail
Technische Anmerkungen
XTC (Xml Tree Compare) ist ein Differenzwerkzeug für XML
Dateien. Es handelt sich um eine Weiterentwicklung eines
Freewareprogramms, das 2008 im Internet veröffentlicht worden ist
(xmldifftool.com). Der Zweck des Programms ist es, als
'Änderungserkennungswerkzeug' für zwei Versionen eines Dokuments
(eine alte und eine neue Version beispielsweise) eingesetzt zu
werden. Der Freewareversion fehlte allerdings einige von
Anwenderseite gewünschte Funktionalität. Deshalb verfügt die
vorliegende Version über eine Reihe neu entwickelter
Funktionalitäten und Verbesserungen.
Die wichtigsten davon sind:
Gesteigerte Performance:
XTC
vergleicht zwei 10 MB große Dateien in 3 - 6 Sekunden, je nach
Änderungsgrad und gewählter Konfiguration (und verwendeter
Hardware). Eine Multithread-Version ist noch deutlich schneller
(erhältlich auf Anfrage).
Attribute:
Attribute können
in den Vergleich miteinbezogen oder davon ausgeschlossen werden, die
Attributreihenfolge kann ignoriert oder beachtet werden.
Gelöschte Elemente:
Können
in der Ergebnisdatei erscheinen oder ausgeschlossen werden.
Vergleich von Textelementen:
Textelemente mit inhaltlichen Änderungen können einem
zusätzlichen Textvergleich (dabei wird u.a. der 'Longest Common
Substring'-Algorithmus (LCSS) verwendet) unterzogen werden.
Die Ankerfunktionalität (eine der Kernfunktionalitäten) wurde erweitert
Der Vergleichsprozess ist so generisch wie möglich konzipiert.
Die einzige Voraussetzung ist die Wohlgeformtheit der XML-Dokumente.
Es kann daher jedes von XML abgeleitete Format wie SVG, XVL etc.
verglichen werden. Das Ergebnis des Vergleichsprozesses wird in eine
Datei geschrieben (Ergebnisdatei). Zusätzlich steht eine graphische
Darstellung als Baumstruktur zur Verfügung.
XTC ist geeignet
um:
eine Ergebnisdatei im XML-Format zu erzeugen, die anschließend weiterverarbeitet (z.B. mit XSLT) werden kann.
ein Vergleichsergebnis unmittelbar in der Visualisierung zu betrachten.
für große Dateien (> 50 MB) länger dauernde Vergleichsprozesse mit der Server-Version durchzuführen. Die Dateigröße ist dabei nur durch den verfügbaren Arbeitsspeicher des Rechners begrenzt.
XTC kann in andere Prozesse integriert werden, indem die Server-Version wie ein Batch-Prozess aufgerufen wird.
A) GUI-Version:
1. Starten Sie XTC mit einem Doppelklick auf
das Programmsymbol oder durch den Aufruf im 'Programme'-Menü von
Windows. Das XTC Hauptfenster erscheint. Wählen Sie zwei XML-Dateien
mittels der Schaltflächen 'XML Datei 1' und 'XML Datei 2' aus. Die
Dateipfade erscheinen links der beiden Schaltflächen in den weißen
Editboxen.
2. Drücken Sie die große Schaltfläche 'Diff'.
3. Je
nach Größe der beiden Dateien und der Hardware kann der
Vergleichsprozess einige Sekunden dauern. Dabei verwandelt sich der
Mauszeiger in eine Sanduhr.
4. Eine Messagebox informiert Sie,
sobald der Vergleichsvorgang abgeschlossen ist.
5. Nach
Beendigung des Vergleichsprozesses kann das Ergebnis durch Druck auf
den Button ganz links in der Werkzeugleiste (Baumsymbol) visualisiert
werden. Ein separates Fenster öffnet sich und zeigt die Struktur der
ersten XML-Datei auf der linken, die Struktur der zweiten XML-Datei
einschließlich der Differenzmarkierungen auf der rechten Seite. Die Visualisierung
verfügt über eine interaktive Funktionalität: wird ein Element in einem der
Bäume selektiert, werden das korrespondierende Element im anderen Baum und
das selektierte Element selbst farbig hervorgehoben.
B) Kommandozeilenversion:
1. Öffnen Sie eine Shell
(DOS-Box auf Windows) und wechseln Sie in das Verzeichnis der
XTC-Programmdatei.
2. Tippen Sie 'xtc.exe xmlfile1 xmlfile2
-batch' ein. Dabei ist 'xmlfile1' der Pfad zur ersten XML-Datei,
'xmlfile2' der Pfad zur zweiten XML-Datei.
3. Je nach Dateigrößen
und Hardware dauert der Vergleichsvorgang einige Sekunden.
4.
Nach Beendigung des Vergleichsprozesses befindet sich die
Ergebnisdatei im Verzeichnis der zweiten XML-Datei. Falls Sie dort
keine Ergebnisdatei finden sollten, sehen Sie in der
Konfigurationsdatei (xtc_cfg.xml im aktuellen Verzeichnis oder in
Ihrem Home-Verzeichnis) nach dem Eintrag <writeresultfile>.
Dieser muss so
aussehen:
<xtcparam_bool name="writeresultfile">1</xtcparam_bool>.
Ansonsten
prüfen Sie, ob es Hinweise auf Fehler in der Logdatei gibt
(xtclog.txt).
Beispiel für eine Ergebnisdatei (Ausschnitt):
Das Vergleichen von XML-Dokumenten kann vielfältig motiviert sein. Beispielsweise möchte man schnell und auf einen Blick sehen, was sich an einem Dokument in Bezug auf seine Vorgängerversion geändert hat. Oder die Änderungen sollen bei der Weiterverarbeitung des Dokuments in einer formatierten Version kenntlich gemacht werden. Ebenso kann es aus Gründen der Qualitätssicherung notwendig sein, Änderungen die per Augenschein nur schwer zu finden sind, z.B. an Zeichnungen im SVG-Format, zu protokollieren.
Erkannte Änderungen werden in der Ergebnisdatei mit
Differenzmarkierungen gekennzeichnet. Eine Differenzmarkierung ist
eine Processing Instruction die das Vergleichsergebnis für das
direkt nachfolgende XML-Element beschreibt. Jede erkannte Änderung
wird mit einer der folgenden zehn Differenzmarkierungen versehen:
complete match
position change
content change
attribute
change
attribute and content change
position and content
change
position and attribute change
position and content and
attribute change
element added
element deleted
Vier
davon (position change, position and content change, position and
attribute change, position and content and attribute change) zeigen
an, dass das Element seine Position geändert hat. Die Distanz der
Positionsänderung wird durch eine Zahl an der Differenzmarkierung
angezeigt. Eine Zahl größer Null bedeutet eine Positionsänderung
'vorwärts' ('nach unten'), d.h. die Entfernung zum Elternelement hat
sich vergrößert (z.B. weil oberhalb ein neues Element eingeschoben
wurde). Eine negative Zahl zeigt an, dass sich das Element nun näher
an seinem Elternelement befindet (z.B. weil vorher ein Element
gelöscht wurde).
Beispiel:
Datei
A:
<parent>
<one/>
<two/>
<three/>
</parent>
file
B:
<parent>
<one/>
<two/>
<hundred/>
<three/>
</parent>
Das
Ergebnis lautet::
<parent>
<one/>
<two/>
<?XTC
element added?>
<hundred/>
<?XTC position change
1?>
<three/>
</parent>
(Die 'complete
match'-Markierungen wurden der Einfachheit halber hier weggelassen)
Die Differenzmarkierungen selbst (hier <?XTC element added?>)
zählen natürlich nicht bei der Ermittlung der Positionsänderung,
da sie ja kein inhaltlicher Bestandteil der Datei sind. Andere
(nicht-XTC) Processing Instructions dagegen zählen als normale
Elemente.
Die Differenzmarkierungen werden genauso in der
Visualisierung verwendet.
XTC wurde als generisches Werkzeug konzipiert um möglichst
universell verwendbar zu sein. Wohlgeformtheit der XML-Dateien ist
dabei die einzige Voraussetzung. Für den jeweiligen Anwendungsfall
muss XTC daher konfiguriert werden. Der folgende Text beschreibt die
Konfigurationsmöglichkeiten.
Hinweis: Die folgende
Beschreibung geht davon aus, dass Sie die GUI-Version verwenden.
Falls Sie mit der Kommandozeilenversion arbeiten, müssen Sie die
Konfigurationsdatei xtc_cfg.xml bearbeiten. Diese befindet sich im
aktuellen Verzeichnis oder in Ihrem Home-Verzeichnis. XTC sucht erst
im aktuellen Verzeichnis nach der Konfigurationsdatei und dann (wenn
nichts gefunden wurde) im Home-Verzeichnis des Anwenders.
Starten
Sie XTC (siehe Schnellstart). Der zweite Button in der Werkzeugleiste
(oder Menü Bearbeiten->Konfiguration) öffnet den
Konfigurationsdialog. Dieser besteht aus vier Reitern ('Allgemein',
'Ankerelemente', 'Textvergleich' und 'Differenzmarkierungen').
Die Gruppe 'Diffmodus' definiert die grundlegenden Einstellungen für den Vergleichsvorgang:
Attribute ignorieren: Schließt Attribute vom Vergleichsvorgang aus.
Attributreihenfolge ignorieren: Falls ausgewählt, wird die Reihenfolge der Attribute nicht als Änderungskriterium angesehen.
Mehrfachleerzeichen reduzieren: Reduziert mehrfach hintereinander stehende Leerzeichen zu einem und eliminiert Wagenrücklaufzeichen (CR) und Tabs in Texten. Sinnvoll ist das vor allem auch dann, wenn XML-Editoren o.ä. eigenmächtig Leerzeichen einfügen. Hinweis: Diese Option betrifft den Vergleichsvorgang, die Visualisierung verwendet diese Option immer.
Ergebnis speichern: Falls man nur
an der Visualisierung interessiert ist, kann man hier das Schreiben
der Ergebnisdatei ausschalten.
Hinweis: Bei großen Dateien kann
das Schreiben der Ergebnisdatei in das Dateisystem viel Zeit in
Anspruch nehmen, unter Umständen mehr als der Vergleichsprozess
selbst.
Shiftmodus: Es kann Situationen
während des Vergleichsprozesses geben, in denen eine eindeutige
Elementzuordnung nicht möglich ist. Das ist der Fall, wenn
gleichnamige Elemente des gleichen Elternknotens sowohl ihre
Positionen vertauscht als auch ihre Inhalte geändert haben. Nicht
immer kann dann erkannt werden, ob es sich um ein verändertes
(Position + Inhalt) oder um ein neu hinzugefügtes Element handelt
(Das ist auch 'per Augenschein' nicht in allen Fällen ersichtlich).
Der Shiftmodus ordnet dann gleichnamige Elemente nach dem
'Kürzeste-Entfernung'-Algorithmus einander zu. Das kann in manchen
Fällen zu unerwünschten Ergebnissen führen. Ohne Shiftmodus
werden solche Elemente als 'added' gekennzeichnet (das entsprechende
Element in der Vergleichsdatei wird als 'deleted' gekennzeichnet).
Im Abschnitt 'Ankerelemente' wird ein anderer Lösungsweg für
diese Problematik aufgezeigt.
Inhaltsmodus: Bei aktiviertem Inhaltsmodus versucht das
Programm, die korrekte Zuordnung der Elemente zueinander durch eine
Ähnlichkeitsanalyse der Textinhalte zu erreichen. Text ist dabei
der Inhalt aller Textknoten unterhalb des betreffenden Elements
(ohne Attribute). Die Länge des dadurch ermittelten Textes ist
durch den 'max'-Parameter der Spinbox begrenzt.
Beispiel:
Datei
A:
<para>etwas Text</para>
<para>alter
Abschnitt</para>
<para>viele verschiedene
Neuigkeiten</para>
Datei B:
<para>neuer
Abschnitt</para>
<para>viele und verschiedene
Neuigkeiten</para>
<para>etwas Text</para>
Im
Beispiel gibt es je drei gleichnamige Elemente mit je einem
Textelement. Dabei haben sich in Datei B die Elementreihenfolge und
einTeil der Texte geändert. Der Algorithmus vergleicht nun die
Textinhalte auf Ähnlichkeit und findet so die korrekte
Zuordnung:
<para>neuer Abschnitt</para>
---------------------------- <para>alter
Abschnitt</para>
<para>viele und verschiedene
Neuigkeiten</para> --- <para>viele verschiedene
Neuigkeiten</para>
<para>etwas Text</para>
---------------------------------- <para>etwas
Text</para>
Hinweis: Manchmal führt der Inhaltsmodus
zu einem unerwarteten (d.h. unerwünschten aber der Konfiguration
nach korrekten) Ergebnis. In einem solchen Fall sollte der
Inhaltsmodus deaktiviert werden.
Vorsicht: Bei aktiviertem
Inhaltsmodus kann grundsätzlich jedes Element (sofern es nicht
anders zugeordnet werden kann) vom Inhaltsmodus analysiert werden.
Da die Texte des gesamten Teilbaums (subtree) des Elements
konkateniert werden, muss die resultierende Textlänge begrenzt
werden, um zu lange Rechenzeiten zu vermeiden. Daher gibt die Zahl
in der 'max'-Spinbox die maximale Anzahl der Zeichen an, aus der der
Text für die Analyse durch den Inhaltsmodus bestehen darf.
XML Wurzelelemente legt fest, wie XTC die Wurzelelemente der beiden XML-Dateien behandeln soll (da diese nicht Teil des Vergleichvorgangs sind).
Ignorieren: Mit dieser Option werden die Wurzelelemente nicht verglichen
Namen müssen übereinstimmen: Hier müssen die beiden Wurzelelemente den gleichen Namen haben
Komplette Übereinstimmung: Hier müssen sowohl die beiden Namen als auch die Attribute der Wurzelelemente gleich sein. Die Reihenfolge der Attribute darf allerdings verschieden sein.
Der Abschnitt 'Datei' definiert Eigenschaften der Ergebnisdatei
Dateinamensergänzung: Legt eine Zeichenfolge fest, die in den Namen der Ergebnisdatei einfließt. Die Ergebnisdatei ist ja zunächst eine Kopie von Datei B, muss aber, um ein Überschreiben zu verhindern, einen anderen Namen bekommen. Beispiel: Der Name von Datei B sei 'book2.xml' und die Dateinamenserweiterung sei _xtc, dann heißt die Ergebnisdatei 'book2_xtc.xml'.
Einrückung: Gibt die Anzahl der Zeichen an, um die verschachtelte Elemente in der Ergebnisdatei eingerückt werden (gilt nur für 'Editierbar / lesbar abspeichern').
Editierbar / lesbar abspeichern: Schreibt jedes XML-Element
in eine eigene Zeile, verwendet Einrückung und erzeugt damit eine
(menschen-)lesbare Datei.
'Ohne Whitespace abspeichern': Erzeugt
eine Ergebnisdatei ohne Leerzeichen und Zeilenschaltungen zwischen
den Elementen. Dies erleichtert die automatisierte
Weiterverarbeitung der Datei (z.B. mit XSLT).
'Gelöschte Elemente':
Gelöschte Elemente in die Ergebnisdatei aufnehmen: Elemente
die in Datei A aber nicht in Datei B vorkommen, werden als gelöscht
markiert. Sollen diese auch in der Ergebnisdatei erscheinen, ist die
Checkbox zu aktivieren.
Hinweis: Dies kann unter Umständen (je
nach DTD oder Schema) dazu führen, dass die Ergebnisdatei nicht
mehr valide ist!
Durch die Definition von Ankerelementen kann man dem Programm Kriterien an die Hand geben, um im Fall von Mehrfachänderungen (Position und Inhalt) und Namensgleichheit das korrekte Vergleichselement zu finden. Anker geben dem Programm zusätzliche Information, die aus den XML-Dateien selbst in solcher Form nicht hervorgeht (das 'Meta'-Wissen des Anwenders). Ein Ankerelement ist ein XML-Elementname oder ein Attributname dessen Inhalt konstant bleibt, auch wenn der Rest des Dokuments sich ändert. Der Anker dient so zur Identifizierung einander zugehöriger Elemente in den beiden Dateien.
Beispiel:
Datei
A:
<chapter>
<section>
<sectionmeta>
<sectionid>3</sectionid>
<sectionname>.....</sectionname>
</sectionmeta>
<para>....</para>
...
</section>
Datei
B:
<section>
<sectionmeta>
<sectionid>4</sectionid>
<sectionname>.....</sectionname>
</sectionmeta>
<para>....</para>
...
</section>
<section>
...
</section>
</chapter>
Hier
kann das Element <sectionid> als Anker definiert werden. Wenn
sich nun die Reihenfolge der 'section'-Elemente und ebenso ihr Inhalt
('sectionid' natürlich ausgenommen) ändert, findet der Algorithmus
die richtige Zuordnung der 'section'-Elemente indem die Inhalte ihrer
'sectionid'-Kindelemente verglichen werden. Der Vergleich ist dabei
ein Textvergleich der auch die Textinhalte (ohne Attribute) aller
Kindelemente (den gesamten Teilbaum) miteinschließt.
Die
Ankerdefinition in der Konfiguration sähe in diesem Beispiel so aus:
section sectionmeta/sectionid
(siehe Abbildung))
Der
Pfad zum Anker wird mit / (Schrägstrich) als Trennungszeichen
angegeben. Auch Attribute können als Anker definiert werden:
Beispiel:
<chapter>
<section>
<sectionmeta
id=”3”>
<sectionname>.....</sectionname>
</sectionmeta>
<para>....</para>
...
</section>
<section>
<sectionmeta
id=”4”>
<sectionname>.....</sectionname>
</sectionmeta>
<para>....</para>
...
</section>
<section>
...
</section>
</chapter>
Die
Ankerdefinition wäre hier:
section sectionmeta/@id
'@' zeigt
an, dass der Anker ein Attribut ist.
Um ein neues
Ankerelement zu definieren, öffnet die Schaltfläche 'Neues Element'
eine kleine Dialogbox.
Dort kann der Elementname und der Pfad zum
Anker eingetragen werden.
Für ein XML-Element sollte nur ein Anker definiert werden. Gibt es mehr als einen Anker, wird nur der zuletzt definierte verwendet. Die Ankerfunktionalität ist auch dann wirksam, wenn 'Attribute ignorieren' eingeschaltet ist. Ankerelemente die definiert aber nicht in der XML-Datei zu finden sind, werden ignoriert.
Anker werden definiert, um dem Programm zusätzliche
Identifikationsmerkmale für die Elemente zu geben. Bei Elementen für
welche ein Anker definiert wurde, die aber dennoch nicht durch den
Ankeralgorithmus zugeordnet werden können, kann man zwei Ursachen
unterscheiden:
1. Es gab keine Übereinstimmung des Ankerinhalts
mit dem eines anderen solchen Elements.
2. Der definierte Anker
ist bei diesem Element (aus welchen Gründen auch immer) nicht
vorhanden.
Falls die 'absolut'-Checkbox aktiviert ist, werden
Elemente mit vorhandenem Anker aber ohne Übereinstimmung als 'added'
bzw. 'deleted' gekennzeichnet, während Elemente ohne den definierten
Anker vom Ankeralgorithmus nicht gekennzeichnet werden. Mit
deaktivierter Checkbox bleiben solche Elemente ohne Unterschied in
ihrem vorherigen Zustand.
Ist ein Element als Anker definiert dann ist der Ankerinhalt der Elementinhalt, und zwar der gesamte darunter befindliche Teilbaum, der als Textkonkatenation ausgewertet wird. Bei aktivierter Checkbox werden mehrfach hintereinander stehende Leerzeichen zu einem reduziert und Wagenrücklaufzeichen (CR) und Tabs eliminiert. Sinnvoll ist das vor allem dann, wenn XML-Editoren o.ä. eigenmächtig Leerzeichen einfügen.
Textelemente die sich inhaltlich geändert haben, können noch
einem zusätzlichen Textvergleich unterzogen werden. 'Textvergleich
ein / aus' schaltet die Funktionalität ein oder aus.
Der
Algorithmus teilt den Textinhalt in drei Kategorien ein:
unverändert (wird nicht gekennzeichnet)
hinzugefügt (gekennzeichnet mit der Zeichenfolge von 'Beginn eines hinzugefügten Textes' / 'Ende eines hinzugefügten Textes')
gelöscht (gekennzeichnet mit der Zeichenfolge von 'Beginn eines gelöschten Textes' / 'Ende eines gelöschten Textes')
Einstellungen:
Groß/Kleinschreibung beachten: Wenn aktiviert, wird beim Vergleich Groß- und Kleinschreibung unterschieden (Der allgemeine Vergleich der XML-Elemente unterscheidet Groß- und Kleinschreibung).
Mindestlänge des LCSS: Der Textvergleich basiert im Kern auf
einer Variante des 'Longest common substring'-Algorithmus (LCSS).
Werden zwei Texte verglichen, finden sich oft viele gemeinsame
Teilstrings, die sehr verschiedener Länge sind (im Extremfall nur
ein Zeichen). Der Parameter gibt nun an, wie lang ein gemeinsamer
Teilstring mindestens sein muss, um ein brauchbares Ergebnis zu
erzielen. Beispiel:
a)
Text 1: “xml” Text 2: “xtc”
falls
'Mindestlänge des LCSS' auf '1' (Mindestwert) gesetzt ist, sieht
das Ergebnis so aus:
x[-]ml[/-][+]tc[/+]
“x” ist
der LCSS und ist unverändert. “ml” wurde gelöscht, “tc”
wurde hinzugefügt.
falls 'Mindestlänge des LCSS' auf '2'
gesetzt ist, ist das Ergebnis:
[-]xml[/-][+]xtc[/+]
Kein
LCSS gleich oder größer 2 ist vorhanden, also wird der gefundene
mit Länge 1 ('x') nicht verwendet.
b)
Text 1: “Nudeln”
Text 2: “Salat”
Falls 'Mindestlänge des LCSS' auf '1'
gesetzt ist:
[-]Nude[/-][+]Sa[/+]l[-]n[/-][+]at[/+]
Falls
'Mindestlänge des LCSS' auf '2' (oder mehr) gesetzt ist:
[-]Salat[/-][+]Nudeln[/+]
Für Texte in natürlicher Sprache ist eine Mindestlänge des
LCSS von 3 oder mehr sinnvoll.
Die Markierungen für
hinzugefügten / gelöschten Text können definiert werden,
vorgegebene Werte sind: [+] Beginn eines hinzugefügten Textes [/+]
Ende eines hinzugefügten Textes [-] Beginn eines gelöschten Textes
[/-] Ende eines gelöschten Textes
Hier können eigene Zeichenfolgen für die Differenzmarkierungen festgelegt werden. Zudem kann für jede Markierung definiert werden, ob sie in der Ergebnisdatei Verwendung finden soll oder nicht. Jede Differenzmarkierung kann damit ein- oder ausgeschaltet werden.
XTC ist in C++ unter Verwendung der QT-Bibliothek von Trolltech
(jetzt Nokia) programmiert.
Dabei wurde eine eigens
konzipierte, spezielle XML-API entwickelt, um Unabhängigkeit,
Flexibilität und sehr gute Performance zu ermöglichen.
Unterstützte Betriebssysteme sind derzeit Windows 2000, XP
und Vista (Windows 7 in der Testphase).
Versionen für andere
Betriebssysteme können auf Anfrage bereitgestellt werden.
Verbrauch an Arbeitsspeicher: Da der Speicherbedarf von
vielen verschiedenen Faktoren (benutzte Funktionalitäten,
Änderungsgrad, Struktur der XML-Dateien etc...) abhängt, ist eine
genaue Vorhersage nicht möglich. Eine grobe Abschätzung ergibt sich
aus der Multiplikation der Summe der Dateigrößen der XML-Dateien
mit 8.
Beispiel: Der Vergleich von zwei 20 MB großen XML-Dateien
erfordert ca. 40MB * 8 = 320 MB Speicher.
Copyright ©
2009-2011 Martin Achtziger