Lisez-moi S.V.P. 

13 novembre 2000

1. Le modèle objet de document Traversal

Rédacteurs
Joe Kesselman, IBM
Jonathan Robie, Software AG
Mike Champion, Software AG

Table des matières

1.1. Aperçu

Ce chapitre décrit la fonctionnalité optionnelle "Traversal" du DOM niveau 2. Ses interfaces TreeWalker, NodeIterator et NodeFilter permettent de traverser facilement, de façon fiable et sélectivement le contenu d'un document.

Les interfaces décrites dans cette section ne sont pas obligatoires. Une application DOM peut employer la méthode hasFeature(feature, version) de l'interface DOMImplementation, respectivement avec les valeurs de paramètre "Traversal" et "2.0", pour déterminer si ce module est reconnu ou non par la mise en œuvre. Pour la gestion complète de ce module, une mise en œuvre doit également gérer la fonctionnalité "Core" définie dans la spécification DOM niveau 2 Core [DOM niveau 2 Core]. Consulter la section à propos de la conformité→vf dans la spécification DOM niveau 2 Core [DOM niveau 2 Core] pour d'autres renseignements.

Les interfaces NodeIterator et TreeWalker permettent de représenter de deux façons les nœuds du sous-arbre d'un document et une position dans les nœuds de ce sous-arbre. L'interface NodeIterator présente une vue à plat du sous-arbre en tant que séquence ordonnée de nœuds, dans l'ordre du document. Comme cette vue se présente indépendamment de la hiérarchie, les itérateurs disposent de méthodes pour avancer ou reculer mais pas pour remonter ou descendre. Au contraire, l'interface TreeWalker maintient les relations hiérarchiques du sous-arbre, qui permettent une navigation dans la hiérarchie. En général, les objets TreeWalker se prêteront mieux aux tâches où on manipulera la structure du document autour des nœuds sélectionnés, tandis que les itérateurs NodeIterator se prêteront mieux aux tâches qui se concentrent sur le contenu de chaque nœud sélectionné.

Les interfaces NodeIterator et TreeWalker présentent chacune une vue d'un sous-arbre du document qui ne contiendra peut-être pas tous les nœuds présents dans le sous-arbre. Dans cette spécification, on l'appelle la vue logique en la distinguant de la vue physique qui correspond au sous-arbre du document en soi. Lorsqu'on crée un itérateur, ou un objet TreeWalker, on peut l'associer à un filtre NodeFilter, lequel examine chaque nœud et détermine son apparition ou non dans la vue logique. En outre, on peut utiliser des indicateurs pour définir les types de nœud susceptibles d'apparaître dans la vue logique.

Les objets NodeIterator et TreeWalker sont dynamiques : la vue logique change pour refléter les changements opérés sur le document sous-jacent. Toutefois, ils se distinguent dans leurs réponses à ces changements. Les itérateurs NodeIterator, qui présentent les nœuds en séquence, essayent de maintenir leur emplacement relativement à une position dans la séquence quand son contenu change. Les objets TreeWalker, qui présentent les nœuds sous une forme d'arbre filtré, maintiennent leur emplacement relativement à leur nœud courant et lui restent attachés quand ce nœud se déplace dans un nouveau contexte. Ces comportements sont expliqués plus loin en détails.

1.1.1. L'interface NodeIterator

L'itérateur NodeIterator permet de retourner les membres d'une liste de nœuds en séquence. Dans les interfaces DOM courantes, cette liste se composera toujours des nœuds d'un sous-arbre, présentés dans l'ordre du document. À la création d'un itérateur, l'appel de sa méthode nextNode() retourne le premier nœud dans la vue logique du sous-arbre ; dans la plupart des cas, il s'agit de la racine du sous-arbre. Chaque appel successif fait avancer l'objet NodeIterator à travers la liste, en retournant le nœud suivant disponible dans la vue logique. La méthode nextNode() retourne la valeur null quand il n'y a plus de nœud visible.

On crée les itérateurs NodeIterator en utilisant la méthode createNodeIterator qui se trouve dans l'interface DocumentTraversal. Quand on crée un itérateur NodeIterator, on peut utiliser des indicateurs pour déterminer quels types de nœud seront « visibles » et quels nœuds seront « invisibles » pendant la traversée de l'arbre ; ces indicateurs peuvent se combiner avec l'opérateur OR. L'itérateur dépasse les nœuds invisibles comme s'ils n'existaient pas.

Le code suivant crée un itérateur puis appelle une fonction pour imprimer le nom de chaque élément :

    NodeIterator iter=
     ((DocumentTraversal)document).createNodeIterator(
          root, NodeFilter.SHOW_ELEMENT, null);

    while (Node n = iter.nextNode())
        printMe(n);
     

1.1.1.1. En avant et en arrière

Les itérateurs NodeIterator présentent les nœuds sous forme d'une liste ordonnée et avancent ou reculent dans celle-ci. L'itérateur est toujours positionné entre deux nœuds, avant le premier ou bien après le dernier. À sa création, l'itérateur est positionné avant le premier élément. Le diagramme suivant montre une vue de la liste d'un sous-arbre particulier par un itérateur, sa position est marquée par un caractère astérisque « * » :

 * A B C D E F G H I

Chaque appel de la méthode nextNode() retourne le nœud suivant et avance la position. Par exemple, en commençant à partir de la position précédente, le premier appel de nextNode() retourne A et avance l'itérateur à la position suivante :

 [A] * B C D E F G H I

La position d'un itérateur NodeIterator est mieux décrite par rapport au dernier nœud retourné, qu'on appelle le nœud de référence. Quand on crée un itérateur, le premier nœud est le nœud de référence et l'itérateur se positionne avant lui. Dans les diagrammes suivants, le nœud de référence est signalé par des crochets.

L'appel de la méthode previousNode() retourne le nœud précédent et recule la position. Par exemple, en commençant avec l'itérateur entre A et B, la méthode retournera A et déplacera la position comme ceci :

 * [A] B C D E F G H I

Si on appelle la méthode nextNode() à la fin d'une liste, ou si on appelle previousNode() au début d'une liste, la valeur null sera retournée et la position de l'itérateur ne changera pas. À la création d'un itérateur NodeIterator, le nœud de référence est le premier :

 * [A] B C D E F G H I

1.1.1.2. La fiabilité

Un itérateur NodeIterator peut être actif pendant l'édition de la structure de données où il navigue, et un itérateur doit donc avoir un comportement progressif face au changement. Les ajouts et retraits dans la structure de données sous-jacente n'invalident pas l'objet NodeIterator ; en fait, il n'est jamais invalidé tant que l'on n'invoque pas sa méthode detach(). Afin d'y parvenir, l'itérateur utilise le nœud de référence pour maintenir sa position. L'état d'un itérateur peut aussi dépendre de sa position avant ou après le nœud de référence.

Si les changements sur la liste itérée ne produisent pas le retrait du nœud de référence, alors ils n'affectent pas l'état de l'itérateur NodeIterator. Par exemple, l'état de l'itérateur n'est pas affecté par l'insertion de nouveaux nœuds à son voisinage ou par le retrait d'autres nœuds hormis celui de référence. Soit la situation initiale suivante :

A B C [D] * E F G H I

Retirons E. L'état final est le suivant :

A B C [D] * F G H I

Lorsqu'on insère un nouveau nœud, l'itérateur NodeIterator reste au contact du nœud de référence, et l'insertion d'un nœud X entre D et F interviendra donc entre l'itérateur et F :

A B C [D] * X F G H I

Le déplacement d'un nœud équivaut à un retrait suivi d'une insertion. Si on déplace et positionne I avant X, le résultat est le suivant :

A B C [D] * I X F G H

Si on retire le nœud de référence pendant l'itération de la liste, un autre nœud est sélectionné comme nœud de référence. Si la position du nœud de référence est avant celle de l'itérateur NodeIterator, ce qui est normalement le cas après un appel de la méthode nextNode(), le nœud le plus proche avant l'itérateur est sélectionné comme nœud de référence. Supposons que l'on retire le nœud D dans la situation initiale suivante :

A B C [D] * F G H I

Le nœud C devient le nouveau nœud de référence, car il est le plus proche de l'itérateur NodeIterator et avant lui :

A B [C] * F G H I

Si le nœud de référence est après l'itérateur NodeIterator, ce qui est normalement le cas après un appel de la méthode previousNode(), le nœude le plus proche après l'itérateur est sélectionné comme nœud de référence. Supposons que l'on retire E dans la situation initiale suivante :

A B C D * [E] F G H I

Le nœud F devient le nouveau nœud de référence, car il est le plus proche de l'itérateur NodeIterator et après lui :

A B C D * [F] G H I

Comme indiqué précédemment, déplacer un nœud équivaut à le retirer puis à l'insérer. Supposons que l'on veuille déplacer le nœud D à la fin de la liste dans la situation initiale suivante :

A B C [D] * F G H I C

L'état final sera le suivant :

A B [C] * F G H I D

Le retrait d'un nœud de référence quand sa position est en fin de la liste représente un cas particulier. Supposons que l'on retire le nœud C dans la situation initiale suivante :

A B * [C]

Conformément aux règles précédentes, le nouveau nœud de référence devrait être celui le plus proche après l'itérateur NodeIterator mais il n'y en a aucun après C. La même situation peut se produire quand la méthode previousNode() vient juste de retourner le premier nœud de la liste lequel est retiré ensuite. Donc, s'il n'y a aucun nœud en direction originale du nœud de référence, le nœud le plus proche dans la direction opposée est sélectionné comme nœud de référence :

A [B] *

Si l'itérateur NodeIterator est positionné dans un bloc de nœuds qui est retiré, la règle précédente indique clairement l'action entreprise. Par exemple, supposons que C soit le nœud parent de D, E et F et que l'on retire C dans la situation initiale suivante :

A B C [D] * E F G H I D

L'état final sera le suivant :

A [B] * G H I D

En définitive, remarquer que le retrait du nœud racine d'un itérateur NodeIterator de son parent n'altère pas la liste en cours d'itération et ne change donc pas l'état de l'itérateur.

1.1.1.3. La visibilité des nœuds

La structure de données sous-jacente en cours d'itération peut contenir des nœuds qui ne font pas partie de la vue logique et qui, de ce fait, ne seront pas retournés par l'itérateur NodeIterator. Si un nœud est exclu en conséquence de la valeur de l'indicateur whatToShow, la méthode nextNode() retourne le nœud visible suivant et dépasse en les excluant ceux qui sont « invisibles ». Si un filtre NodeFilter est présent, il s'appliquera avant de retourner le nœud ; si le filtre n'accepte pas le nœud, le processus se répète jusqu'à ce que le filtre en accepte un et que le nœud soit retourné. Si aucun nœud visible n'est rencontré, la valeur null est retournée et l'itérateur se positionne à la fin de la liste. Auquel cas, le nœud de référence est le dernier nœud, qu'il soit visible ou non. La même approche est adoptée pour la méthode previousNode(), en direction opposée.

Dans les exemples suivants, on utilisera des lettres minuscules pour représenter les nœuds présents dans la structure de données mais absents de la vue logique. Par exemple, prenons la liste suivante :

A [B] * c d E F G

Un appel de la méthode nextNode() retourne E et fait avancer l'itérateur à la position suivante :

A B c d [E] * F G

Les nœuds invisibles peuvent toutefois servir de référence, si un nœud de référence est retiré. Supposons que le nœud E soit retiré dans la situation initiale précédente. L'état final est le suivant :

A B c [d] * F G

Supposons qu'un nouveau nœud X visible soit inséré avant d. L'état final est le suivant :

A B c X [d] * F G

Remarquer qu'un appel de la méthode previousNode() retourne désormais le nœud X. Il importe de ne pas dépasser les nœuds invisibles quand le nœud de référence est retiré car, dans certains cas tel que le précédent, des résultats erronés seront retournés. Quand E a été retourné, si le nouveau nœud de référence avait été B au lieu de d, l'appel de la méthode previousNode() n'aurait pas retourné X.

1.1.2. L'interface NodeFilter

L'interface NodeFilter permet à l'utilisateur de créer des objets qui « trient » les nœuds. Chaque filtre contient une fonction écrite par l'utilisateur qui examine le nœud et détermine s'il doit être présenté ou non comme partie de la vue logique de la traversée du document. Pour utiliser un filtre NodeFilter, on crée un objet NodeIterator, ou TreeWalker, qui l'utilise. Le moteur de traversée applique le filtre à chaque nœud et, si le filtre ne retient pas le nœud, la traversée dépasse le nœud comme s'il n'était pas présent dans le document. Les filtres NodeFilter n'ont pas besoin de savoir comment naviguer dans la structure contenant les nœuds sur lesquels ils agissent.

Les filtres sont consultés lorsqu'une opération de traversée a lieu, ou lorsqu'on retire le nœud de référence d'un itérateur NodeIterator dans le sous-arbre en cours d'itération et que l'itérateur doit en sélectionner un nouveau. Toutefois, la temporisation exacte des appels de ces filtre peut varier d'une mise en œuvre DOM à l'autre. Pour cette raison, les filtres NodeFilter ne devraient pas essayer de maintenir d'état fondé sur l'historique des invocations passées ; le comportement final ne sera peut-être pas portable.

De même, les objets TreeWalker et NodeIterator devraient se comporter comme s'ils n'avaient aucune mémoire des résultats de filtrages passés ni anticipaient de résultats futurs. Si les conditions examinées par un filtre NodeFilter ont changé (par exemple, un attribut testé a été ajouté ou retiré) depuis la dernière logique de traversée du nœud, ce changement de visibilité ne sera découvert qu'à la prochaine opération de traversée. Par exemple, si la constante de filtrage du nœud courant change de FILTER_SHOW FILTER_ACCEPT à FILTER_SKIP, un objet TreeWalker pourra naviguer hors de ce nœud, dans toutes les directions, mais pas y revenir tant que les conditions de filtrage n'auront pas à nouveau changé. On peut écrire des filtres NodeFilter qui changent pendant une traversée mais leur comportement pouvant être ambigu on devrait si possible éviter de le faire.

1.1.2.1. L'utilisation des filtres NodeFilter

Un filtre NodeFilter contient une seule méthode acceptNode() qui permet à un itérateur NodeIterator ou à un objet TreeWalker de passer un nœud Node au filtre, afin qu'il détermine si ce nœud devrait être présent ou non dans la vue logique. La fonction acceptNode() retourne l'une de trois valeurs, qui indiquent comment traiter le nœud Node. Si acceptNode() retourne la valeur FILTER_ACCEPT, le nœud Node sera présent dans la vue logique ; pour la valeur FILTER_SKIP, le nœud ne sera pas présent dans la vue logique quoique ses enfants puissent l'être ; pour la valeur FILTER_REJECT, ni le nœud ni ses descendants ne seront dans la vue logique. Puisque les itérateurs NodeIterator présentent les nœuds sous forme d'une liste ordonnée sans hiérarchie, les valeurs FILTER_REJECT et FILTER_SKIP sont synonymes pour ces itérateurs qui ne dépassent que le seul nœud courant.

Supposons un filtre qui accepte les ancres nommées dans un document HTML. En HTML, un attribut HREF peut désigner tout élément A ayant un attribut NAME. Voici un filtre NodeFilter en Java pour examiner un nœud et déterminer s'il s'agit d'une ancre nommée :

    class NamedAnchorFilter implements NodeFilter
    {
     short acceptNode(Node n) {
      if (n.getNodeType()==Node.ELEMENT_NODE) {
       Element e = (Element)n;
       if (! e.getNodeName().equals(A))
        return FILTER_SKIP;
      if (e.getAttributeNode("NAME") != null)
        return FILTER_ACCEPT;
       }
        return FILTER_SKIP;
      }
    }

Si le filtre précédent NodeFilter ne devait servir qu'avec des itérateurs NodeIterator, il pourrait utiliser la valeur FILTER_REJECT à chaque fois que la valeur FILTER_SKIP était employée, et le comportement ne changerait pas. Par contre, pour un objet TreeWalker, une valeur FILTER_REJECT rejetterait les enfants de tout élément qui n'est pas une ancre nommée et, comme les ancres nommées sont toujours contenues dans d'autres éléments, aucune ancre nommée n'aurait été trouvée. La valeur FILTER_SKIP rejette le nœud en question mais continue d'examiner les enfants ; le filtre précédent fonctionnera donc avec un itérateur NodeIterator comme avec un objet TreeWalker.

Pour utiliser ce filtre, l'utilisateur devra créer une instance de filtre NodeFilter et un itérateur NodeIterator qui l'utilise :

NamedAnchorFilter myFilter = new NamedAnchorFilter(); 
NodeIterator iter=
     ((DocumentTraversal)document).createNodeIterator(
          node, NodeFilter.SHOW_ELEMENT, myFilter);
   

Remarquer que l'emploi de l'indicateur SHOW_ELEMENT n'est pas strictement nécessaire dans cet exemple, dans la mesure où le filtre NodeFilter teste l'attribut nodeType (N.D.T. getNodeType). Toutefois, certaines mises en œuvre des interfaces Traversal peuvent améliorer les performances de l'attribut whatToShow en profitant d'une connaissance de la structure du document, ce qui rend l'utilisation de SHOW_ELEMENT précieuse. Au contraire, alors qu'on pouvait supprimer le test de l'attribut nodeType dans le filtre, le filtre serait devenu dépendant de l'attribut whatToShow pour distinguer les objets de type Element, Attr et ProcessingInstruction.

1.1.2.2. Les filtres NodeFilter et les exceptions

Pour l'écriture d'un filtre NodeFilter, les utilisateurs devraient éviter d'écrire du code susceptible de soulever une exception. Néanmoins, puisqu'une mise en œuvre DOM ne peut pas empêcher les exceptions, il importe de bien définir le comportement des filtres susceptibles de le faire. Un itérateur TreeWalker, ou un objet NodeIterator, ne capture pas ni n'altère l'exception lancée par un filtre mais la laisse se propager jusqu'au code de l'utilisateur. Les fonctions suivantes peuvent invoquer un filtre NodeFilter et peuvent donc propager une exception si le filtre en lance une :

  1. NodeIterator.nextNode()
  2. NodeIterator.previousNode()
  3. TreeWalker.firstChild()
  4. TreeWalker.lastChild()
  5. TreeWalker.nextSibling()
  6. TreeWalker.previousSibling()
  7. TreeWalker.nextNode()
  8. TreeWalker.previousNode()
  9. TreeWalker.parentNode()

1.1.2.3. Les filtres NodeFilter et la mutation du document

Les filtres NodeFilter bien conçus ne devraient pas avoir à modifier la structure sous-jacente du document. Mais une mise en œuvre DOM ne peut pas empêcher l'utilisateur d'écrire un filtre qui altère la structure du document. Le module Traversal ne propose aucun traitement spécial pour gérer ce cas. Par exemple, si un filtre NodeFilter retire un nœud d'un document, il peut toujours l'accepter, c'est-à-dire que le nœud peut être retourné par l'itérateur NodeIterator, ou l'objet TreeWalker, bien qu'il ne soit plus dans le sous-arbre traversé. En général, cela peut conduire à des résultats incohérents et ambigus, et on encourage donc les utilisateurs à écrire des filtres NodeFilter qui ne changent pas la structure du document. Faites plutôt l'édition dans la boucle contrôlée par l'objet de traversée.

1.1.2.4. Les filtres NodeFilter et les indicateurs whatToShow

Les itérateurs NodeIterator et les objets TreeWalker appliquent leurs indicateurs whatToShow avant d'appliquer les filtres. Si un nœud est dépassé du fait des indicateurs actifs whatToShow, aucun filtre NodeFilter ne sera appelé pour évaluer le nœud. Remarquer que ce comportement est similaire à celui pour la valeur FILTER_SKIP ; les enfants du nœud seront pris en compte et des filtres pourront être appelés pour les évaluer. Remarquer aussi qu'il s'agira en réalité d'un d'un « dépassement » même si le filtre NodeFilter aurait préféré rejeter le sous-arbre entier ; si cela posait un problème pour votre application, fixez la valeur de whatToShow à SHOW_ALL et faites le test nodeType dans le filtre.

1.1.3. L'interface TreeWalker

L'interface TreeWalker offre beaucoup des avantages de l'interface NodeIterator. La différence principale entre les deux réside dans le fait que l'interface TreeWalker présente une vue arborescente des nœuds dans un sous-arbre au lieu de la vue en liste de l'itérateur. En d'autres termes, un itérateur permet de se déplacer en avant et en arrière, tandis qu'un objet TreeWalker permet de se déplacer au parent d'un nœud, à l'un de ses enfants ou à un frère.

L'utilisation de l'interface TreeWalker ressemble assez à une navigation en se servant directement du nœud, les méthodes de navigation des deux interfaces étant analogues. Par exemple, voici une fonction qui parcourt récursivement un arbre de nœuds dans l'ordre du document, en entreprenant des actions distinctes d'abord pour l'accès au nœud puis après le traitement des enfants :

processMe(Node n) {
   nodeStartActions(n);
   for (Node child=n.firstChild(); 
        child != null;
        child=child.nextSibling()) {
      processMe(child);
   }
   nodeEndActions(n);
}

Faire la même chose avec un objet TreeWalker est très semblable. Sauf que, puisque la navigation avec l'objet TreeWalker change la position courante, la position aura changé à la fin de la fonction. Un attribut en lecture/écriture appelé currentNode permet de rechercher et de fixer la valeur du nœud courant d'un objet TreeWalker. On l'utilisera pour s'assurer que la position de l'objet TreeWalker sera restaurée quand la fonction aura terminé :

processMe(TreeWalker tw) {
   Node n = tw.getCurrentNode();
   nodeStartActions(tw);
   for (Node child=tw.firstChild(); 
        child!=null;
        child=tw.nextSibling()) {
      processMe(tw);
   }

   tw.setCurrentNode(n);
   nodeEndActions(tw);
}

L'avantage d'employer un objet TreeWalker au lieu d'une navigation directe par œud est que l'objet TreeWalker permet à l'utilisateur de choisir une vue appropriée de l'arbre. On peut utiliser des indicateurs pour exposer ou cacher des nœuds Comment ou ProcessingInstruction ; on peut développer ou exposer des entités sous forme de nœuds EntityReference. En outre, on peut utiliser des filtres NodeFilter pour présenter une vue personnalisée de l'arbre. Supposons qu'un programme ait besoin d'une vue d'un document qui montre quelles tables apparaissent dans chaque chapitre, listées par chapitre. Dans cette vue, seuls les éléments CHAPTER et les éléments TABLE qu'ils contiennent sont visibles. La première étape consiste à écrire un filtre adéquat :

class TablesInChapters implements NodeFilter {

   short acceptNode(Node n) {
      if (n.getNodeType()==Node.ELEMENT_NODE) {
    
          if (n.getNodeName().equals("CHAPTER"))
             return FILTER_ACCEPT;

          if (n.getNodeName().equals("TABLE"))
             return FILTER_ACCEPT;

          if (n.getNodeName().equals("SECT1")
              || n.getNodeName().equals("SECT2")
              || n.getNodeName().equals("SECT3")
              || n.getNodeName().equals("SECT4")
              || n.getNodeName().equals("SECT5")
              || n.getNodeName().equals("SECT6")
              || n.getNodeName().equals("SECT7"))
             return FILTER_SKIP;

      }

      return FILTER_REJECT;
    }
}

Ce filtre suppose que les éléments TABLE soient directement contenus dans des éléments CHAPTER ou SECTn. En cas de rencontre d'un autre type d'élément, l'élément et ses enfants seront rejetés. En cas de rencontre d'un élément SECTn, l'élément sera dépassé mais ses enfants seront explorés pour voir s'ils contiennent des éléments TABLE.

Le programme peut désormais créer une instance de ce filtre NodeFilter, créer un objet TreeWalker qui l'utilise et passer cet objet TreeWalker à la fonction ProcessMe() :

TablesInChapters tablesInChapters  = new TablesInChapters();
TreeWalker tw  = 
     ((DocumentTraversal)document).createTreeWalker(
          root, NodeFilter.SHOW_ELEMENT, tablesInChapters);
processMe(tw);

(Une fois encore, on a choisi à la fois de tester l'attribut nodeType conformément à la logique du filtre et d'utiliser l'indicateur SHOW_ELEMENT, pour les raisons abordées dans l'exemple antérieur avec l'itérateur NodeIterator).

Sans changer la fonction ProcessMe() précédente, elle ne traitera maintenant que les éléments CHAPTER et TABLE. Le programmeur peut écrire d'autres filtres ou paramétrer d'autres indicateurs pour sélectionner des jeux de nœuds différents ; si les fonctions utilisent un objet TreeWalker pour naviguer, elles reconnaîtront toute vue du document définie avec un objet TreeWalker.

Remarquer que la structure de la vue filtrée d'un document d'un objet TreeWalker peut différer significativement de la vue du document en question. Par exemple, un objet TreeWalker, dont le paramètre whatToShow a seulement la valeur SHOW_TEXT, présenterait tous les nœuds Text comme si tous étaient frères et pourtant n'avaient aucun parent.

1.1.3.1. La fiabilité

Comme pour les itérateurs NodeIterator, un objet TreeWalker peut être actif, alors que la structure de données où il navigue est en cours d'édition, et il doit donc avoir un comportement progressif face au changement. Les ajouts et retraits dans la structure de données sous-jacente n'invalident pas un objet TreeWalker ; en fait, un objet TreeWalker n'est jamais invalidé.

Mais la réponse d'un objet TreeWalker face aux changements est très différente de celle de l'itérateur NodeIterator. Tandis que les itérateurs NodeIterator répondront à une édition en maintenant leur position dans la liste itérée, les objets TreeWalker resteront plutôt attachés au nœud désigné par leur attribut currentNode. Toutes les méthodes de navigation de l'interface TreeWalker opèrent au niveau du nœud courant currentNode au moment où on les invoquent, quoiqu'il soit arrivé au nœud, ou autour du nœud, depuis son dernier accès par l'objet TreeWalker. Ceci reste vrai même si l'objet currentNode est sorti de son sous-arbre d'origine.

Pour exemple, considérons le fragment de document suivant :

    ...
    <subtree>
        <twRoot>
            <currentNode/>
            <anotherNode/>
        </twRoot>
    </subtree>
    ...
 

Supposons que l'on ait créé un objet TreeWalker dont le nœud racine est l'élément <twRoot/> et dont le nœud courant est l'élément <currentNode/>. Pour cette illustration, on supposera que tous les nœuds montrés ci-dessus sont acceptés par les indicateurs whatToShow et les filtres de l'objet TreeWalker.

Si on utilise la méthode removeChild() pour retirer l'élément <currentNode/> de son parent, cet élément reste le nœud courant currentNode de l'objet TreeWalker, même s'il n'est plus dans le sous-arbre du nœud racine. On peut toujours utiliser l'objet TreeWalker pour naviguer à travers les enfants éventuels du nœud currentNode orphelin, mais on ne peut plus naviguer hors du contexte de ce nœud currentNode puisqu'il n'y a aucun parent disponible.

Si on utilise la méthode insertBefore(), ou appendChild(), pour donner un nouveau parent à l'élément <currentNode/>, alors la navigation de l'objet TreeWalker opérera à partir de la nouvelle position du nœud courant currentNode. Par exemple, si on insère <currentNode/> immédiatement après l'élément <anotherNode/>, la méthode previousSibling() de l'objet TreeWalker établirait <anotherNode/> comme nœud courant et l'appel de la méthode parentNode() remonterait à l'élément <twRoot/>.

Si au lieu de cela on insère le nœud courant currentNode dans l'élément <subtree/> de cette façon :

    ...
    <subtree>
        <currentNode/>
        <twRoot>
            <anotherNode/>
        </twRoot>
    </subtree>
    ...

On aura sorti le nœud courant currentNode du nœud racine de l'objet TreeWalker. Cela n'invalide pas l'objet TreeWalker, et on peut toujours l'utiliser pour naviguer par rapport au nœud courant currentNode. Par exemple, l'appel de la méthode parentNode() l'établirait sur l'élément <subtree/> quoiqu'il soit aussi en-dehors du nœud racine d'origine. Par contre, si la navigation de l'objet TreeWalker devait le ramener dans le sous-arbre du nœud racine original (par exemple, au lieu d'appeler la méthode parentNode(), si on avait appelé nextNode() qui déplacerait l'objet TreeWalker sur l'élément <twRoot/>) le nœud racine « recapturera » l'objet TreeWalker et l'empêchera de retourner en arrière.

Les choses sont un peu plus compliquées avec des filtres. Le repositionnement du nœud courant currentNode (ou la sélection explicite d'un nouveau currentNode, ou le changement des conditions qui interviennent dans la décision du filtre NodeFilter) peut amener un objet TreeWalker à avoir un nœud courant currentNode qui ne serait pas visible sinon dans la vue (logique) filtrée du document. On peut assimiler ce nœud à un « membre éphémère » de cette vue. Quand on demande à l'objet TreeWalker de naviguer hors de ce nœud, c'est comme s'il avait été visible mais qu'on ne puisse pas retourner à lui tant que les conditions n'auront pas changé pour le rendre à nouveau visible.

Notamment, si le nœud courant currentNode devient partie d'un sous-arbre qui aurait été rejeté par le filtre sinon, ce sous-arbre entier peut être ajouté comme membre éphémère de la vue logique. On pourra naviguer dans ce sous-arbre (soumis au filtrage normal) tant qu'on ne va pas en amont de l'ancêtre rejeté. Le comportement est comme si seul le nœud rejeté avait été dépassé (puisqu'on s'est promené dans son sous-arbre) jusqu'à ce qu'on en sorte ; le filtrage normal s'applique ensuite.

1.2. La définition formelle de l'interface

L'interface NodeIterator (introduite dans DOM niveau 2)

Les itérateurs servent à parcourir un ensemble de nœuds, par exemple, l'ensemble de nœuds d'un objet NodeList, le sous-arbre d'un document commandé par un objet Node particulier, le résultat d'une recherche ou tout autre ensemble de nœuds. L'ensemble de nœuds à itérer est déterminé par la mise en œuvre de l'itérateur NodeIterator. Le DOM niveau 2 définit une seule mise en œuvre NodeIterator pour la traversée d'un sous-arbre d'un document, dans l'ordre du document. Les instances de ces itérateurs sont créées en appelant la fonction DocumentTraversal.createNodeIterator().


Définitions IDL
// Introduite dans DOM niveau 2 :
interface NodeIterator {
  readonly attribute Node             root;
  readonly attribute unsigned long    whatToShow;
  readonly attribute NodeFilter       filter;
  readonly attribute boolean          expandEntityReferences;
  Node               nextNode()
                                        raises(DOMException);
  Node               previousNode()
                                        raises(DOMException);
  void               detach();
};

Attributs
expandEntityReferences de type boolean, en lecture seule
La valeur de cet indicateur détermine si les enfants des nœuds d'appel d'entité seront visibles ou non par l'itérateur. Pour la valeur false, ces nœuds enfants et leurs descendants seront rejetés.
Remarquer que le rejet prime sur l'indicateur whatToShow et le filtre. Remarquer également que c'est actuellement la seule situation où un itérateur NodeIterator pourra rejeter un sous-arbre entier au lieu de dépasser des nœuds individuels.

Pour obtenir une vue du document dont les appels d'entité sont résolus mais sans exposer le nœud de l'appel d'entité en question, utilisez les indicateurs whatToShow pour cacher le nœud de référence d'entité et fixez la valeur true à l'attribut expandEntityReferences à la création de l'itérateur. Pour obtenir une vue du document avec des nœuds d'appel d'entité sans résolution des entités, utilisez les indicateurs whatToShow pour exposer le nœud d'appel d'entité et fixez la valeur false à l'attribut expandEntityReferences.
filter de type NodeFilter, en lecture seule
Le filtre NodeFilter utilisé pour trier les nœuds.
root de type Node, en lecture seule
Le nœud racine de l'objet NodeIterator comme défini à sa création.
whatToShow de type unsigned long, en lecture seule
Cet attribut détermine quels types de nœud sont présentés via l'itérateur. Le jeu de constantes disponibles est défini dans l'interface NodeFilter. Les nœuds non acceptés par whatToShow seront dépassés mais leurs enfants peuvent encore être pris en compte. Remarquer que le dépassement prime, le cas échéant, sur le filtre.
Méthodes
detach
Détache l'itérateur NodeIterator de l'ensemble dans lequel il itérait, en libérant toutes les ressources de calcul et en plaçant l'itérateur dans l'état INVALID. Après l'invocation de la méthode detach, les appels des méthodes nextNode ou previousNode soulèveront une exception INVALID_STATE_ERR.
Aucun paramètre
Aucune valeur retournée
Aucune exception
nextNode
Retourne le nœud suivant dans l'ensemble et y avance la position de l'itérateur. Après la création d'un itérateur NodeIterator, le premier appel de la méthode nextNode() retournera le premier nœud dans l'ensemble.
Valeur retournée

Node

L'objet Node suivant dans l'ensemble itéré ou la valeur null s'il n'y a pas d'autre membre dans l'ensemble.

Exceptions

DOMException

INVALID_STATE_ERR : Soulevée si on appelle cette méthode après que la méthode detach a été invoquée.

Aucun paramètre
previousNode
Retourne le nœud précédent dans l'ensemble et y recule la position de l'itérateur NodeIterator.
Valeur retournée

Node

L'objet Node précédent dans l'ensemble itéré ou la valeur null s'il n'y a pas d'autre membre dans l'ensemble.

Exceptions

DOMException

INVALID_STATE_ERR : Soulevée si on appelle cette méthode après que la méthode detach est invoquée.

Aucun paramètre
L'interface NodeFilter (introduite dans DOM niveau 2)

Les filtres sont des objets qui savent trier les nœuds. Si on attribue un filtre NodeFilter à un itérateur NodeIterator, ou à un objet TreeWalker, ce dernier applique le filtre avant de retourner le nœud suivant. Si le filtre indique d'accepter le nœud, la logique de traversée le retourne ; sinon la traversée examine le nœud suivant et fait comme si le nœud rejeté n'était pas là.

Le DOM ne fournit aucun filtre. Le filtre NodeFilter n'est qu'une interface que les utilisateurs peuvent mettre en œuvre afin de créer leurs propres filtres.

Les filtres NodeFilter n'a pas besoin de savoir comment passer d'un nœud à l'autre ni de connaître quoi que ce soit au sujet de la structure de données traversée. Il est donc très facile d'écrire des filtres, puisqu'ils doivent uniquement savoir évaluer un seul nœud. On peut se servir d'un filtre pour plusieurs types de traversée, ce qui favorise un recyclage du code.


Définitions IDL
// Introduite dans DOM niveau 2 :
interface NodeFilter {

  // Les constantes retournées par l'attribut acceptNode
  const short               FILTER_ACCEPT                  = 1;
  const short               FILTER_REJECT                  = 2;
  const short               FILTER_SKIP                    = 3;


  // Les constantes de l'attribut whatToShow
  const unsigned long       SHOW_ALL                       = 0xFFFFFFFF;
  const unsigned long       SHOW_ELEMENT                   = 0x00000001;
  const unsigned long       SHOW_ATTRIBUTE                 = 0x00000002;
  const unsigned long       SHOW_TEXT                      = 0x00000004;
  const unsigned long       SHOW_CDATA_SECTION             = 0x00000008;
  const unsigned long       SHOW_ENTITY_REFERENCE          = 0x00000010;
  const unsigned long       SHOW_ENTITY                    = 0x00000020;
  const unsigned long       SHOW_PROCESSING_INSTRUCTION    = 0x00000040;
  const unsigned long       SHOW_COMMENT                   = 0x00000080;
  const unsigned long       SHOW_DOCUMENT                  = 0x00000100;
  const unsigned long       SHOW_DOCUMENT_TYPE             = 0x00000200;
  const unsigned long       SHOW_DOCUMENT_FRAGMENT         = 0x00000400;
  const unsigned long       SHOW_NOTATION                  = 0x00000800;

  short              acceptNode(in Node n);
};

Groupe de définition Constantes retournées par acceptNode

La méthode acceptNode() retourne les constantes suivantes :

Constantes définies
FILTER_ACCEPT
Accepte le nœud. Les méthodes de navigation définies pour les itérateurs NodeIterator ou les objets TreeWalker retourneront le nœud.
FILTER_REJECT
Rejette le nœud . Les méthodes de navigation définies pour les itérateurs NodeIterator ou les objets TreeWalker ne retourneront pas le nœud. En ce qui concerne les objets TreeWalker, les enfants du nœud seront également rejetés. Les itérateurs NodeIterator traitent cette valeur comme un synonyme de la valeur FILTER_SKIP.
FILTER_SKIP
Dépasse ce seul nœud. Les méthodes de navigation définies pour les itérateurs NodeIterator ou les objets TreeWalker ne retourneront pas le nœud. Pour les itérateurs NodeIterator et les objets TreeWalker, les enfants du nœud seront toutefois pris en compte.
Groupe de définition Constantes pour whatToShow

Voici les valeurs admissibles du paramètre whatToShow utilisé avec les objets TreeWalker et les itérateurs NodeIterator. Ce sont les mêmes que celles du jeu de types possibles de l'objet Node et leurs valeurs sont dérivées en utilisant une position de bit correspondant à la valeur de l'attribut nodeType du type de nœud équivalent. Si on fixe un bit dans whatToShow à false, cela sera considéré comme une requête pour dépasser ce type de nœud ; le comportement dans ce cas est similaire à celui pour la valeur FILTER_SKIP.

Remarquer que si on devait un jour introduire des types de nœud supérieurs à 32, ils ne seraient alors plus testables individuellement via whatToShow. Si le besoin se faisait sentir, on pourrait le gérer en séletionnant la valeur SHOW_ALL et en utilisant un filtre NodeFilter approprié.

Constantes définies
SHOW_ALL
Expose tous les objets Node.
SHOW_ATTRIBUTE
Expose les nœuds Attr. Cela n'a de sens que pour la création d'un itérateur ou d'un objet TreeWalker dont la racine est un nœud d'attribut ; auquel cas, le nœud d'attribut apparaîtra en première position dans l'itération ou la traversée. Puisque les attributs ne sont jamais les enfants d'autres nœuds, ils n'apparaissent pas au cours de la traversée de l'arbre du document.
SHOW_CDATA_SECTION
Expose les nœuds CDATASection.
SHOW_COMMENT
Expose les nœuds Comment.
SHOW_DOCUMENT
Expose les nœuds Document.
SHOW_DOCUMENT_FRAGMENT
Expose les nœuds DocumentFragment.
SHOW_DOCUMENT_TYPE
Expose les nœuds DocumentType.
SHOW_ELEMENT
Expose les nœuds Element.
SHOW_ENTITY
Expose les nœuds Entity. Cela n'a de sens que pour la création d'un itérateur ou d'un objet TreeWalker dont la racine est un nœud Entity ; auquel cas, le nœud apparaîtra en première position de la traversée. Puisque les entités ne font pas partie de l'arbre du document, ils n'apparaissent pas au cours de sa traversée.
SHOW_ENTITY_REFERENCE
Expose les nœuds EntityReference.
SHOW_NOTATION
Expose les nœuds Notation. Cela n'a de sens que pour la création d'un itérateur d'un objet TreeWalker dont la racine est un nœud Notation ; auquel cas, le nœud Notation apparaîtra en première position de la traversée. Puisque les notations ne font pas partie de l'arbre du document, ils n'apparaissent pas au cours de sa traversée.
SHOW_PROCESSING_INSTRUCTION
Expose les nœuds ProcessingInstruction.
SHOW_TEXT
Expose les nœuds Text.
Méthodes
acceptNode
Teste si le nœud indiqué est visible ou non dans la vue logique d'un objet TreeWalker ou d'un itérateur NodeIterator. Cette fonction sera appelée par la mise en œuvre TreeWalker ou NodeIterator ; elle est normalement appelée directement depuis le code de l'utilisateur. (Quoiqu'on puisse le faire de cette façon, si on souhaite employer le même filtre pour guider sa propre logique d'application).
Paramètres
n de type Node
Le nœud à examiner afin de vérifier s'il passe le filtre ou non.
Valeur retournée

short

Une constante pour déterminer si le nœud est accepté, rejeté ou dépassé, comme défini précédemment.

Aucune exception
L'interface TreeWalker (introduite dans DOM niveau 2)

Les objets TreeWalker servent à naviguer dans l'arbre, ou un sous-arbre, d'un document en utilisant la vue du document définie par leurs indicateurs whatToShow et, le cas échéant, leurs filtres. Une fonction effectuant une navigation avec un objet TreeWalker reconnaîtra automatiquement n'importe quelle vue définie par un objet TreeWalker.

L'omission de nœuds dans la vue logique d'un sous-arbre peut se traduire par une structure qui diffère significativement du même sous-arbre dans le document complet non filtré. Les nœuds frères dans la vue de l'objet TreeWalker peuvent être les enfants de nœuds distincts très éloignés dans la vue originale. Par exemple, prenons un filtre NodeFilter qui dépassent tous les nœuds sauf les nœuds Text et le nœud racine d'un document. Dans la vue logique finale, tous les nœuds Text seront frères et apparaîtront comme enfants du nœud racine, quelle que soit leur profondeur d'imbrication dans la structure du document original.


Définitions IDL
// Introduite dans DOM niveau 2 :
interface TreeWalker {
  readonly attribute Node             root;
  readonly attribute unsigned long    whatToShow;
  readonly attribute NodeFilter       filter;
  readonly attribute boolean          expandEntityReferences;
           attribute Node             currentNode;
                      // soulève une exception DOMException à l'initialisation

  Node               parentNode();
  Node               firstChild();
  Node               lastChild();
  Node               previousSibling();
  Node               nextSibling();
  Node               previousNode();
  Node               nextNode();
};

Attributs
currentNode de type Node
Le nœud où l'objet TreeWalker est actuellement positionné.
Les altérations de l'arbre DOM peuvent entraîner que le filtre associé à l'objet TreeWalker n'accepte plus le nœud courant. On peut fixer explicitement le nœud courant currentNode sur tout autre nœud, qu'il soit ou non dans le sous-arbre défini par le nœud racine, ou qu'il soit accepté ou non par le filtre et les indicateurs whatToShow. Les traversées ultérieures adviennent relativement au nœud courant currentNode, même s'il ne fait pas partie de la vue courante, en appliquant les filtres dans la direction demandée ; si aucune traversée n'est possible, l'attribut le nœud courant currentNode ne change pas.
Exceptions à l'initialisation

DOMException

NOT_SUPPORTED_ERR : Soulevée si on essaye de donner à l'attribut currentNode la valeur null.

expandEntityReferences de type boolean, en lecture seule
La valeur de cet indicateur détermine si les enfants des nœuds d'appels d'entité sont visibles, ou non, pour l'objet TreeWalker. Pour une valeur false, ces nœuds enfants et leurs descendants seront rejetés.
Remarquer que ce rejet prime sur l'attribut whatToShow et, le cas échéant, le filtre.
Pour obtenir une vue du document dont les appels d'entité sont résolus sans exposer le nœud de l'appel d'entité en question, utiliser les indicateurs whatToShow le pour cacher et fixer la valeur de l'attribut expandEntityReferences à true à la création de l'objet TreeWalker. Pour produire une vue du document avec des nœuds d'appels d'entité sans résolution des entités, utiliser les indicateurs whatToShow pour exposer le nœude d'appel d'entité et fixer la valeur de expandEntityReferences à false.
filter de type NodeFilter, en lecture seule
Le filtre utilisé pour trier les nœuds.
root de type Node, en lecture seule
Le nœud racine de l'objet TreeWalker, comme défini à sa création.
whatToShow de type unsigned long, en lecture seule
Cet attribut détermine quels types de nœud seront exposés via l'objet TreeWalker. Le jeu de constantes disponibles est défini dans l'interface NodeFilter. Les nœuds non acceptés par l'attribut whatToShow seront dépassés toutefois leurs enfants seront pris en compte. Remarquer que ce dépassement prime, le cas échéant, sur le filtre.
Méthodes
firstChild
Déplace l'objet TreeWalker au premier enfant visible du nœud courant et retourne le nouveau nœud. Si le nœud courant n'a pas d'enfant visible, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si le nœud courant n'a aucun enfant visible dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
lastChild
Déplace l'objet TreeWalker au dernier enfant visible du nœud courant et retourne le nouveau œud. Si le nœud courant n'a pas d'enfant visible, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si le nœud courant n'a aucun enfant visible dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
nextNode
Déplace l'objet TreeWalker au nœud visible suivant dans l'ordre du document relativement au nœud courant et retourne le nouveau nœud. Si aucun nœud ne suit le nœud courant, ou si la recherche de la méthode nextNode essaye d'aller en amont du nœud racine de l'objet TreeWalker, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si aucun nœud ne suit le nœud courant dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
nextSibling
Déplace l'objet TreeWalker au frère suivant du nœud courant et retourne le nouveau nœud. Si aucun frère visible ne suit le nœud courant, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si aucun frère ne suit le nœud courant dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
parentNode
Déplace l'objet TreeWalker au nœud ancêtre visible le plus proche du nœud courant et retourne cet ancêtre. Si la recherche de la méthode parentNode essaye d'aller en amont du nœud racine de l'objet TreeWalker ou si elle échoue à trouver un nœud ancêtre visible, cette méthode retient la position courante et retourne la valeur null.
Valeur retournée

Node

Le nouveau nœud parent ou la valeur null si le nœud courant n'a aucun parent dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
previousNode
Déplace l'objet TreeWalker au nœud visible précédent dans l'ordre du document relativement au nœud courant et retourne le nouveau nœud. Si aucun nœud ne précède le nœud courant, ou si la recherche de previousNode essaye d'aller en amont du nœud racine de l'objet TreeWalker, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si aucun nœud ne précède le nœud courant dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
previousSibling
Déplace l'objet TreeWalker au frère précédent du nœud courant et retourne le nouveau nœud. Si aucun frère visible ne précède le nœud courant, retourne la valeur null et conserve le nœud courant.
Valeur retournée

Node

Le nouveau nœud ou la valeur null si aucun frère ne précède le nœud courant dans la vue logique de l'objet TreeWalker.

Aucun paramètre
Aucune exception
L'interface DocumentTraversal (introduite dans DOM niveau 2)

L'interface DocumentTraversal contient des méthodes permettant de créer des itérateurs et des objets TreeWalker pour la traversée d'un nœud et ses enfants dans l'ordre du document (c'est-à-dire, une traversée préordonnée en profondeur d'abord, qui équivaut à l'ordre d'apparition des balises ouvrantes dans la représentation textuelle du document). Dans les mises en œuvre DOM reconnaissant la fonctionnalité "Traversal", l'interface DocumentTraversal sera mise en œuvre par les mêmes objets que ceux pour l'interface Document.


Définitions IDL
// Introduite dans DOM niveau 2 :
interface DocumentTraversal {
  NodeIterator       createNodeIterator(in Node root, 
                                        in unsigned long whatToShow, 
                                        in NodeFilter filter, 
                                        in boolean entityReferenceExpansion)
                                        raises(DOMException);
  TreeWalker         createTreeWalker(in Node root, 
                                      in unsigned long whatToShow, 
                                      in NodeFilter filter, 
                                      in boolean entityReferenceExpansion)
                                        raises(DOMException);
};

Méthodes
createNodeIterator
Crée un nouvel itérateur NodeIterator en amont du sous-arbre qui prend racine au nœud indiqué.
Paramètres
root de type Node
Le nœud à itérer et ses enfants. L'itérateur est initialement positionné juste avant ce nœud. Les indicateurs whatToShow et, le cas échéant, le filtre ne sont pas pris en compte au paramétrage de cette position. La racine ne doit pas avoir la valeur null.
whatToShow de type unsigned long
Cet indicateur indique quels types de nœud peut apparaître dans la vue logique de l'arbre présenté par l'itérateur. Cf. la description du filtre NodeFilter pour le jeu des valeurs possibles SHOW_xxx.
On peut combiner ces indicateurs avec l'opérateur OR.
filter de type NodeFilter
Le filtre NodeFilter à utiliser avec cet objet TreeWalker NodeIterator ou la valeur null pour ne pas indiquer de filtre.
entityReferenceExpansion de type boolean
La valeur de cet indicateur détermine si les nœuds des appels d'entité sont résolus ou non.
Valeur retournée

NodeIterator

L'itérateur NodeIterator nouvellement créé.

Exceptions

DOMException

NOT_SUPPORTED_ERR : Soulevée si l'attribut root indiqué a la valeur null.

createTreeWalker
Crée un nouvel objet TreeWalker en amont du sous-arbre qui prend racine au nœud indiqué.
Paramètres
root de type Node
Le nœud qui servira de racine pour l'objet TreeWalker. Les indicateurs whatToShow et le filtre NodeFilter ne sont pas pris en compte au paramétrage de cette valeur ; tout type de nœud sera accepté comme racine. L'attribut currentNode de l'objet TreeWalker indique ce nœud, qu'il soit visible ou non. La racine a une fonction de point d'arrêt pour les méthodes de traversée remontant dans la structure du document, telles que les méthodes parentNode et nextNode. La valeur de l'attribut root ne doit pas être null.
whatToShow de type unsigned long
Cet indicateur indique les types de nœud qui peuvent apparaître dans la vue logique de l'arbre présentée par l'objet TreeWalker. Cf. la description du filtre NodeFilter pour le jeu des valeurs possibles SHOW_xxx.
On peut combiner ces indicateurs en utilisant l'opérateur OR.
filter de type NodeFilter
Le filtre NodeFilter à utiliser avec cet objet TreeWalker ou la valeur null pour aucun filtre.
entityReferenceExpansion de type boolean
Si la valeur de cet indicateur est false, le contenu des nœuds EntityReference n'est pas présenté dans la vue logique.
Valeur retournée

TreeWalker

L'objet TreeWalker nouvellement créé.

Exceptions

DOMException

NOT_SUPPORTED_ERR : Soulevée si l'attribut root indiqué a la valeur null.