J'essaie d'extraire la valeur d'un nœud d'un pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<parent>
<groupId>org.me.labs</groupId>
<artifactId>my-random-project</artifactId>
<version>1.5.0</version>
</parent>
...
</project>
J'ai besoin d'extraire artifactId et la version XML à l'aide d'une commande Shell. J'ai les exigences/observations suivantes:
J'ai essayé ce qui suit:
xpath
fonctionne sur mon Mac, mais n'est pas disponible par défaut sur les machines RHEL. De même pour xmllint --xpath
, qui, je suppose, n'est disponible que sur les versions ultérieures de xmllint
, que je n'ai pas et que je ne peux pas appliquer.xmllint --pattern
semblait prometteur, mais je n'arrive pas à obtenir une sortie sur xmllint --pattern '//project/parent/version' pom.xml
(affiche tout le code XML) ou xmllint --stream --pattern '//project/parent/version' pom.xml
(pas de sortie).Je me rends compte que c’est une question courante ici sur les SO, mais les points ci-dessus expliquent pourquoi je ne peux pas utiliser ces réponses. TIA pour votre aide.
J'ai réussi à le résoudre pour le moment avec ce script plutôt involontaire en utilisant xmllint --Shell
.
echo "cat //project/parent/version" | xmllint --Shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'
Si les noeuds XML ont des attributs d'espace de noms comme ceux de mon pom.xml, les choses deviennent plus lourdes, en extrayant le noeud par son nom:
echo "cat //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" | xmllint --Shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'
J'espère que ça aide. Si quelqu'un peut simplement ces expressions, je vous en serais reconnaissant.
--format
est utilisé uniquement pour formater (indenter, etc.) le document. Vous pouvez le faire en utilisant --xpath
(testé dans Ubuntu, libxml v20900):
$ xmllint --xpath "//project/parent/version/text()" pom.xml
1.5.0
Je suis venu ici à la recherche d'un bon moyen de gratter une valeur d'un site Web. L'exemple suivant peut être utile à ceux (contrairement à l'affiche) qui ont une version de xmllint qui prend en charge --xpath.
J'avais besoin d'extraire la version stable la plus récente du fichier .debfile d'elasticsearch et de l'installer. Les responsables ont utilement placé le numéro de version dans une plage avec la classe "version".
version=`curl -s http://www.elasticsearch.org/download/ |\
xmllint --html --xpath '//span[@class="version"]/text()'\
2>/dev/null - `;
Ce qui se passe:
Nous utilisons l'option curl -s (silencieuse).
curl -s http://www.elasticsearch.org/download/
Nous utilisons les commutateurs xmllint --html et --xpath. Les arguments xpath (entre guillemets simples)
'//span[@class="version"]/text()'
... recherche un noeud <span> avec l'attribut de classe (@class) "version" et extrait la valeur de texte (/ text ()).
Puisque xmllint est (surprise!) Un linter, il gémira à propos des déchets inévitables dans votre flux HTML. Nous dirigeons le stderr vers/dev/null de la manière habituelle:
2>/dev/null
Enfin, notez le "-" à la fin de la commande xmllint, qui indique à xmllint que le flux provient de stdin.
L'utilisation de la fonction text()
XPath vous donne la valeur de l'élément, sans avoir à supprimer les balises XML
echo "cat //project/parent/version/text()" | xmllint --Shell pom.xml
Avec les POM, vous pouvez créer des problèmes d'espaces de nommage empêchant xmllint de fonctionner comme prévu. This articles vous indique une solution de rechange très efficace (regardez le paragraphe sed).
Tu peux essayer
xmllint --xpath "/*[name()='project']/*[name()='groupId']/text()" pom.xml