Das Erlernen des Parsens von XML wird oft als komplexes Unterfangen angesehen, muss es aber nicht. XML ist hochgradig und streng strukturiert, also relativ vorhersehbar. Es gibt auch viele Tools, die Ihnen helfen, die Arbeit zu bewältigen.
Eines meiner bevorzugten XML-Dienstprogramme ist XMLStarlet, ein XML-Toolkit für Ihr Terminal. Mit XMLStarlet können Sie XML-Daten validieren, parsen, bearbeiten, formatieren und transformieren. XMLStarlet ist ein relativ minimaler Befehl, aber das Navigieren in XML ist voller Potenzial. In diesem Artikel wird daher gezeigt, wie Sie damit XML-Daten abfragen können.
Installieren
XMLStarlet wird standardmäßig auf CentOS, Fedora und vielen anderen modernen Linux-Distributionen installiert, also öffnen Sie einfach ein Terminal und geben Sie ein xmlstarlet
um darauf zuzugreifen. Wenn XMLStarlet noch nicht installiert ist, bietet Ihr Betriebssystem an, es für Sie zu installieren.
Alternativ können Sie die xmlstarlet
Befehl von Ihrem Paketmanager:
$ sudo dnf install xmlstarlet
Verwenden Sie unter macOS MacPorts oder Homebrew. Verwenden Sie unter Windows Chocolatey.
Sollte alles andere fehlschlagen, können Sie es manuell aus dem Quellcode auf Sourceforge installieren.
Parsen von XML mit XMLStarlet
Es gibt viele Tools, die Ihnen beim Parsen und Transformieren von XML-Daten helfen, einschließlich Softwarebibliotheken, mit denen Sie Ihren eigenen Parser schreiben können, und komplexe Befehle wie fop
und xsltproc
. Manchmal müssen Sie jedoch keine XML-Daten verarbeiten; Sie brauchen nur eine bequeme Möglichkeit, wichtige Daten zu extrahieren, zu aktualisieren oder einfach nur zu validieren. Für spontane XML-Interaktionen verwende ich xmlstarlet
, eine klassische Anwendung im Stil eines “Schweizer Taschenmessers”, die die gängigsten XML-Aufgaben erledigt. Sie können sehen, was es zu bieten hat, indem Sie den Befehl zusammen mit dem ausführen --help
Möglichkeit:
$ xmlstarlet --help
Usage: xmlstarlet [<options>] <command> [<cmd-options>]
where <command> is one of:
ed (or edit) - Edit/Update XML document(s)
sel (or select) - Select data or query XML document(s) (XPATH, etc)
tr (or transform) - Transform XML document(s) using XSLT
val (or validate) - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)
fo (or format) - Format XML document(s)
el (or elements) - Display element structure of XML document
c14n (or canonic) - XML canonicalization
ls (or list) - List directory as XML
[...]
Sie können weitere Hilfe erhalten, indem Sie anhängen --help
bis zum Ende eines dieser Unterbefehle:
$ xmlstarlet sel --help
-Q or --quiet - do not write anything to standard output.
-C or --comp - display generated XSLT
-R or --root - print root element <xsl-select>
-T or --text - output is text (default is XML)
-I or --indent - indent output
[...]
Daten auswählen mit sel
Sie können die Daten in XML mit dem xmlstarlet select
(sel
kurz) Befehl. Hier ist ein einfaches XML-Dokument:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
<os>
<linux>
<distribution>
<name>Fedora</name>
<release>7</release>
<codename>Moonshine</codename>
<spins>
<name>Live</name>
<name>Fedora</name>
<name>Everything</name>
</spins>
</distribution>
<distribution>
<name>Fedora Core</name>
<release>6</release>
<codename>Zod</codename>
<spins></spins>
</distribution>
</linux>
</os>
</xml>
Bei der Suche nach Daten in einer XML-Datei besteht Ihre erste Aufgabe darin, sich auf den Knoten zu konzentrieren, den Sie untersuchen möchten. Wenn Sie den Pfad zum Knoten kennen, geben Sie den vollständigen Pfad mit dem . an --value-of
Möglichkeit. Je früher Sie im Document Object Model (DOM)-Baum mit der Erkundung beginnen, desto mehr Informationen werden angezeigt:
$ xmlstarlet select --template
--value-of /xml/os/linux/distribution
--nl myfile.xml
Fedora
7
Moonshine
Live
Fedora
Everything
Fedora Core
6
Zod
Die --nl
steht für “neue Zeile” und fügt reichlich Leerzeichen ein, um sicherzustellen, dass Ihre Terminal-Eingabeaufforderung eine neue Zeile erhält, nachdem Ihre Ergebnisse eingegeben wurden. Ich habe einen Teil des überschüssigen Platzes in der Beispielausgabe entfernt.
Schränken Sie Ihren Fokus ein, indem Sie weiter in den DOM-Baum hineingehen:
$ xmlstarlet select --template
--value-of /xml/os/linux/distribution/name
--nl myfile.xml
Fedora
Fedora Core
Bedingte Auswahl
Eines der mächtigsten Tools zum Navigieren und Analysieren von XML heißt XPath. Es regelt die bei XML-Suchen verwendete Syntax und ruft Funktionen aus XML-Bibliotheken auf. XMLStarlet versteht XPath-Ausdrücke, sodass Sie Ihre Auswahl mit einer XPath-Funktion bedingt machen können. XPath bietet eine Fülle von Funktionen und ist vom W3C ausführlich dokumentiert, aber ich finde die XPath-Dokumentation von Mozilla prägnanter.
Sie können eckige Klammern als Testfunktion verwenden, um den Inhalt eines Elements mit einem Wert zu vergleichen. Hier ist ein Test für den Wert der <name>
-Element, das die Versionsnummer zurückgibt, die nur einer bestimmten Übereinstimmung zugeordnet ist.
Stellen Sie sich für einen Moment vor, dass die XML-Beispieldatei alle Fedora-Versionen enthält, die mit 1 beginnen. Um alle Versionsnummern anzuzeigen, die mit dem alten Namen “Fedora Core” verbunden sind (das Projekt hat “Core” ab Version 7 weggelassen):
$ xmlstarlet sel --template
--value-of '/xml/os/linux/distribution[name = "Fedora Core"]/release'
--nl myfile.xml
6
5
4
3
2
1
Sie können auch alle Codenamen für diese Veröffentlichungen anzeigen, indem Sie die --value-of
Weg nach /xml/os/linux/distribution[name = "Fedora Core"]/codename
.
Pfade abgleichen und Werte erhalten
Ein Vorteil der Anzeige von XML-Tags als Knoten besteht darin, dass Sie sich den Knoten als Ihr aktuelles “Verzeichnis” mit Daten vorstellen können, sobald Sie den Knoten gefunden haben. Es ist nicht wirklich ein Verzeichnis, zumindest nicht im Sinne des Dateisystems, aber es ist eine Sammlung von Daten, die Sie abfragen können. Um Ihnen dabei zu helfen, Ihr Ziel und die darin enthaltenen Daten voneinander zu trennen, unterscheidet XMLStarlet zwischen dem, was Sie mit den --match
Option und den Wert der gewünschten Daten mit a --value-of
Möglichkeit.
Angenommen, Sie wissen, dass die <spin>
Knoten enthält mehrere Elemente. Das macht es zu Ihrem Ziel. Sobald Sie dort sind, können Sie --value-of
um anzugeben, für welches Element Sie einen Wert wünschen. Um alle Elemente anzuzeigen, verwenden Sie einen Punkt (.
) um Ihren aktuellen Standort darzustellen:
$ xmlstarlet sel --template
--match '/xml/os/linux/distribution/spin'
--value-of '.' --nl myfile.xml
Live
Fedora
Everything
Wie beim Navigieren im DOM können Sie XPath-Ausdrücke verwenden, um den Umfang der zurückgegebenen Daten einzuschränken. In diesem Beispiel verwende ich die last()
Funktion zum Abrufen nur des letzten Elements im spin
Knoten:
$ xmlstarlet select --template
--match '/xml/os/linux/distribution/spin'
--value-of '*[last()]' --nl myfile.xml
Everything
In diesem Beispiel verwende ich die position()
Funktion zum Auswählen eines bestimmten Elements im spin
Knoten:
$ xmlstarlet select --template
--match '/xml/os/linux/distribution/spin'
--value-of '*[position() = 2]' --nl myfile.xml
Fedora
Die --match
und --value-of
Optionen können sich überschneiden, es liegt also an Ihnen, wie Sie sie zusammen verwenden möchten. Diese beiden Ausdrücke bewirken im Fall der Beispiel-XML dasselbe:
$ xmlstarlet select --template
--match '/xml/os/linux/distribution/spin'
--value-of '.'
--nl myfile.xml
Live
Fedora
Everything
$ xmlstarlet select --template
--match '/xml/os/linux/distribution'
--value-of 'spin'
--nl myfile.xml
Live
Fedora
Everything
Sich mit XML vertraut machen
XML kann manchmal übertrieben und unhandlich erscheinen, aber die Tools, die für die Interaktion damit entwickelt wurden, überraschen mich immer wieder. Wenn Sie XML nutzen möchten, könnte XMLStarlet ein guter Einstiegspunkt sein. Wenn Sie das nächste Mal eine XML-Datei öffnen, um strukturierte Daten anzuzeigen, versuchen Sie es mit XMLStarlet und prüfen Sie, ob Sie diese Daten stattdessen abfragen können. Je komfortabler Sie mit XML werden, desto besser kann es Ihnen als robustes und flexibles Datenformat dienen.