2012-07-23 15 views

risposta

8

Prova questa, non è bello, ma funziona :)

ho appena cancellare le linee che contengono > da stdout, tagliato la corda per ottenere la seconda parte dopo il = ed eliminare "

test=$(echo 'cat //body/value/@name' | xmllint --shell "test.xml" | grep -v ">" | cut -f 2 -d "=" | tr -d \"); 
echo $test 
+2

Usa xmllint in modo da non dover usare RE per analizzare XML. Renditi conto che devi usare i RE per analizzare l'output di xmllint. – badp

+0

perché stampa ------- prima del valore dell'attributo nome? come rimuoverlo? –

23

È necessario utilizzare fn:string(), che restituirà il valore del suo argomento come xs:string. Nel caso in cui il suo argomento sia un attributo, restituirà quindi il valore dell'attributo come xs:string.

test=$(xmllint --xpath "string(//body/value/@name)" test.xml) 
+8

sfortunatamente --xpath non è supportato su molte installazioni – Fergie

+0

http://stackoverflow.com/questions/11975862/xmllint-unknown-option-xpath – Dejan

+5

Questo mostra solo il valore per un singolo elemento, è possibile ottenere più corrispondenze ? –

4

Recentemente ho dovuto porto la mia soluzione originale più semplice utilizzando --xpath ad una piattaforma manca questa caratteristica, quindi abbiamo dovuto adottare la soluzione "cat" troppo. Questo gestirà più corrispondenze, testato su Ubuntu 12.04 e Solaris 11:

getxml() { # $1 = xml file, $2 = xpath expression 
    echo "cat $2" | xmllint --shell $1 |\ 
    sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1/gp' 
} 

ad es. l'estrazione di nomi di istanza da una configurazione di dominio GlassFish:

$ getxml /tmp/test.xml "//server[@node-ref]/@name" 
inst1 
inst2 

Il post-processing sed appena afferra tutti i valori indicati che era adeguata per le mie esigenze (ottenendo bit di configurazione pesci vetro).

3

Un approccio con un aiutante awk comando che supporta più attributi (una versione semplificata di ego's approach):

echo 'cat //*/@name' | xmllint --shell file | awk -F\" 'NR % 2 == 0 { print $2 }' 

Il comando awk:

  • divide xmllint d' uscita linee nei campi da " caratteri. (-F\")

    • noti che xmllint normalizza citare intorno a valori di attributo "..." sull'uscita, anche se l'ingresso era '...', quindi è sufficiente raggruppati per ".
  • elabora solo linee di numero pari (NR %2 == 0), filtrando in tal modo le linee di separazione che cat invariabilmente stampe.

  • print $2 quindi stampa solo campo 2a, che è il valore di ciascun attributo senza racchiude "...".

Assumendo il seguente codice XML di esempio in file:

<body> 
    <value name="abc"></value> 
    <value name="def"></value> 
</body> 

i rendimenti superiori:

abc 
def 
+0

funziona perfettamente per me, grazie. Hai anche un bel modo di assegnare i valori a diverse variabili. Come VAR_1 = $ (echo 'cat // */@ nome' | xmllint --shell file | awk -F \ "'NR% 2 == 0 {print $ 2}')? – dieHellste

+0

@dieHellste: puoi' leggere' le righe di output in variabili (in un ciclo 'while' o, in Bash, in un array con' read -a'); se hai bisogno di ulteriori indicazioni, fai una nuova domanda. – mklement0

Problemi correlati