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

Respuestas:


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

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


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.


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 ().


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"

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.


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

3

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

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.