2012-01-26 10 views
6

Tengo un pom.xml típico, y quiero imprimir groupId, artifactId y versión, separados por dos puntos. Creo que XMLStarlet es la herramienta adecuada para eso. Intenté varias maneras, pero siempre tengo una línea vacía.XMLStarlet no selecciona nada

xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml 

Resultados previstos:

org.something.apps:app-acct:5.4 

salida real: línea vacía

Incluso si se intenta imprimir sólo el groupId no consigo nada:

Estoy seguro de que la herramienta ve los elementos porque puedo enumerarlos sin problema:

xml el pom.xml 

imprime el siguiente (correctamente):

project 
project/modelVersion 
project/parent 
project/parent/groupId 
project/parent/artifactId 
project/parent/version 
project/groupId 
project/artifactId 
project/version 
project/packaging 

¿Qué pasa?

Aquí es la versión reducida de pom.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/maven-v4_0_0.xsd"> 

    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>org.something</groupId> 
     <artifactId>base</artifactId> 
     <version>1.16</version> 
    </parent> 

    <groupId>org.something.apps</groupId> 
    <artifactId>app-acct</artifactId> 
    <version>5.4</version> 
    <packaging>war</packaging> 

</project> 

Respuesta

28

Desafortunadamente, XMLStarlet es muy exigente con el nombre por defecto. Si el documento tiene que declaró (xmlns=), usted tiene que declarar por XMLStarlet también, y anteponer los elementos con el nombre que ha elegido (ver here):

xml sel -N = http://maven.apache.org/POM/4.0.0 mi -t - m mi: mi proyecto -v: groupId -o: -v mi: -o artifactId: -v mi: versión pom.xml

al ejecutar el comando anterior muestra el resultado esperado:

org.something.apps:app-acct:5.4 

Sin embargo, si el documento NO tiene el el espacio de nombres de falla declarado (o el espacio de nombres tiene una URL ligeramente diferente), el comando anterior NO funcionará, que es un PITA real. Una solución más universal es eliminar la declaración predeterminada del espacio de nombres antes de seleccionar los elementos. A partir de XMLStarlet 1.3.1, al convertir XML a formato PYX y viceversa, se eliminan las declaraciones del espacio de nombres:

xml pyx pom.xml | xml p2x | sel xml -t -v -m proyecto groupId -o: -v artifactId -o: -v versión 2> nul

ACTUALIZACIÓN (12/02/2014): como de XMLStarlet 1.4.2 Pyx < -> La conversión XML es fija (no elimina las declaraciones del espacio de nombres), por lo que el comando anterior NO funcionará (gracias a Peter Gluck por la sugerencia). Use en su lugar el siguiente comando:

xml pyx pom.xml | grep -v^A | xml p2x | sel xml -t -v -m proyecto groupId -o: -v artifactId -o: versión -v

Nota: el grep anterior elimina todos los atributos del documento, no sólo las declaraciones de espacio de nombres. Para este caso específico (seleccionando valores de elementos de pom.xml, donde no se espera que los elementos con espacios de nombres no predeterminados) Esta bien, pero para un XML en general se eliminaría simplemente la declaración (s) espacio de nombres predeterminado y nada más:

xml pyx pom.xml | grep -v "^ Axmlns" | xml p2x | xml sel -t proyecto -m -v groupId -o: -v artifactId -o: versión -v


Nota (obsoleto): la redirección de error (2>nul) es necesaria para ocultar la queja sobre la (ahora) desconocido xsi espacio de nombres:

-: 1,28: Espacio de nombres xsi prefijo para schemaLocation el proyecto no se define

Otra manera de deshacerse de la queja es eliminar la schemaLocation en tributo (en realidad, este comando elimina todos los atributos del documento PYX, no solo xsi: schemaLocation):

xml pyx pom.xml | grep -v^A | xml p2x | xml sel -t proyecto -m -v groupId -o: -v artifactId -o: versión -v

+0

Su comentario sobre el prefijo de elementos con el (alias para?) El espacio de nombres declarado es la diferencia crucial para los documentos vinculados. – chernevik

5

El XML> PYX - trick> XML no funcionó para mí (usando XMLStarlet versión 1.4.2) . Sin embargo, el XMLStarlet documentation contiene este práctico mando sed que elimina declaraciones de espacios de un documento XML:

sed -e 's/ xmlns.*=".*"//g' 

que funcionó. Para la pregunta original, la sintaxis sería:

cat pom.xml | sed -e 's/ xmlns.*=".*"//g' | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version 
+0

Gracias por la actualización sobre el cambio en PYX -> conversión XML. Esto significa que la última línea de comando (con grep -v^A) es ahora la preferida. Sin embargo, sed/grep/awk, etc. NO debe usarse en XML general: funciona para ese ejemplo simple específico en la documentación (y también para mi ejemplo simplificado), pero podría crear fácilmente un documento XML no válido. Ejemplo: ejecutar ese sed "práctico" en esto: a = "X"; devolver a; dará como resultado esto: uk4sx