web-dev-qa-db-fra.com

Comment puis-je obtenir la valeur d'un attribut à l'aide de xmllint et XPath?

Je veux obtenir la valeur du nom et la mettre dans une variable en utilisant XMLLint

<body>
<value name="abc"></value>
</body>

echo 'cat //body/value/@name' | xmllint --Shell "test.xml"

/ >  -------
 name="abc"
/ > 

Je veux donc affecter la valeur "abc" à la variable $ test

30
Tran Ngu Dang

Vous devez utiliser fn: string () , qui renverra la valeur de son argument sous la forme xs:string. Dans le cas où son argument est un attribut, il retournera donc la valeur de l'attribut comme xs:string.

test=$(xmllint --xpath "string(//body/value/@name)" test.xml)
28
h0li0

Essayez ça, ce n'est pas beau mais ça marche :)

Je supprime simplement les lignes contenant > de stdout, coupez la chaîne pour obtenir la deuxième partie après le =, et supprimez "

test=$(echo 'cat //body/value/@name' | xmllint --Shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
echo $test
8
ego

Une approche avec une commande d'assistance awk qui prend en charge plusieurs attributs (une version simplifiée de approche de l'ego ):

echo 'cat //*/@name' | xmllint --Shell file | awk -F\" 'NR % 2 == 0 { print $2 }'

La commande awk:

  • divise les lignes de sortie de xmllint en champs par " caractères. (-F\")

    • Notez que xmllint normalise la citation autour des valeurs d'attribut à "..." en sortie, même si l'entrée avait '...', il suffit donc de diviser par ".
  • ne traite que les lignes paires (NR %2 == 0), filtrant ainsi les lignes de séparation que cat imprime invariablement.

  • print $2 imprime ensuite uniquement le 2ème champ, qui est la valeur de chaque attribut sans le "...".

En supposant que l'exemple de XML suivant dans file:

<body>
  <value name="abc"></value>
  <value name="def"></value>
</body>

les rendements ci-dessus:

abc
def
5
mklement0

J'ai récemment dû porter ma solution plus simple d'origine en utilisant --xpath sur une plate-forme ne disposant pas de cette fonctionnalité, j'ai donc dû adopter la solution "cat" également. Cela gérera plusieurs correspondances, testées sur Ubuntu 12.04 et Solaris 11:

getxml() { # $1 = xml file, $2 = xpath expression
    echo "cat $2" | xmllint --Shell $1 |\
    sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1/gp'
}

par exemple. extraire les noms d'instance d'une configuration de domaine glassfish:

$ getxml /tmp/test.xml "//server[@node-ref]/@name"
inst1
inst2

Le post-traitement sed prend juste toutes les valeurs citées qui étaient adéquates pour mes besoins (obtenir des morceaux de config de glassfish).

4
steve.sims