web-dev-qa-db-de.com

Linux Bash XMLLINT mit XPATH

Heute lerne ich, wie man xmllint richtig einsetzt. Es scheint nicht gut abgedeckt oder erklärt zu werden. Ich plane, eine einzige Sprachressourcendatei zu verwenden, um mein gesamtes System auszuführen. Ich habe eine Mischung aus Bash-Skripten und PHP-Seiten, die aus dieser Sprachdatei gelesen werden müssen.

Derzeit verwende ich das folgende Format in meiner XML-Datei en.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

   <item id="index.php">
        <label>LABEL</label>
        <value>VALUE</value>
        <description>DESCRIPTION</description>
   </item>
   <item id="config.php">
        <label>LABEL</label>
        <value>VALUE</value>
        <description>DESCRIPTION</description>
   </item>

</resources>

Jetzt muss ich mit einer Bash-Skriptzeile beginnen, die die Datenwerte aus der XML-Datei abrufen soll. Zum Beispiel möchte ich den Wert von DESCRIPTION vom index.php-Element abrufen.

Ich habe benutzt 

xmllint --xpath 'string(//description)' /path/en.xml

für ein anderes Layout, das funktioniert hat, aber jetzt, da ich das Layout meiner XML-Datei ändere, bin ich nicht mehr daran interessiert, wie ich einen bestimmten <item> anvisieren und dann das zugehörige untergeordnete Element im Bash-Skript aufrufen kann.

Kann jemand mit einer xmllint --xpath-Zeile helfen, diesen Wert bitte zu erhalten?

11
RootWannaBe

wie man am besten ein bestimmtes Ziel anvisiert und dann das untergeordnete Element ausführt

Der korrekte XPath-Ausdruck dafür ist:

/resources/item[@id="index.php"]/description/text()

Im Klartext: Beginnen Sie vom Dokumentknoten über das Dokumentelement resources bis zum untergeordneten item, jedoch nur, wenn der Wert des id-Attributs "index.php" ist, bis zum untergeordneten description und rufen Sie den Textwert ab.

Ich verwende xmllint zum Überprüfen von XML-Dokumenten, jedoch niemals für Pfadausdrücke. In einer Bash-Shell (zumindest unter Mac OS) gibt es ein noch einfacheres Werkzeug zum Auswerten von XPath-Ausdrücken, das als "xpath" bezeichnet wird:

$ xpath en.xml '/resources/item[@id="index.php"]/description/text()'

Dann wird folgendes Ergebnis erhalten:

Found 1 nodes:
-- NODE --
DESCRIPTION

Wenn Sie xmllint trotzdem bevorzugen, verwenden Sie es folgendermaßen:

$ xmllint --xpath '/resources/item[@id="index.php"]/description/text()' en.xml > result.txt

Standardmäßig impliziert --xpath--noout, wodurch verhindert wird, dass xmllint irgendetwas ausgibt. Leiten Sie die Ausgabe in eine Datei um.

$ cat result.txt 
DESCRIPTION
12
Mathias Müller

Mein Favorit ist xmlstarlet , weil es mächtiger zu sein scheint als xmllint :

xmlstarlet sel -t -v '/resources/item[@id="index.php"]/description/text()' en.xml
1
typelogic

Ich hatte vor ein paar Minuten das gleiche Problem und sah diesen Beitrag.

Nachdem ich ein bisschen gehackt hatte, fand ich die folgende Lösung, um die Stadt zu extrahieren:

(wget 'http://maps.googleapis.com/maps/api/geocode/xml?latlng=53.244921,-2.479539&sensor=true' -O dummy.xml -o /dev/null;xmllint --format --xpath '/GeocodeResponse/result[type = "postal_town"]/address_component[type = "postal_town"]/short_name/node()'  dummy.xml)

Sie müssen den richtigen X-Pfad angeben, um das gewünschte XML-Tag zu erhalten, und dann nur den Knotenwert zurückgeben.

0
Andreas Cordes