Extraire la valeur du nœud d'attribut via XPath


270

Comment puis-je extraire la valeur d'un nœud d'attribut via XPath?

Un exemple de fichier XML est:

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

Jusqu'à présent, j'ai cette chaîne XPath:

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

Il ne renvoie que des childéléments, mais j'aimerais avoir la valeur de l' nameattribut.

Pour mon exemple de fichier XML, voici ce que j'aimerais que la sortie soit:

Child_2
Child_4
Child_1
Child_3

Réponses:


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

Votre original child[@name]signifie un élément childqui a un attribut name. Tu veux child/@name.


14
Je suis d'accord, la question était de savoir comment obtenir la valeur de l'attribut
Vladtn

5
Que faire si je souhaite extraire uniquement la valeur / description / données présentes entre les balises ....
Dinu Duke

147

Pour obtenir uniquement la valeur (sans les noms d'attribut), utilisez string():

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

La fonction fn: string () renverra la valeur de son argument comme xs:string. Dans le cas où son argument est un attribut, il retournera donc la valeur de l'attribut comme xs:string.


1
Avec xqillail fallait appeler xs:string. Je me demande pourquoi.
krlmlr du

1
@krlmlr xsest probablement le préfixe d'espace de noms pour les fonctions XPath. Ils ne sont donc pas mélangés avec les autres.
acdcjunior du

4
LOL. C'est la seule réponse qui répond réellement à la question. +1
james.garriss

3
Cela ne fournira que le premier hit dans xmllint
crazyduck

1
Et si j'ai une liste d'attributs et j'ai besoin de leurs valeurs? string () semble renvoyer uniquement la première valeur.
damluar

9

Tu devrais utiliser //Parent[@id='1']/Children/child/data(@name)

Les attributs ne peuvent pas être sérialisés, vous ne pouvez donc pas les renvoyer dans un résultat au format xml. Ce que vous devez faire est d'obtenir les données de l'attribut à l'aide de la fonction data ().


9

Comme répondu ci-dessus:

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

ne sortira que l' nameattribut des 4 childnœuds appartenant au Parentspécifié par son prédicat [@id=1]. Vous devrez ensuite modifier le prédicat [@id=2]pour obtenir l'ensemble de childnœuds pour le prochainParent .

Cependant, si vous ignorez Parentcomplètement le nœud et utilisez:

//child/@name

vous pouvez sélectionner l' nameattribut de tous les childnœuds en une seule fois.

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

C'est le cas qui peut être utilisé lorsque l'élément a 2 attributs et que nous pouvons obtenir un attribut à l'aide d'un autre.


3

@ryenus, vous devez parcourir le résultat. Voici comment je le ferais 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

pour tout xml avec espace de noms, utilisez local-name ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.