secuencias - ¿Cómo puedo obtener el valor de un atributo usando xmllint y XPath?
xpath tutorial español (4)
Quiero obtener el valor del nombre y ponerlo en una variable usando XMLLint
<body>
<value name="abc"></value>
</body>
echo ''cat //body/value/@name'' | xmllint --shell "test.xml"
/ > -------
name="abc"
/ >
Entonces quiero asignar el valor "abc" a la variable $ test
Necesita usar fn:string() , que devolverá el valor de su argumento como xs:string
. En caso de que su argumento sea un atributo, devolverá el valor del atributo como xs:string
.
test=$(xmllint --xpath "string(//body/value/@name)" test.xml)
Prueba esto, no es hermoso, pero funciona :)
Simplemente borro las líneas que contienen >
desde stdout, corté la cadena para obtener la segunda parte después de =
y eliminé "
test=$(echo ''cat //body/value/@name'' | xmllint --shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d /");
echo $test
Recientemente tuve que portar mi solución original más simple usando --xpath a una plataforma que carecía de esta característica, así que también tuve que adoptar la solución "cat". Esto manejará múltiples coincidencias probadas en Ubuntu 12.04 y Solaris 11:
getxml() { # $1 = xml file, $2 = xpath expression
echo "cat $2" | xmllint --shell $1 |/
sed -n ''s/[^/"]*/"/([^/"]*/)/"[^/"]*//1/gp''
}
por ejemplo, extrayendo nombres de instancia de una configuración de dominio glassfish:
$ getxml /tmp/test.xml "//server[@node-ref]/@name"
inst1
inst2
El postprocesamiento de sed simplemente toma todos los valores cotizados que fueron adecuados para mis necesidades (obtener bits de configuración de Glassfish).
Un enfoque con un comando auxiliar awk
que admite múltiples atributos (una versión optimizada del enfoque del ego ):
echo ''cat //*/@name'' | xmllint --shell file | awk -F/" ''NR % 2 == 0 { print $2 }''
El comando awk
:
divide las líneas de salida de
xmllint
en campos por"
chars. (-F/"
)- Tenga en cuenta que
xmllint
normaliza la cita de los valores de los atributos a"..."
en la salida, incluso si la entrada tenía''...''
, por lo que es suficiente para dividir por"
.
- Tenga en cuenta que
solo procesa líneas pares (
NR %2 == 0
), filtrando de ese modo las líneas de separación que elcat
imprime invariablemente.print $2
luego imprima solo el 2do campo, que es el valor de cada atributo sin el adjunto"..."
.
Suponiendo el siguiente XML de muestra en el file
:
<body>
<value name="abc"></value>
<value name="def"></value>
</body>
los rendimientos anteriores:
abc
def