Extraer el valor del nodo de atributo a través de XPath

270

¿Cómo puedo extraer el valor de un nodo de atributo a través de XPath?

Un archivo XML de muestra es:

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

Hasta ahora tengo esta cadena XPath:

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

Solo devuelve childelementos, pero me gustaría tener el valor del nameatributo.

Para mi archivo XML de muestra, esto es lo que me gustaría que sea la salida:

Child_2
Child_4
Child_1
Child_3
Rehman
fuente
Posible duplicado del atributo Obteniendo usando XPath
tripleee

Respuestas:

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

Su original child[@name]significa un elemento childque tiene un atributo name. Que desea child/@name.

morador
fuente
14
Estoy de acuerdo, la pregunta era cómo obtener el valor del atributo
Vladtn
55
¿Qué pasa si me gustaría extraer sólo el valor / Descripción / datos presentes entre las etiquetas ....
Dinu Duque
147

Para obtener solo el valor (sin nombres de atributos), use string():

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

La función fn: string () 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.

acdcjunior
fuente
1
Con xqillaque era necesario llamar xs:string. Me pregunto porque.
krlmlr
1
@krlmlr Probablemente xses el prefijo del espacio de nombres para las funciones XPath. Entonces no están mezclados con otros.
acdcjunior
44
Jajaja Esta es la única respuesta que realmente responde la pregunta. +1
james.garriss
3
Esto proporcionará solo el primer éxito en xmllint
crazyduck
1
¿Qué sucede si tengo una lista de atributos y necesito sus valores? string () parece devolver solo el primer valor.
Damluar
9

Deberías usar //Parent[@id='1']/Children/child/data(@name)

Los atributos no se pueden serializar, por lo que no puede devolverlos en un resultado de aspecto xml. Lo que debe hacer es obtener los datos del atributo utilizando la función data ().

Natalia Maciejowska
fuente
9

Como se respondió anteriormente:

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

solo generará el nameatributo de los 4 childnodos que pertenecen al Parentespecificado por su predicado [@id=1]. Luego deberá cambiar el predicado [@id=2]para obtener el conjunto de childnodos para el siguiente Parent.

Sin embargo, si ignora el Parentnodo por completo y usa:

//child/@name

Puede seleccionar el nameatributo de todos los childnodos de una vez.

name="Child_2"
name="Child_4"
name="Child_1"
name="Child_3"
name="Child_1"
name="Child_2"
name="Child_4"
name="Child_3"
Vinod Srivastav
fuente
6
//Parent/Children[@  Attribute='value']/@Attribute

Este es el caso que se puede usar cuando el elemento tiene 2 atributos y podemos obtener un atributo con la ayuda de otro.

Akshay Dubey
fuente
3

@ryenus, debes recorrer el resultado. Así es como lo haría en 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
NickC
fuente
3

para todos los xml con espacio de nombres use local-name ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
Ed Bangga
fuente