Estrai il valore del nodo dell'attributo tramite XPath


270

Come posso estrarre il valore di un nodo attributo tramite XPath?

Un file XML di esempio è:

<parents name='Parents'>
  <Parent id='1' name='Parent_1'>
    <Children name='Children'>
      <child name='Child_2' id='2'>child2_Parent_1</child>
      <child name='Child_4' id='4'>child4_Parent_1</child>
      <child name='Child_1' id='3'>child1_Parent_1</child>
      <child name='Child_3' id='1'>child3_Parent_1</child>
    </Children>
  </Parent>
  <Parent id='2' name='Parent_2'>
    <Children name='Children'>
      <child name='Child_1' id='8'>child1_parent2</child>
      <child name='Child_2' id='7'>child2_parent2</child>
      <child name='Child_4' id='6'>child4_parent2</child>
      <child name='Child_3' id='5'>child3_parent2</child>
    </Children>
  </Parent>
</parents>

Finora ho questa stringa XPath:

//Parent[@id='1']/Children/child[@name]  

Restituisce solo childelementi, ma vorrei avere il valore namedell'attributo.

Per il mio file XML di esempio, ecco cosa vorrei che fosse l'output:

Child_2
Child_4
Child_1
Child_3

Possibile duplicato dell'attributo Getting usando XPath
tripleee

Risposte:


351
//Parent[@id='1']/Children/child/@name 

Il tuo originale child[@name]indica un elemento childche ha un attributo name. Tu vuoi child/@name.


14
Sono d'accordo, la domanda era come ottenere il valore dell'attributo
Vladtn

5
E se volessi estrarre solo il valore / la descrizione / i dati presenti tra i tag ....
Dinu Duke,

147

Per ottenere solo il valore (senza i nomi degli attributi), utilizzare string():

string(//Parent[@id='1']/Children/child/@name)

La fucntion fn: string () 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.


1
Con xqillaera necessario chiamare xs:string. Mi chiedo perché.
krlmlr,

1
@krlmlr Probabilmente xsè il prefisso dello spazio dei nomi per le funzioni XPath. Quindi non si confondono con gli altri.
acdcjunior,

4
LOL. Questa è l'unica risposta che risponde effettivamente alla domanda. +1
james.garriss,

3
Questo fornirà solo il primo successo in xmllint
crazyduck il

1
Cosa succede se ho un elenco di attributi e ho bisogno dei loro valori? string () sembra restituire solo il primo valore.
damluar,

9

Dovresti usare //Parent[@id='1']/Children/child/data(@name)

Gli attributi non possono essere serializzati, quindi non è possibile restituirli in un risultato dall'aspetto XML. Quello che devi fare è ottenere i dati dall'attributo usando la funzione data ().


9

Come risposto sopra:

//Parent[@id='1']/Children/child/@name 

produrrà solo l' nameattributo dei 4 childnodi appartenenti a quello Parentspecificato dal suo predicato [@id=1]. Sarà quindi necessario modificare il predicato in [@id=2]per ottenere il set di childnodi per il successivo Parent.

Tuttavia, se si ignora del Parenttutto il nodo e si utilizza:

//child/@name

puoi selezionare l' nameattributo di tutti i childnodi in una volta sola.

name="Child_2"
name="Child_4"
name="Child_1"
name="Child_3"
name="Child_1"
name="Child_2"
name="Child_4"
name="Child_3"

6
//Parent/Children[@  Attribute='value']/@Attribute

Questo è il caso che può essere usato laddove l'elemento abbia 2 attributo e possiamo ottenere un attributo con l'aiuto di un altro.


3

@ryenus, è necessario scorrere il risultato. Questo è come lo farei in vbscript;

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.load("kids.xml")

'Remove the id=1 attribute on Parent to return all child names for all Parent nodes
For Each c In xmlDoc.selectNodes ("//Parent[@id='1']/Children/child/@name")
    Wscript.Echo c.text
Next

3

per tutti i file XML con spazio dei nomi utilizzare local-name ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.