validar - xmllint xpath
Conjunto de comandos de shell nativo para extraer el valor de nodo de XML (6)
Estoy intentando extraer el valor de un nodo de 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>
Necesito extraer el artifactId y la versión del XML usando un comando de shell. Tengo los siguientes requisitos / observaciones:
- El script de shell se realizará dentro de un archivo de ensamblaje de compilación que usamos en el trabajo, por lo que cuanto más pequeño sea el script, mejor.
- Dado que se usará en varios sistemas (generalmente RHEL5), estoy buscando algo que pueda ejecutarse de forma nativa en imágenes predeterminadas.
- Etiquetas como pueden aparecer en otras partes del pom, por lo que no puedo simplemente aceptar esas etiquetas.
He probado lo siguiente:
-
xpath
funciona en mi Mac, pero no está disponible de forma predeterminada en las máquinas RHEL. De manera similar, paraxmllint --xpath
, que creo que solo está disponible en versiones posteriores dexmllint
, que no tengo y no puedo hacer cumplir. -
xmllint --pattern
parecía prometedor, pero parece que no puedo obtener una salida dexmllint --pattern ''//project/parent/version'' pom.xml
(imprime XML completo) oxmllint --stream --pattern ''//project/parent/version'' pom.xml
(sin salida).
Me doy cuenta de que esta es una pregunta común aquí en SO, pero los puntos anteriores son por qué no puedo usar esas respuestas. TIA por tu ayuda.
Con los POM, puede generar problemas con los espacios de nombres que impiden que xmllint funcione como se espera. Este artículo le señala una solución alternativa y muy buena (vea el párrafo sed ).
El uso de la función text()
XPath le da el valor del elemento, en lugar de tener que eliminar las etiquetas XML:
echo "cat //project/parent/version/text()" | xmllint --shell pom.xml
Me las arreglé para resolverlo por el momento con esta secuencia de comandos bastante inoportuna utilizando xmllint --shell
.
echo "cat //project/parent/version" | xmllint --shell pom.xml | sed ''/^// >/d'' | sed ''s/<[^>]*.//g''
Si los nodos XML tienen atributos de espacio de nombres como los que tenía mi pom.xml, las cosas se ponen más pesadas, básicamente extrayendo el nodo por su nombre:
echo "cat //*[local-name()=''project'']/*[local-name()=''parent'']/*[local-name()=''version'']" | xmllint --shell pom.xml | sed ''/^// >/d'' | sed ''s/<[^>]*.//g''
Espero eso ayude. Si alguien puede simplemente estas expresiones, estaría agradecido.
Puedes probar
xmllint --xpath "/*[name()=''project'']/*[name()=''groupId'']/text()" pom.xml
Vine aquí en busca de una buena manera de obtener un valor de un sitio web. El siguiente ejemplo puede ser útil para aquellos (a diferencia del póster) que tienen una versión de xmllint que admite --xpath.
Necesitaba extraer la versión estable más reciente del archivo .debfile de elasticsearch e instalarlo. Los mantenedores han puesto de manera útil el número de versión en un intervalo con la clase "versión".
version=`curl -s http://www.elasticsearch.org/download/ |/
xmllint --html --xpath ''//span[@class="version"]/text()''/
2>/dev/null - `;
Lo que pasa
Usamos la opción curl -s (silenciosa).
curl -s http://www.elasticsearch.org/download/
Usamos los conmutadores xmllint --html y --xpath. Los argumentos xpath (en comillas simples)
''//span[@class="version"]/text()''
... busca un nodo <span> con el atributo de clase (@class) "versión", y extrae el valor de texto (/ text ()).
Ya que xmllint es (¡una sorpresa!) Una máscara, retumbará sobre la inevitable basura en su flujo html. Dirigimos el stderr a / dev / null de la forma habitual:
2>/dev/null
Finalmente, tenga en cuenta el "-" al final del comando xmllint, que le dice a xmllint que el flujo proviene de stdin.
--format
se usa solo para formatear (sangrar, etc.) el documento. Puede hacerlo utilizando --xpath
(probado en Ubuntu, libxml v20900):
$ xmllint --xpath "//project/parent/version/text()" pom.xml
1.5.0