Introduction à l/g'utilisation de XPath avec JavaScript

  • Raccourci de la révision : Introduction_à_l'utilisation_de_XPath_avec_JavaScript
  • Titre de la révision : Introduction à l'utilisation de XPath avec JavaScript
  • ID de la révision : 275667
  • Créé :
  • Créateur : Fredchat
  • Version actuelle ? Non
  • Commentaire /* Constantes définies de XPathResult */

Contenu de la révision

{{template.Traduction_en_cours("Introduction to using XPath in JavaScript")}} Ce document décrit l'utilisation de l'interface d'utilisation de XPath dans JavaScript en interne, dans les extensions et depuis les sites Web. Mozilla implémente une partie importante de DOM 3 XPath (en). Cele signifie que les expressions XPath peuvent être utilisées sur des documents HTML et XML.

La principale interface pour l'utilisation de XPath est la fonction evaluate de l'objet document.

document.evaluate

Cette méthode évalue les expressions XPath dans un document XML (y compris les documents HTML), et retourne un objet XPathResult, que peut être un nœud unique ou un ensemble de nœud. La documentation existante sur cette méthode se trouve à la page DOM:document.evaluate mais elle est plutôt succincte comparé à nos besoins actuels, nous l'examinerons de façon plus complète dans la suite de ce document.

var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );

Paramètres

La fonction evaluate prend cinq arguments au total :

xpathExpression
Une chaîne contenant l'expression XPath à évaluer.
contextNode
Un nœud du document dans lequel xpathExpression doit être évaluée, incluant n'importe lequel de ses descendants. Le nœud document est le plus couramment utilisé.
namespaceResolver
Une fonction qui sera passée à n'importe quel préfixe d'espace de nommage contenu dans xpathExpression qui retourne une chaîne représentant l'URI de l'espace de nommage associé au préfixe. Cela permet la conversion entre le préfixe utilisé dans les expressions XPath et les différents préfixes éventuellement utilisés dans le document. Cette fonction peut être :
  • Créé à l'aide de la méthode createNSResolver d'un objet XPathEvaluator. Vous devriez utiliser cela virtuellement tout le temps.
  • null, qui peut être utilisé pour les documents HTML ou lorsqu'aucun préfixe n'est utilisé. Remarquez que si l'xpathExpression contient un préfixe d'espace de nommage cela entraînera une DOMException envoyée avec le code NAMESPACE_ERR.
  • Une fonction personnalisée par l'utilisateur. Voir la section Implémentation d'un résolveur d'espace de nommage personnalisé dans l'annexe pour plus de détails.
resultType
Une constante qui définit le type de résultat désiré à retourner comme résultat de l'évaluation. La constante la plus courante est XPathResult.ANY_TYPE qui retournera les résultats de l'expression XPath dans le type le plus naturel. Il y a une section de l'annexe qui contient une liste complète des constantes disponibles. Elles sont expliquées dans la section #Définition du type de retour ci-dessous.
  • result : Soit un objet XPathResult existant qui sera réutilisé pour retourner les résultats, soit null qui peut être utilisé pour créer un nouvel objet XPathResult.

Valeur retournée

Retourne xpathResult, qui est un objet XPathResult du type défini dans le paramètre resultType. L'interface XPathResult est définie dans ce document.

Implémentation d'un résolveur d'espaces de nommage par défaut

Nous créons en résolveur d'espace de nommage à l'aide de la méthode createNSResolver de l'objet document.

var nsResolver = document.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement );

Ou alternativement en utilisant la méthode <code>createNSResolver</code> d'un objet <code>XPathEvaluator</code>. <pre> var xpEvaluator = new XPathEvaluator(); var nsResolver = xpEvaluator.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement ); </pre> Puis nous passons document.evaluate, la variable nsResolver comme paramètre namespaceResolver.

Notez que XPath définit les QNames sans les préfixes pour ne correspondre qu'aux éléments de l'espace de nommage null. Il n'existe aucun moyen dans XPath pour récupérer l'espace de nommage par défaut. Pour coupler des éléments ou des attributs dans un espace de nommage non nul, vous devez utiliser prefixed name tests, et créer un résolveur d'espace de nommage qui fera correspondre le préfix avec l'espace de nommage. Apprenez-en plus sur la façon de créer un résolveur d'espace de nommage personnalisé ci-dessous.

Définition du type de retour

La variable xpathResult retournée depuis document.evaluate peut être composée par des nœuds individuels (types simples), ou un groupe de nœuds (types ensemble de nœuds).

Types simples

Lorsque le type de résultat désiré resultType est défini par l'un des types suivants :

  • NUMBER_TYPE - un nombre
  • STRING_TYPE - une chaîne
  • BOOLEAN_TYPE - un booléen

Nous obtenons la valeur retournée de l'expression en accédant, respectivement aux propriétés de l'objet XPathResult suivantes :

  • numberValue
  • stringValue
  • booleanValue
Exemple

Cet exemple utilise l'expression XPath count(//p) pour obtenir le nombre d'éléments <p> présents dans le documents HTML :

var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );

alert( 'Ce document contient ' + paragraphCount.numberValue + ' éléments de paragraphe' );

Bien que JavaScript nous permette de convertir un nombre en chaîne pour l'affichage, l'interface XPath ne convertira pas automatiquement le résultat numérique si la propriété stringValue est requise, ainsi, la code suivant ne fonctionnera pas :

var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );

alert( 'Ce document contient ' + paragraphCount.stringValue + ' éléments de paragraphe' );

À la place il retournera une exception avec le code NS_DOM_TYPE_ERROR.

Types ensemble de nœuds

L'objet XPathResult permet de retourner les ensembles de nœuds dans les trois principaux types :

Itérateurs

Lorsque le type de résultat désiré resultType est défini par l'un des types suivants :

  • UNORDERED_NODE_ITERATOR_TYPE
  • ORDERED_NODE_ITERATOR_TYPE

L'objet XPathResult retourné est un ensemble de nœuds de nœuds appariés qui se comportera comme un itérateur, nous permettant d'accéder aux nœuds individuels qu'il contient en utilisant la méthode iterateNext() de XPathResult.

Une fois l'itération effectuée sur tous les nœuds individuels appariés, iterateNext() retournera null.

Notez cependant que si le document le document est muté (l'arbre du document est modifié) entre les itérations cela invalidera l'itération et la propriété invalidIteratorState de XPathResult sera définie à true, et une exception NS_ERROR_DOM_INVALID_STATE_ERR sera envoyée.

Exemple d'itérateur
var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );

try {
  var thisNode = iterator.iterateNext();
  
  while (thisNode) {
    alert( thisNode.textContent );
    thisNode = iterator.iterateNext();
  }	
}
catch (e) {
  dump( 'Erreur : L'arbre du document a été modifié pendant l'itération ' + e );
}
Snapshots

Lorsque le type de résultat désiré resultType est défini par l'un des types suivants :

  • UNORDERED_NODE_SNAPSHOT_TYPE
  • ORDERED_NODE_SNAPSHOT_TYPE

L'objet XPathResult retourné est un ensemble de nœuds statiques de nœuds appariés, qui nous permet d'accéder à chaque nœud au travers de la méthode snapshotItem(itemNumber) de l'objet XPathResult, où itemNumber est l'index du nœud à récupérer. On peut accéder au nombre total de nœuds contenus dans l'ensemble par la propriété snapshotLength.

Les snapshots ne changent avec les mutations du document, aussi, contrairement aux itérateurs, le snapshot ne devient pas invalide, mais il peut ne plus correspondre au document actuel, par exemple, les nœuds peuvent avoir été déplacés, il peut contenir des nœuds qui n'existent plus ou de nouveaux nœuds peuvent avoir été ajoutés.

Exemple de snapshot
var nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );

for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
{
  dump( nodesSnapshot.snapshotItem(i).textContent );
}
Premiers nœuds

Lorsque le type de résultat désiré resultType est défini par l'un des types suivants :

  • ANY_UNORDERED_NODE_TYPE
  • FIRST_ORDERED_NODE_TYPE

L'objet XPathResult retourné n'est que le premier nœud trouvé qui vérifié l'expression XPath. On peut y accéder à l'aide de la propriété singleNodeValue de l'objet XPathResult. Ce sera null si l'ensemble de nœuds est vide.

Notez que, pour le sous-type non ordonné, le nœud unique retourné ne sera peut-être pas le premier nœud dans l'ordre du document, mais pour le sous-type ordonné, vous pouvez être sûr d'obtenir le premier nœud correspond dans l'ordre du document.

Exemple premier nœud
var firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );

dump( 'Le premier numéro de téléphone trouvé est ' + firstPhoneNumber.singleNodeValue.textContent );

La constante ANY_TYPE

Lorsque le type de résultat désiré resultType est défini par ANY_TYPE, l'objet XPathResult retourné pourra être n'importe quel type résultant naturellement de l'évaluation de l'expression.

Il peut être n'importe lequel des types simples (NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE), mais, si le type du résultat retourné est un ensemble de nœuds alors il ne sera que du type UNORDERED_NODE_ITERATOR_TYPE.

Pour déterminer ce type après l'évaluation, nous utilisons la propriété resultType de l'objet XPathResult. Les valeurs constantes de cette propriété sont définies dans l'annexe.

None Yet =====Exemple Any_Type===== <pre> </pre>

Exemples

Dans un document HTML

Le code suivant est destiné à être inséré dans un fragment JavaScript dans un document HTML ou lié depuis un document HTML que l'expression XPath devra évaluer.

Pour extraire tous les éléments d'en-tête <h2> d'un document HTML à l'aide de XPath, le xpathExpression est simplement '//h2'. Où, // est le Recursive Descent Operator (RDO ou opérateur descendant récursif) qui correspond aux éléments avec le nodeName h2 n'importe où dans l'arbre du document. Le code complet pour cela est : link to introductory xpath doc

var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );

Notez que, comme HTML ne possède pas d'espace de nommage, nous avons passé à null le paramètre namespaceResolver.

Comme nous désirons chercher les en-têtes dans l'intégralité du document, nous avons utilisé l'objet document lui-même comme contextNode.

Le résultat de cette expression est un objet XPathResult. Si nous voulons connaître le type du résultat retourné, nous devons évaluer la propriété resultType de l'objet retourné. Dans ce cas, cela évaluera à 4, un UNORDERED_NODE_ITERATOR_TYPE. C'est le type retourné par défaut lorsque le résultat de l'expression XPath est un ensemble de nœuds. Il fournit un accès à un seul nœud à la fois et ne doit pas retourner les nœuds dans un ordre particulier. Pour accéder aux nœuds retournés, nous utilisons la méthode iterateNext() de l'objet retourné :

var thisHeading = headings.iterateNext();

var alertText = 'Les en-têtes de niveau 2 présents dans ce document sont :\n'

while (thisHeading) {
  alertText += thisHeading.textContent + '\n';
  thisHeading = headings.iterateNext();
}

Une fois l'itération effectuée sur un nœud, nous avons accès à toutes les Interfaces DOM standards de ce nœud. Après l'itération sur tous les éléments h2 retournés depuis notre expression, tout autre appel à iterateNext() retournera null.

Évaluation d'un document XML appartenant à une extension

L'exemple suivant utilise un document XML localisé à l'adresse chrome://yourextension/content/peopleDB.xml.

<?xml version="1.0"?>
<people xmlns:xul = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
  <person>
	<name first="george" last="bush" />
	<address street="1600 pennsylvania avenue" city="washington" country="usa"/>
	<phoneNumber>202-456-1111</phoneNumber>
  </person>
  <person>
	<name first="tony" last="blair" />
	<address street="10 downing street" city="london" country="uk"/>
	<phoneNumber>020 7925 0918</phoneNumber>
  </person>
</people>

Pour rendre accessible les contenus du document XML depuis l'extension, nous créons un objet XMLHttpRequest pour charger de façon synchrone le document, La variable xmlDoc contiendra le document comme un objet XMLDocument sur lequel nous pouvons utiliser la méthode evaluate.

JavaScript utilisé dans les documents xul/js des extensions.

var req = new XMLHttpRequest();

req.open("GET", "chrome://yourextension/content/peopleDB.xml", false); 
req.send(null);

var xmlDoc = req.responseXML;		

var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);

var personIterator = xmlDoc.evaluate('//person', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );

Appendix

Implementing a User Defined Namespace Resolver

This is an example for illustration only. This function will need to take namespace prefixes from the xpathExpression and return the URI that corresponds to that prefix. For example, the expression:

'//xhtml:td/mathml:math'

will select all MathML expressions that are the children of (X)HTML table data cell elements.

In order to associate the mathml: prefix with the namespace URI 'http://www.w3.org/1998/Math/MathML' and html: with the URI http://www.w3.org/1999/xhtml we provide a function:

function nsResolver(prefix) {
  var ns = {
    'xhtml' : 'http://www.w3.org/1999/xhtml',
    'mathml': 'http://www.w3.org/1998/Math/MathML'
  };
  return ns[prefix] || null;
}

Our call to document.evaluate would then looks like:

document.evaluate( '//xhtml:td/mathml:math', document, nsResolver, XPathResult.ANY_TYPE, null );

Implementing a default namespace for XML documents

As noted in the #Implementing a Default Namespace Resolver previously, the default resolver does not handle the default namespace for XML documents. For example with this document:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <entry />
    <entry />
    <entry />
</feed>

doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null) will return an empty set (where nsResolver is the resolver returned by createNSResolver. Passing a null resolver doesn't work any better, either.

One possible workaround is to create a custom resolver that returns the correct default namespace (the Atom namespace in this case). E.g.:

function resolver() {
    return 'http://www.w3.org/2005/Atom';
}
doc.evaluate('//entry', doc, resolver, XPathResult.ANY_TYPE, null)

Note that a more complex resolver will be required if the document uses multiple namespaces.

Constantes définies de XPathResult

Constante du type de résultat Valeur Description
ANY_TYPE 0 Un ensemble contenant n'importe quel type qui résulte naturellement de l'évaluation de l'expression, alors le type résultant sera toujours UNORDERED_NODE_ITERATOR_TYPE.
NUMBER_TYPE 1 Un résultat contenant un nombre unique. C'est utile, par exemple, dans une expression XPath utilisant la fonction count().
STRING_TYPE 2 Un résultat contenant une chaîne unique.
BOOLEAN_TYPE 3 Un résultat contenant une valeur booléenne unique. C'est utile, par exemple, dans une expression XPath utilisant la fonction not().
UNORDERED_NODE_ITERATOR_TYPE 4 Un ensemble de nœuds contenant tous les nœuds vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
ORDERED_NODE_ITERATOR_TYPE 5 Un ensemble de nœuds contenant tous les nœuds vérifiant l'expression. Les nœuds du résultat sont dans le même ordre que celui dans lequel ils apparaissent dans le document.
UNORDERED_NODE_SNAPSHOT_TYPE 6 Un ensemble de nœuds contenant les snapshots de tous les nœuds vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
ORDERED_NODE_SNAPSHOT_TYPE 7 Un ensemble de nœuds contenant les snapshots de tous les nœuds vérifiant l'expression. Les nœuds du résultat sont dans le même ordre que celui dans lequel ils apparaissent dans le document.
ANY_UNORDERED_NODE_TYPE 8 Un ensemble de nœuds contenant n'importe quel nœud unique vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
FIRST_ORDERED_NODE_TYPE 9 Un ensemble de nœuds contenant le premier nœud du document vérifiant l'expression.

Informations sur le document original

  • Document original : Mozilla XPath Tutorial (en)
  • Auteur(s) : James Graham.
  • Autre(s) contributeur(s): James Thompson.
  • Dernière mise à jour : 25 mars 2006

Interwiki Languages Links

{{ wiki.languages( { "en": "en/Introduction_to_using_XPath_in_JavaScript", "ja": "ja/Introduction_to_using_XPath_in_JavaScript", "ko": "ko/Introduction_to_using_XPath_in_JavaScript" } ) }}

Source de la révision

<p>
{{template.Traduction_en_cours("Introduction to using XPath in JavaScript")}}
Ce document décrit l'utilisation de l'interface d'utilisation de <a href="fr/XPath">XPath</a> dans JavaScript en interne, dans les extensions et depuis les sites Web. Mozilla implémente une partie importante de <a class="external" href="http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html">DOM 3 XPath (en)</a>. Cele signifie que les expressions XPath peuvent être utilisées sur des documents HTML et XML.
</p><p>La principale interface pour l'utilisation de XPath est la fonction <a href="fr/DOM/document.evaluate">evaluate</a> de l'objet  <a href="fr/DOM/document">document</a>.
</p>
<h2 name="document.evaluate">document.evaluate</h2>
<p>Cette méthode évalue les expressions <a href="fr/XPath">XPath</a> dans un document <a href="fr/XML">XML</a> (y compris les documents HTML), et retourne un objet <code>XPathResult</code>, que peut être un nœud unique ou un ensemble de nœud. La documentation existante sur cette méthode se trouve à la page <a href="fr/DOM/document.evaluate">DOM:document.evaluate</a> mais elle est plutôt succincte comparé à nos besoins actuels, nous l'examinerons de façon plus complète dans la suite de ce document.
</p>
<pre class="eval">var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
</pre>
<h3 name="Param.C3.A8tres">Paramètres</h3>
<p>La fonction <a href="fr/DOM/document.evaluate">evaluate</a> prend cinq arguments au total :
</p>
<dl><dt> <code>xpathExpression</code>
</dt><dd> Une chaîne contenant l'expression XPath à évaluer.
</dd><dt> <code>contextNode</code>
</dt><dd> Un nœud du document dans lequel <code>xpathExpression</code> doit être évaluée, incluant n'importe lequel de ses descendants. Le nœud <a href="fr/DOM/document">document</a> est le plus couramment utilisé.
</dd><dt> <code>namespaceResolver</code>
</dt><dd> Une fonction qui sera passée à n'importe quel préfixe d'espace de nommage contenu dans <code>xpathExpression</code> qui retourne une chaîne représentant l'URI de l'espace de nommage associé au préfixe. Cela permet la conversion entre le préfixe utilisé dans les expressions XPath et les différents préfixes éventuellement utilisés dans le document. Cette fonction peut être :
</dd></dl>
<ul><li> <a href="#Implementing_a_Default_Namespace_Resolver">Créé</a> à l'aide de la méthode <code><a href="fr/DOM/document.createNSResolver">createNSResolver</a></code> d'un objet <code><a class="external" href="http://www.xulplanet.com/references/objref/XPathEvaluator.html">XPathEvaluator</a></code>. Vous devriez utiliser cela virtuellement tout le temps.
</li><li> <code>null</code>, qui peut être utilisé pour les documents HTML ou lorsqu'aucun préfixe n'est utilisé. Remarquez que si l'<code>xpathExpression</code> contient un préfixe d'espace de nommage cela entraînera une  <code>DOMException</code> envoyée avec le code <code>NAMESPACE_ERR</code>.
</li><li> Une fonction personnalisée par l'utilisateur. Voir la section <a href="#Impl.C3.A9mentation_d.27un_r.C3.A9solveur_d.27espace_de_nommage_personnalis.C3.A9">Implémentation d'un résolveur d'espace de nommage personnalisé</a> dans l'annexe pour plus de détails.
</li></ul>
<dl><dt> <code>resultType</code>
</dt><dd> Une <a href="#Constantes_d.C3.A9finies_de_XPathResult">constante</a> qui définit le type de résultat désiré à retourner comme résultat de l'évaluation. La constante la plus courante est <code>XPathResult.ANY_TYPE</code> qui retournera les résultats de l'expression XPath dans le type le plus naturel. Il y a une section de l'annexe qui contient une liste complète des <a href="#Constantes_d.C3.A9finies_de_XPathResult">constantes disponibles</a>. Elles sont expliquées dans la section <a href="#D.C3.A9finition_du_type_de_retour">#Définition du type de retour</a> ci-dessous.
</dd></dl>
<ul><li> <code>result</code> : Soit un objet <code>XPathResult</code> existant qui sera réutilisé pour retourner les résultats, soit <code>null</code> qui peut être utilisé pour créer un nouvel objet <code>XPathResult</code>.
</li></ul>
<h3 name="Valeur_retourn.C3.A9e">Valeur retournée</h3>
<p>Retourne <code>xpathResult</code>, qui est un objet <code>XPathResult</code> du type <a href="#D.C3.A9finition_du_type_de_retour">défini</a> dans le paramètre <code>resultType</code>. L'interface <code>XPathResult</code> est définie dans ce <a class="external" href="http://lxr.mozilla.org/seamonkey/source/dom/public/idl/xpath/nsIDOMXPathResult.idl">document</a>.
</p>
<h3 name="Impl.C3.A9mentation_d.27un_r.C3.A9solveur_d.27espaces_de_nommage_par_d.C3.A9faut">Implémentation d'un résolveur d'espaces de nommage par défaut</h3>
<p>Nous créons en résolveur d'espace de nommage à l'aide de la méthode <code>createNSResolver</code> de l'objet <a href="fr/DOM/document">document</a>.
</p>
<pre class="eval">var nsResolver = document.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement );
</pre>
<p><span class="comment">Ou alternativement en utilisant la méthode &lt;code&gt;createNSResolver&lt;/code&gt; d'un objet &lt;code&gt;XPathEvaluator&lt;/code&gt;.  &lt;pre&gt; var xpEvaluator = new XPathEvaluator();  var nsResolver = xpEvaluator.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement ); &lt;/pre&gt;</span>
Puis nous passons <code>document.evaluate</code>, la variable <code>nsResolver</code> comme paramètre <code>namespaceResolver</code>.
</p><p>Notez que XPath définit les <code>QNames</code> sans les préfixes pour ne correspondre qu'aux éléments de l'espace de nommage <code>null</code>. Il n'existe aucun moyen dans XPath pour récupérer l'espace de nommage par défaut. Pour coupler des éléments ou des attributs dans un espace de nommage non nul, vous devez utiliser <b>prefixed name tests</b>, et créer un résolveur d'espace de nommage qui fera correspondre le préfix avec l'espace de nommage. Apprenez-en plus sur la façon de <a href="#Impl.C3.A9mentation_d.27un_r.C3.A9solveur_d.27espace_de_nommage_personnalis.C3.A9">créer un résolveur d'espace de nommage personnalisé</a> ci-dessous.
</p>
<h3 name="D.C3.A9finition_du_type_de_retour">Définition du type de retour</h3>
<p>La variable <code>xpathResult</code> retournée depuis <code>document.evaluate</code> peut être composée par des nœuds individuels (<a href="#Types_simples">types simples</a>), ou un groupe de nœuds (<a href="#Types_ensemble_de_n.C5.93uds">types ensemble de nœuds</a>).
</p>
<h4 name="Types_simples">Types simples</h4>
<p>Lorsque le type de résultat désiré <code>resultType</code> est défini par l'un des types suivants :
</p>
<ul><li> <code>NUMBER_TYPE</code>  - un nombre
</li><li> <code>STRING_TYPE</code>  - une chaîne
</li><li> <code>BOOLEAN_TYPE</code> - un booléen
</li></ul>
<p>Nous obtenons la valeur retournée de l'expression en accédant, respectivement aux propriétés de l'objet <code>XPathResult</code> suivantes :
</p>
<ul><li> <code>numberValue</code>
</li><li> <code>stringValue</code>
</li><li> <code>booleanValue</code>
</li></ul>
<h5 name="Exemple">Exemple</h5>
<p>Cet exemple utilise l'expression XPath <code><a href="fr/XPath/Fonctions/count">count(//p)</a></code> pour obtenir le nombre d'éléments <code>&lt;p&gt;</code> présents dans le documents HTML :
</p>
<pre>var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );

alert( 'Ce document contient ' + paragraphCount.numberValue + ' éléments de paragraphe' );
</pre>
<p>Bien que JavaScript nous permette de convertir un nombre en chaîne pour l'affichage, l'interface XPath ne convertira pas automatiquement le résultat numérique si la propriété <code>stringValue</code> est requise, ainsi, la code suivant ne fonctionnera pas :
</p>
<pre>var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );

alert( 'Ce document contient ' + paragraphCount.stringValue + ' éléments de paragraphe' );
</pre>
<p>À la place il retournera une exception avec le code <code>NS_DOM_TYPE_ERROR</code>.
</p>
<h4 name="Types_ensemble_de_n.C5.93uds">Types ensemble de nœuds</h4>
<p>L'objet <code>XPathResult</code> permet de retourner les ensembles de nœuds dans les trois principaux types :
</p>
<ul><li> <a href="#It.C3.A9rateurs">Itérateurs</a>
</li><li> <a href="#Snapshots">Snapshots</a>
</li><li> <a href="#Premiers_n.C5.93uds">Premiers nœuds</a>
</li></ul>
<h5 name="It.C3.A9rateurs">Itérateurs</h5>
<p>Lorsque le type de résultat désiré <code>resultType</code> est défini par l'un des types suivants :
</p>
<ul><li> <code>UNORDERED_NODE_ITERATOR_TYPE</code>
</li><li> <code>ORDERED_NODE_ITERATOR_TYPE</code>
</li></ul>
<p>L'objet <code>XPathResult</code> retourné est un ensemble de nœuds de nœuds appariés qui se comportera comme un itérateur, nous permettant d'accéder aux nœuds individuels qu'il contient en utilisant la méthode <code>iterateNext()</code> de <code>XPathResult</code>. 
</p><p>Une fois l'itération effectuée sur tous les nœuds individuels appariés, <code>iterateNext()</code> retournera <code>null</code>.
</p><p>Notez cependant que si le document le document est muté (l'arbre du document est modifié) entre les itérations cela invalidera l'itération et la propriété <code>invalidIteratorState</code> de <code>XPathResult</code> sera définie à  <code>true</code>, et une exception <code>NS_ERROR_DOM_INVALID_STATE_ERR</code> sera envoyée.
</p>
<h6 name="Exemple_d.27it.C3.A9rateur">Exemple d'itérateur</h6>
<pre>var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );

try {
  var thisNode = iterator.iterateNext();
  
  while (thisNode) {
    alert( thisNode.textContent );
    thisNode = iterator.iterateNext();
  }	
}
catch (e) {
  dump( 'Erreur : L'arbre du document a été modifié pendant l'itération ' + e );
}
</pre>
<h5 name="Snapshots">Snapshots</h5>
<p>Lorsque le type de résultat désiré <code>resultType</code> est défini par l'un des types suivants :
</p>
<ul><li> <code>UNORDERED_NODE_SNAPSHOT_TYPE</code>
</li><li> <code>ORDERED_NODE_SNAPSHOT_TYPE</code>
</li></ul>
<p>L'objet <code>XPathResult</code> retourné est un ensemble de nœuds statiques de nœuds appariés, qui nous permet d'accéder à chaque nœud au travers de la méthode <code>snapshotItem(itemNumber)</code> de l'objet <code>XPathResult</code>, où <code>itemNumber</code> est l'index du nœud à récupérer. On peut accéder au nombre total de nœuds contenus dans l'ensemble par la propriété <code>snapshotLength</code>.
</p><p>Les snapshots ne changent avec les mutations du document, aussi, contrairement aux itérateurs, le snapshot ne devient pas invalide, mais il peut ne plus correspondre au document actuel, par exemple, les nœuds peuvent avoir été déplacés, il peut contenir des nœuds qui n'existent plus ou de nouveaux nœuds peuvent avoir été ajoutés.
</p>
<h6 name="Exemple_de_snapshot">Exemple de snapshot</h6>
<pre>var nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );

for ( var i=0 ; i &lt; nodesSnapshot.snapshotLength; i++ )
{
  dump( nodesSnapshot.snapshotItem(i).textContent );
}
</pre>
<h5 name="Premiers_n.C5.93uds">Premiers nœuds</h5>
<p>Lorsque le type de résultat désiré <code>resultType</code> est défini par l'un des types suivants :
</p>
<ul><li> <code>ANY_UNORDERED_NODE_TYPE</code>
</li><li> <code>FIRST_ORDERED_NODE_TYPE</code>
</li></ul>
<p>L'objet <code>XPathResult</code> retourné n'est que le premier nœud trouvé qui vérifié l'expression XPath. On peut y accéder à l'aide de la propriété <code>singleNodeValue</code> de l'objet <code>XPathResult</code>. Ce sera <code>null</code> si l'ensemble de nœuds est vide.
</p><p>Notez que, pour le sous-type non ordonné, le nœud unique retourné ne sera peut-être pas le premier nœud dans l'ordre du document, mais pour le sous-type ordonné, vous pouvez être sûr d'obtenir le premier nœud correspond dans l'ordre du document.
</p>
<h6 name="Exemple_premier_n.C5.93ud">Exemple premier nœud</h6>
<pre>var firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );

dump( 'Le premier numéro de téléphone trouvé est ' + firstPhoneNumber.singleNodeValue.textContent );
</pre>
<h4 name="La_constante_ANY_TYPE">La constante ANY_TYPE</h4>
<p>Lorsque le type de résultat désiré <code>resultType</code> est défini par <code>ANY_TYPE</code>, l'objet <code>XPathResult</code> retourné pourra être n'importe quel type résultant naturellement de l'évaluation de l'expression.
</p><p>Il peut être n'importe lequel des types simples (<code>NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE</code>), <b>mais</b>, si le type du résultat retourné est un ensemble de nœuds alors il ne sera que du type <code>UNORDERED_NODE_ITERATOR_TYPE</code>.
</p><p>Pour déterminer ce type après l'évaluation, nous utilisons la propriété <code>resultType</code> de l'objet <code>XPathResult</code>. Les valeurs <a href="#Constantes_d.C3.A9finies_de_XPathResult">constantes</a> de cette propriété sont définies dans l'annexe.
</p><p><span class="comment">None Yet =====Exemple Any_Type===== &lt;pre&gt;  &lt;/pre&gt;</span>
</p>
<h2 name="Exemples">Exemples</h2>
<h3 name="Dans_un_document_HTML">Dans un document HTML</h3>
<p>Le code suivant est destiné à être inséré dans un fragment JavaScript dans un document HTML ou lié depuis un document HTML que l'expression XPath devra évaluer.
</p><p>Pour extraire tous les éléments d'en-tête <code>&lt;h2&gt;</code> d'un document HTML à l'aide de XPath, le <code>xpathExpression</code> est simplement '<code>//h2</code>'. Où, <code>//</code> est le Recursive Descent Operator (RDO ou opérateur descendant récursif) qui correspond aux éléments avec le <code>nodeName</code> <code>h2</code> n'importe où dans l'arbre du document. Le code complet pour cela est :
<span class="comment">link to introductory xpath doc</span>
</p>
<pre class="eval">var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );
</pre>
<p>Notez que, comme HTML ne possède pas d'espace de nommage, nous avons passé à <code>null</code> le paramètre <code>namespaceResolver</code>.
</p><p>Comme nous désirons chercher les en-têtes dans l'intégralité du document, nous avons utilisé l'objet <a href="fr/DOM/document">document</a> lui-même comme <code>contextNode</code>.
</p><p>Le résultat de cette expression est un objet <code>XPathResult</code>. Si nous voulons connaître le type du résultat retourné, nous devons évaluer la propriété <code>resultType</code> de l'objet retourné. Dans ce cas, cela évaluera à <code>4</code>, un <code>UNORDERED_NODE_ITERATOR_TYPE</code>. C'est le type retourné par défaut lorsque le résultat de l'expression XPath est un ensemble de nœuds. Il fournit un accès à un seul nœud à la fois et ne doit pas retourner les nœuds dans un ordre particulier. Pour accéder aux nœuds retournés, nous utilisons la méthode <code>iterateNext()</code> de l'objet retourné :
</p>
<pre>var thisHeading = headings.iterateNext();

var alertText = 'Les en-têtes de niveau 2 présents dans ce document sont :\n'

while (thisHeading) {
  alertText += thisHeading.textContent + '\n';
  thisHeading = headings.iterateNext();
}
</pre>
<p>Une fois l'itération effectuée sur un nœud, nous avons accès à toutes les <a href="fr/Interfaces_DOM">Interfaces DOM</a> standards de ce nœud. Après l'itération sur tous les éléments <code>h2</code> retournés depuis notre expression, tout autre appel à <code>iterateNext()</code> retournera <code>null</code>.
</p>
<h3 name=".C3.89valuation_d.27un_document_XML_appartenant_.C3.A0_une_extension">Évaluation d'un document XML appartenant à une extension</h3>
<p>L'exemple suivant utilise un document XML localisé à l'adresse chrome://yourextension/content/peopleDB.xml.
</p>
<pre>&lt;?xml version="1.0"?&gt;
&lt;people xmlns:xul = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" &gt;
  &lt;person&gt;
	&lt;name first="george" last="bush" /&gt;
	&lt;address street="1600 pennsylvania avenue" city="washington" country="usa"/&gt;
	&lt;phoneNumber&gt;202-456-1111&lt;/phoneNumber&gt;
  &lt;/person&gt;
  &lt;person&gt;
	&lt;name first="tony" last="blair" /&gt;
	&lt;address street="10 downing street" city="london" country="uk"/&gt;
	&lt;phoneNumber&gt;020 7925 0918&lt;/phoneNumber&gt;
  &lt;/person&gt;
&lt;/people&gt;
</pre>
<p>Pour rendre accessible les contenus du document XML depuis l'extension, nous créons un objet <code><a href="fr/XMLHttpRequest">XMLHttpRequest</a></code> pour charger de façon synchrone le document, La variable <code>xmlDoc</code> contiendra le document comme un objet <code><a href="fr/XMLDocument">XMLDocument</a></code> sur lequel nous pouvons utiliser la méthode <code>evaluate</code>.
</p><p><i>JavaScript utilisé dans les documents xul/js des extensions.</i>
</p>
<pre>var req = new XMLHttpRequest();

req.open("GET", "chrome://yourextension/content/peopleDB.xml", false); 
req.send(null);

var xmlDoc = req.responseXML;		

var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);

var personIterator = xmlDoc.evaluate('//person', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );
</pre>
<h2 name="Appendix">Appendix</h2>
<h4 name="Implementing_a_User_Defined_Namespace_Resolver">Implementing a User Defined Namespace Resolver</h4>
<p>This is an example for illustration only. This function will need to take namespace prefixes from the <code>xpathExpression</code> and return the URI that corresponds to that prefix. For example, the expression:
</p>
<pre>'//xhtml:td/mathml:math'
</pre>
<p>will select all <a href="fr/MathML">MathML</a> expressions that are the children of (X)HTML table data cell elements. 
</p><p>In order to associate the <code>mathml:</code> prefix with the namespace URI '<code>http://www.w3.org/1998/Math/MathML</code>' and <code>html:</code> with the URI <code>http://www.w3.org/1999/xhtml</code> we provide a function:
</p>
<pre>function nsResolver(prefix) {
  var ns = {
    'xhtml' : 'http://www.w3.org/1999/xhtml',
    'mathml': 'http://www.w3.org/1998/Math/MathML'
  };
  return ns[prefix] || null;
}
</pre>
<p>Our call to <code>document.evaluate</code> would then looks like:
</p>
<pre>document.evaluate( '//xhtml:td/mathml:math', document, nsResolver, XPathResult.ANY_TYPE, null );
</pre>
<h4 name="Implementing_a_default_namespace_for_XML_documents"> Implementing a default namespace for XML documents </h4>
<p>As noted in the <a href="#Implementing_a_Default_Namespace_Resolver">#Implementing a Default Namespace Resolver</a> previously, the default resolver does not handle the default namespace for XML documents.  For example with this document:
</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;feed xmlns="http://www.w3.org/2005/Atom"&gt;
    &lt;entry /&gt;
    &lt;entry /&gt;
    &lt;entry /&gt;
&lt;/feed&gt;
</pre>
<p><code>doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null)</code> will return an empty set (where <code>nsResolver</code> is the resolver returned by <code>createNSResolver</code>.  Passing a <code>null</code> resolver doesn't work any better, either.
</p><p>One possible workaround is to create a custom resolver that returns the correct default namespace (the Atom namespace in this case).  E.g.:
</p>
<pre>function resolver() {
    return 'http://www.w3.org/2005/Atom';
}
doc.evaluate('//entry', doc, resolver, XPathResult.ANY_TYPE, null)
</pre>
<p>Note that a more complex resolver will be required if the document uses multiple namespaces.
</p>
<h4 name="Constantes_d.C3.A9finies_de_XPathResult">Constantes définies de XPathResult</h4>
<table class="standard-table">

<tbody><tr>
<td class="header">Constante du type de résultat
</td><td class="header">Valeur
</td><td class="header">Description
</td></tr>

<tr>
<td>ANY_TYPE
</td><td>0
</td><td>Un ensemble contenant n'importe quel type qui résulte naturellement de l'évaluation de l'expression, alors le type résultant sera toujours UNORDERED_NODE_ITERATOR_TYPE.
</td></tr>

<tr>
<td>NUMBER_TYPE
</td><td>1
</td><td>Un résultat contenant un nombre unique. C'est utile, par exemple, dans une expression XPath utilisant la fonction <code>count()</code>.
</td></tr>

<tr>
<td>STRING_TYPE
</td><td>2
</td><td>Un résultat contenant une chaîne unique.
</td></tr>

<tr>
<td>BOOLEAN_TYPE
</td><td>3
</td><td>Un résultat contenant une valeur booléenne unique. C'est utile, par exemple, dans une expression XPath utilisant la fonction <code>not()</code>.
</td></tr>

<tr>
<td>UNORDERED_NODE_ITERATOR_TYPE
</td><td>4
</td><td>Un ensemble de nœuds contenant tous les nœuds vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
</td></tr>

<tr>
<td>ORDERED_NODE_ITERATOR_TYPE
</td><td>5
</td><td>Un ensemble de nœuds contenant tous les nœuds vérifiant l'expression. Les nœuds du résultat sont dans le même ordre que celui dans lequel ils apparaissent dans le document.
</td></tr>

<tr>
<td>UNORDERED_NODE_SNAPSHOT_TYPE
</td><td>6
</td><td>Un ensemble de nœuds contenant les snapshots de tous les nœuds vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
</td></tr>

<tr>
<td>ORDERED_NODE_SNAPSHOT_TYPE
</td><td>7
</td><td>Un ensemble de nœuds contenant les snapshots de tous les nœuds vérifiant l'expression. Les nœuds du résultat sont dans le même ordre que celui dans lequel ils apparaissent dans le document.
</td></tr>

<tr>
<td>ANY_UNORDERED_NODE_TYPE
</td><td>8
</td><td>Un ensemble de nœuds contenant n'importe quel nœud unique vérifiant l'expression. Les nœuds ne sont pas nécessairement être dans le même ordre que celui dans lequel ils apparaissent dans le document.
</td></tr>

<tr>
<td>FIRST_ORDERED_NODE_TYPE
</td><td>9
</td><td>Un ensemble de nœuds contenant le premier nœud du document vérifiant l'expression.
</td></tr>
</tbody></table>
<div class="originaldocinfo">
<h2 name="Informations_sur_le_document_original"> Informations sur le document original </h2>
<ul><li> Document original : <a class="external" href="http://www-xray.ast.cam.ac.uk/~jgraham/mozilla/xpath-tutorial.html">Mozilla XPath Tutorial (en)</a>
</li><li> Auteur(s) : James Graham.
</li><li> Autre(s) contributeur(s): James Thompson.
</li><li> Dernière mise à jour : 25 mars 2006
</li></ul>
</div>
<p><span class="comment">Interwiki Languages Links</span>
</p>{{ wiki.languages( { "en": "en/Introduction_to_using_XPath_in_JavaScript", "ja": "ja/Introduction_to_using_XPath_in_JavaScript", "ko": "ko/Introduction_to_using_XPath_in_JavaScript" } ) }}
Revenir à cette révision