web-dev-qa-db-fra.com

XPath - Différence entre node () et text ()

J'ai du mal à comprendre la différence entre text() et node(). D'après ce que j'ai compris, text() serait ce qu'il y a entre les balises <item>Apple</item> Qui est Apple dans ce cas. Node serait quel que soit ce nœud, ce qui serait item

Mais ensuite, on m'a assigné un travail dans lequel on me demandait de "sélectionner le texte de tous les articles sous produire" et une question distincte demandant "de sélectionner tous les nœuds de gestionnaires dans tous les départements".

Comment la sortie est supposée regarder text() par opposition à node()

Extrait de XML:

<produce>
 <item>Apple</item>
 <item>banana</item>
 <item>pepper</item>
</produce>

<department>
 <phone>123-456-7891</phone>
 <manager>John</manager>
</department>

Bien sûr, il y a plus de départements et plus de gestionnaires, mais ce n'était qu'un extrait de code.

Toute aide serait très appréciée!

57
Pztar

text() et node() sont des tests de nœuds , en terminologie XPath ( comparez ).

Les tests de nœuds fonctionnent sur un ensemble (sur un ) axe , pour être exact) et renvoient ceux qui sont d'un certain type. Lorsqu'aucun axe n'est mentionné, l'axe child est utilisé par défaut.

Il y a toutes sortes de tests de nœuds :

  • node() correspond à un noeud (le test de noeud le plus spécifique)
  • text() correspond à text nœuds uniquement
  • comment() correspond comment noeuds
  • * Correspond à n'importe quel nœud d'élément
  • foo correspond à n'importe quel nœud d'élément nommé "foo"
  • processing-instruction() correspond aux nœuds PI (ils ressemblent à <?name value?>).
  • Note latérale: Le * Correspond également aux nœuds d'attribut, mais uniquement le long de l'axe attribute. @* Est un raccourci pour attribute::*. Les attributs ne font pas partie de l'axe child, c'est pourquoi un * Normal ne les sélectionne pas.

Ce document XML:

<produce>
    <item>Apple</item>
    <item>banana</item>
    <item>pepper</item>
</produce>

représente le DOM suivant (simplifié):

 nœud racine 
 nœud d'élément (name = "produire") 
 nœud de texte (value = "\ n") 
 nœud d'élément (name = "item") 
 noeud de texte (valeur = "Apple") 
 noeud de texte (valeur = "\ n") 
 noeud d'élément (name = "item") 
 noeud de texte (valeur = "banane") 
 nœud de texte (valeur = "\ n") 
 nœud d'élément (name = "item") 
 nœud de texte (valeur = "pepper") 
 noeud de texte (valeur = "\ n") 

Donc avec XPath:

  • / Sélectionne le nœud racine
  • /produce Sélectionne un élément enfant du nœud racine s'il porte le nom "produce" (Appelé élément du document ; il représente le document lui-même. L'élément de document et le nœud racine sont souvent confondus, mais ce n'est pas la même chose.)
  • /produce/node() sélectionne tout type de nœud enfant sous /produce/ (c'est-à-dire tous les 7 enfants)
  • /produce/text() sélectionne les 4 (!) noeuds de texte avec espace seulement
  • /produce/item[1] Sélectionne le premier élément enfant nommé "item"
  • /produce/item[1]/text() sélectionne tous les nœuds de texte enfant (il n'y en a qu'un - "Apple" - dans ce cas)

Etc.

Alors, tes questions

  • "Sélectionnez le texte de tous les éléments sous" "/produce/item/text() (3 nœuds sélectionnés)
  • "Sélectionne tous les nœuds du gestionnaire dans tous les départements" //department/manager (1 nœud sélectionné)

Remarques

  • L'axe par défaut dans XPath est l'axe child. Vous pouvez modifier l'axe en préfixant un nom d'axe différent. Par exemple: //item/ancestor::produce
  • Les nœuds d'élément ont des valeurs de texte. Lorsque vous évaluez un nœud d'élément, son contenu textuel est renvoyé. Dans le cas de cet exemple, /produce/item[1]/text() et string(/produce/item[1]) seront identiques.
  • Voir aussi cette réponse où je décris graphiquement les différentes parties d’une expression XPath.
121
Tomalak

Sélectionnez le texte de tous les articles sous le produit:

//produce/item/text()

Sélectionnez tous les nœuds de gestionnaire dans tous les départements:

//department/*
1
Danil Speransky