2015-02-12 15 views
5

Sto tentando di elaborare un numero elevato di file xml (maven poms) utilizzando xmllint --xpath. Con alcuni tentativi ed errori ho capito che non funziona come previsto a causa della dichiarazione di spazio dei nomi predefinito male in questi file, che è la seguente:Forza xmllint per ignorare la defultazione errata xmlns

<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"> 

Un semplice comando non riesce nel modo seguente:

$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml) 
XPath set is empty 

Se mi libero dei xmlns attributo, sostituendo l'elemento principale come segue:

<project 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"> 

il comando precedente dà i risultati attesi:

0.123,51641 milioni
$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml) 
4.0.0 

La modifica di centinaia di file pom non è un'opzione, soprattutto perché lo stesso maven non si lamenta.

Esiste un modo per lo xmllint di elaborare il file con il numero errato xmlns?

UPDATE

Grazie a Damien sono stato in grado di fare qualche progresso:

$ (echo setns x=http://maven.apache.org/POM/4.0.0; echo 'xpath /x:project/x:modelVersion/text()';) | xmllint --shell pom.xml 
/> setns x=http://maven.apache.org/POM/4.0.0 
/> xpath /x:project/x:modelVersion/text() 
Object is a Node Set : 
Set contains 1 nodes: 
1 TEXT 
    content=4.0.0 

Ma questo non abbastanza fare quello che mi serve. Le mie domande di follow-up sono le seguenti:

  1. C'è un modo per stampare solo il testo? Vorrei che l'output contenga 4.0.0 nell'esempio precedente

  2. Sembra che l'output venga troncato dopo circa 30 caratteri. È possibile ottenere l'output completo? Questo non accade con xmllint --xpath

+0

Non è uno spazio dei nomi * errato *. È un namespace.Ciò che in genere significa è che devi anche usare lo spazio dei nomi nella tua query XPath, ma non ho familiarità con le specifiche dello strumento che stai usando per dirti con esattezza. –

+0

Non va bene perché fa fallire xmllint :) Anche perché la schmealocation è sbagliata. –

+1

Un po 'di semplice ricerca su 'xmllint namespace' ha trovato [questa domanda] (http://stackoverflow.com/questions/8264134/xmllint-failing-to-properly-query-with-xpath) che sembra mostrare due possibili modi di lavorare * con * lo spazio dei nomi. E lo schemalocation sembra essere corretto. Dice che lo schema identificato dall'URI 'http: // maven.apache.org/POM/4.0.0' può trovarsi all'URL' http: // maven.apache.org/maven-v4_0_0.xsd' e sembrerebbe essere vero –

risposta

5

striscia lo spazio dei nomi con sed

dato in 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> 
</project> 

questo:

cat pom.xml | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' - 

restituisce questo:

<modelVersion>4.0.0</modelVersion> 

se avete la formattazione funky (come, xmlns attributi sono sulle proprie linee), eseguirlo tramite il formattatore prima:

cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' - 
+0

Grazie, ho appena visto questo. Ho gli attributi xmlns distribuiti su più righe, '--format' potrebbe essere una buona soluzione per questo –

1
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml 

Non è vero abbastanza, ma evitare di formattazione assunzioni e/o riformattazione del file pom.xml di input.

Se è necessario rimuovere il "-SNAPSHOT" per qualche motivo, reindirizzare il risultato di sopra tramite | sed -e "s|-SNAPSHOT||".

Problemi correlati