Analyzovat XML pro získání hodnoty uzlu v bash skriptu?

Chtěl bych vědět, jak mohu získat hodnotu uzlu pomocí následujících cest:

config/global/resources/default_setup/connection/host config/global/resources/default_setup/connection/username config/global/resources/default_setup/connection/password config/global/resources/default_setup/connection/dbname 

z následujícího XML:

<?xml version="1.0"?> <config> <global> <install> <date><![CDATA[Tue, 11 Dec 2012 12:31:25 +0000]]></date> </install> <crypt> <key><![CDATA[70e75d7969b900b696785f2f81ecb430]]></key> </crypt> <disable_local_modules>false</disable_local_modules> <resources> <db> <table_prefix><![CDATA[]]></table_prefix> </db> <default_setup> <connection> <host><![CDATA[localhost]]></host> <username><![CDATA[root]]></username> <password><![CDATA[pass123]]></password> <dbname><![CDATA[testdb]]></dbname> <initStatements><![CDATA[SET NAMES utf8]]></initStatements> <model><![CDATA[mysql4]]></model> <type><![CDATA[pdo_mysql]]></type> <pdoType><![CDATA[]]></pdoType> <active>1</active> </connection> </default_setup> </resources> <session_save><![CDATA[files]]></session_save> </global> <admin> <routers> <adminhtml> <args> <frontName><![CDATA[admin]]></frontName> </args> </adminhtml> </routers> </admin> </config> 

Také chci přiřadit tuto hodnotu proměnné pro další použití. Dejte mi vědět svůj nápad.

Komentáře

Odpověď

Použití bash a xmllint (jak je uvedeno ve značkách):

xmllint --version # xmllint: using libxml version 20703 # Note: Newer versions of libxml / xmllint have a --xpath option which # makes it possible to use xpath expressions directly as arguments. # --xpath also enables precise output in contrast to the --shell & sed approaches below. #xmllint --help 2>&1 | grep -i "xpath" 

{ # the given XML is in file.xml host="$(echo "cat /config/global/resources/default_setup/connection/host/text()" | xmllint --nocdata --shell file.xml | sed "1d;$d")" username="$(echo "cat /config/global/resources/default_setup/connection/username/text()" | xmllint --nocdata --shell file.xml | sed "1d;$d")" password="$(echo "cat /config/global/resources/default_setup/connection/password/text()" | xmllint --nocdata --shell file.xml | sed "1d;$d")" dbname="$(echo "cat /config/global/resources/default_setup/connection/dbname/text()" | xmllint --nocdata --shell file.xml | sed "1d;$d")" printf "%s\n" "host: $host" "username: $username" "password: $password" "dbname: $dbname" } # output # host: localhost # username: root # password: pass123 # dbname: testdb 

V případě, že existuje pouze řetězec XML a je třeba se vyhnout použití dočasného souboru, jsou způsobem použití deskriptory souborů.

(který je zde uveden/dev/fd/3jako argument souboru):

set +H { xmlstr="<?xml version="1.0"?> <config> <global> <install> <date><![CDATA[Tue, 11 Dec 2012 12:31:25 +0000]]></date> </install> <crypt> <key><![CDATA[70e75d7969b900b696785f2f81ecb430]]></key> </crypt> <disable_local_modules>false</disable_local_modules> <resources> <db> <table_prefix><![CDATA[]]></table_prefix> </db> <default_setup> <connection> <host><![CDATA[localhost]]></host> <username><![CDATA[root]]></username> <password><![CDATA[pass123]]></password> <dbname><![CDATA[testdb]]></dbname> <initStatements><![CDATA[SET NAMES utf8]]></initStatements> <model><![CDATA[mysql4]]></model> <type><![CDATA[pdo_mysql]]></type> <pdoType><![CDATA[]]></pdoType> <active>1</active> </connection> </default_setup> </resources> <session_save><![CDATA[files]]></session_save> </global> <admin> <routers> <adminhtml> <args> <frontName><![CDATA[admin]]></frontName> </args> </adminhtml> </routers> </admin> </config> " # exec issue #exec 3<&- 3<<<"$xmlstr" #exec 3<&- 3< <(printf "%s" "$xmlstr") exec 3<&- 3<<EOF $(printf "%s" "$xmlstr") EOF { read -r host; read -r username; read -r password; read -r dbname; } < <( echo "cat /config/global/resources/default_setup/connection/*[self::host or self::username or self::password or self::dbname]/text()" | xmllint --nocdata --shell /dev/fd/3 | sed -e "1d;$d" -e "/^ *--* *$/d" ) printf "%s\n" "host: $host" "username: $username" "password: $password" "dbname: $dbname" exec 3<&- } set -H # output # host: localhost # username: root # password: pass123 # dbname: testdb 

Komentáře

Odpověď

Ačkoli již existuje spousta odpovědí, ozvu se xml2.

$ xml2 < test.xml /config/global/install/date=Tue, 11 Dec 2012 12:31:25 +0000 /config/global/crypt/key=70e75d7969b900b696785f2f81ecb430 /config/global/disable_local_modules=false /config/global/resources/db/table_prefix /config/global/resources/default_setup/connection/host=localhost /config/global/resources/default_setup/connection/username=root /config/global/resources/default_setup/connection/password=pass123 /config/global/resources/default_setup/connection/dbname=testdb /config/global/resources/default_setup/connection/initStatements=SET NAMES utf8 /config/global/resources/default_setup/connection/model=mysql4 /config/global/resources/default_setup/connection/type=pdo_mysql /config/global/resources/default_setup/connection/pdoType /config/global/resources/default_setup/connection/active=1 /config/global/session_save=files /config/admin/routers/adminhtml/args/frontName=admin 

S trochou magie je můžete dokonce přímo nastavit jako proměnné:

odpověď

Použití xmllint a možnost –xpath je to velmi snadné. Můžete jednoduše udělat toto:

XML_FILE=/path/to/file.xml HOST=$(xmllint --xpath "string(/config/global/resources/default_setup/connection/host)" $XML_FILE USERNAME=$(xmllint --xpath "string(/config/global/resources/default_setup/connection/username)" $XML_FILE PASSWORD=$(xmllint --xpath "string(/config/global/resources/default_setup/connection/password)" $XML_FILE DBNAME=$(xmllint --xpath "string(/config/global/resources/default_setup/connection/dbname)" $XML_FILE 

Pokud se potřebujete dostat k atributu prvku, je to také snadné pomocí XPath. Představte si, že máte soubor:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <addon name="Turn Off" version="0.10.0" provider-name="Dag Wieërs"> ..snip.. </addon> 

Potřebné příkazy prostředí budou:

VERSION=$(xmllint --xpath "string(/addon/@version)" $ADDON_XML) AUTHOR=$(xmllint --xpath "string(/addon/@provider-name)" $ADDON_XML) 

Odpověď

Při spuštění proti vašim testovacím datům funguje následující:

{ read -r host; read -r username; read -r password; read -r dbname; } \ < <(xmlstarlet sel -t -m /config/global/resources/default_setup/connection \ -v ./host -n \ -v ./username -n \ -v ./password -n \ -v ./dbname -n) 

Tím se obsah umístí do proměnných host, username, password a dbname.

Komentáře

  • xmlstarlet: příkaz nebyl nalezen, takže tento příkaz pro mě není užitečný: (
  • @MagePsycho bash nemá žádnou vestavěnou podporu pro analýzu XML. Buď potřebujete mít nástroj, který ano (xmlstarlet, xsltproc, moderní Python atd.) , nebo můžete ‚ správně analyzovat XML.
  • @CharlesDuffy existuje způsob, jak získat hodnotu, může být pomocí regexového vzoru, nebo jinak?
  • @MagePsycho stačí nainstalovat xmlstarlet. V každém případě byste nikdy neměli používat regul ar výrazy k analýze (X) HTML .
  • @MagePsycho Chystal jsem se zveřejnit stejný odkaz, který již terdon udělal. Ve zkratce: Ne.

Odpověď

Čistý bash funkce, jen pro nešťastný případ, kdy vám není dovoleno instalovat nic vhodného. U složitějších XML to může a pravděpodobně selže:

 function xmlpath() { local expr="${1//\// }" local path=() local chunk tag data while IFS="" read -r -d "<" chunk; do IFS=">" read -r tag data <<< "$chunk" case "$tag" in "?"*) ;; "!–-"*) ;; "![CDATA["*) data="${tag:8:${#tag}-10}" ;; ?*"/") ;; "/"?*) unset path[${#path[@]}-1] ;; ?*) path+=("$tag") ;; esac [[ "${path[@]}" == "$expr" ]] && echo "$data" done }  

Použití :

bash-4.1$ xmlpath "config/global/resources/default_setup/connection/host" < MagePsycho.xml localhost 

Známé problémy:

  • pomalý
  • vyhledává pouze podle názvů značek
  • žádné dekódování entit znaků

odpověď

Tento komentář používá pouze příkazy a metody sh / bash! /test.xml je váš soubor typu XML na první otázku …

#!/bin/sh cat /test.xml | while read line;do [ "$(echo "$line" | grep "<host>")" ]&& echo "host: $(echo $line | cut -f3 -d"[" | cut -f1 -d"]")" [ "$(echo "$line" | grep "<username>")" ]&& echo "username: $(echo $line | cut -f3 -d"[" | cut -f1 -d"]")" [ "$(echo "$line" | grep "<password>")" ]&& echo "password: $(echo $line | cut -f3 -d"[" | cut -f1 -d"]")" [ "$(echo "$line" | grep "<dbname")" ]&& echo "dbname: $(echo $line | cut -f3 -d"[" | cut -f1 -d"]")" done 

výstup:

host: localhost username: root password: pass123 dbname: testdb 

pokud chcete tyto hodnoty zapsat do souboru, použijte tuto metodu:

#!/bin/sh cat /test.xml | while read line;do [ "$(echo "$line" | grep "<host>")" ]&& echo "$line" | cut -f3 -d"[" | cut -f1 -d"]" > /config/global/resources/default_setup/connection/host [ "$(echo "$line" | grep "<username>")" ]&& echo "$line" | cut -f3 -d"[" | cut -f1 -d"]" > /config/global/resources/default_setup/connection/username [ "$(echo "$line" | grep "<password>")" ]&& echo "$line" | cut -f3 -d"[" | cut -f1 -d"]" > /config/global/resources/default_setup/connection/password [ "$(echo "$line" | grep "<dbname")" ]&& echo "$line" | cut -f3 -d"[" | cut -f1 -d"]" > /config/global/resources/default_setup/connection/dbname done 

tato metoda přepíše vaše místní soubory, které používají pouze k získání hodnot (vaše data budou z výstupních souborů ztraceny)

Odpověď

Můžete použít kódování rozhraní příkazového řádku php v bash skriptech ke zpracování několika složitých skripty, které se skutečně rozprostírají na více řádcích kódování. Nejprve zkuste vytvořit své řešení pomocí skriptů PHP a poté později předejte parametry pomocí režimu CLI. Získáte tak kontrolu nad vynikajícím využitím XML analyzátorů.

Zdá se, že prostředí můžete používat v klientském režimu pomocí přístupu ssh / shell.

php -f yourxmlparser.php 

Nyní proveďte všechny věci ve vašem php souboru. Využijte parametry příkazového řádku, které může trvat.

Tyto návratové hodnoty můžete dokonce přiřadit prostředí prostředí Shell, abyste mohli pokračovat ve zbytku svých skriptů prostředí.

A druhým způsobem je použití | možnost grep, aby odpovídala vaší požadované hodnotě v souboru XML, pokud jste si docela jisti strukturou vašeho souboru XML, která se časem nemění.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *