This chapter describes the optional DOM Level 2 Traversal feature. Its
TreeWalker, NodeIterator, and Filter interfaces provide easy-to-use, robust,
selective traversal for document nodes. A DOM application can use the
hasFeature
method of the DOMImplementation
interface
to determine whether they are supported or not. The feature string for all the
interfaces listed in this section is "Traversal". Iterators and TreeWalkers are
two different ways of representing the nodes of a document subtree and a
position within the nodes they present. A NodeIterator presents a flattened
view of the subtree as an ordered sequence of document nodes, presented in
document order. Because this view is presented without respect to hierarchy,
iterators have methods to move forward and backward, but not to move up and
down. A TreeWalker maintains the hierarchical relationships of the subtree,
allowing navigation of this hierarchy. In general, TreeWalkers are better for
tasks in which the structure of the document around selected nodes will be
manipulated, while iterators are better for tasks that focus on the content of
each selected node.
Iterators and TreeWalkers each present a view of a document subtree that may not contain all nodes found in the subtree. In this specification, we refer to this as the logical view to distinguish it from the physical view, which corresponds to the document subtree per se. When an iterator or TreeWalker is created, it may be associated with a Filter, which examines a node and determines whether it should appear in the logical view. In addition, flags may be used to specify which node types should occur in the logical view.
Iterators and TreeWalkers are dynamic - the logical view changes to reflect changes made to the underlying document. However, they differ in how they respond to those changes. NodeIterators, which present the nodes sequentially, attempt to maintain their location relative to a position in that sequence when the sequence's contents change. TreeWalkers, which present the nodes as a filtered tree, maintain their location relative to their current node, and remain attached to that node if it is moved to a new context. We will discuss these behaviors in greater detail below.
An iterator allows the members of a list of nodes to be returned
sequentially. In the current DOM interfaces, this list will always consist of
the nodes of a subtree, presented in document order. When an iterator is first
created, calling nextNode() returns the first node in the logical view of the
subtree; in most cases, this is the root of the subtree. When no more nodes are
present, nextNode() returns null
.
Iterators are created using the createNodeIterator method found in the
DocumentTraversal
interface. When a NodeIterator is created, flags
can be used to determine which node types will be "visible" and which nodes
will be "invisible" while traversing the tree; these flags can be combined
using the OR operator. Nodes that are "invisible" are skipped over by the
iterator as though they did not exist. The following code creates an iterator,
then calls a function to print the name of each element:
NodeIterator iter=((DocumentTraversal)document).createNodeIterator(root, NodeFilter.SHOW_ELEMENT, null); while (Node n = iter.nextNode()) printMe(n);
Iterators present nodes as an ordered list, and move forward and backward within this list. The iterator's position is always between two nodes, before the first node, or after the last node. When an iterator is first created, the position is set before the first item. The following diagram shows the list view that an iterator might provide for a particular subtree, with the position indicated by an asterisk '*' :
* A B C D E F G H I
Each call to nextNode() returns the next node and advances the position. For instance, if we start with the above position, the first call to nextNode() returns "A" and advances the iterator:
[A] * B C D E F G H I
The position of an iterator can best be described with respect to the last node returned, which we will call the reference node. When an iterator is created, the first node is the reference node, and the iterator is positioned before the reference node. In these diagrams, we use square brackets to indicate the reference node.
A call to previousNode() returns the previous node and moves the position backward. For instance, if we start with the iterator between "A" and "B", it would return "A" and move to the position shown below:
* [A] B C D E F G H I
If nextNode() is called at the end of a list, or previousNode() is
called at the beginning of a list, it returns null
and does not
change the position of the iterator. When an iterator is first created, the
reference node is the first node:
* [A] B C D E F G H I
An iterator may be active while the data structure it navigates is being edited, so an iterator must behave gracefully in the face of change. Additions and removals in the underlying data structure do not invalidate an iterator; in fact, an iterator is never invalidated unless its detach() method is invoked. To make this possible, the iterator uses the reference node to maintain its position. The state of an iterator also depends on whether the iterator is positioned before or after the reference node. If the reference node is removed, another node becomes the reference node.
If changes to the iterated list do not remove the reference node, they do not affect the state of the iterator. For instance, the iterator's state is not affected by inserting new nodes in the vicinity of the iterator or removing nodes other than the reference node. Suppose we start from the following position:
A B C [D] * E F G H I
Now let's remove "E". The resulting state is:
A B C [D] * F G H I
If a new node is inserted, the iterator stays close to the reference node, so if a node is inserted between "D" and "F", it will occur between the iterator and "F":
A B C [D] * X F G H I
Moving a node is equivalent to a removal followed by an insertion. If we move "I" to the position before "X" the result is:
A B C [D] * I X F G H
If the reference node is removed, a different node is selected as the reference node. If the reference node is before the iterator, which is usually the case after nextNode() has been called, the nearest node before the iterator is chosen as the new reference node. Suppose we remove the "D" node, starting from the following state:
A B C [D] * F G H I
The "C" node becomes the new reference node, since it is the nearest node to the iterator that is before the iterator:
A B [C] * F G H I
If the reference node is after the iterator, which is usually the case after previousNode() has been called, the nearest node after the iterator is chosen as the new reference node. Suppose we remove "E", starting from the following state:
A B C D * [E] F G H I
The "F" node becomes the new reference node, since it is the nearest node to the iterator that is after the iterator:
A B C D * [F] G H I
Moving a node is equivalent to a removal followed by an insertion. Suppose we wish to move the "D" node to the end of the list, starting from the following state:
A B C [D] * F G H I C
The resulting state is as follows:
A B [C] * F G H I D
One special case arises when the reference node is the last node in the list and the reference node is removed. Suppose we remove node "C", starting from the following state:
A B * [C]
According to the rules we have given, the new reference node should be the nearest node after the iterator, but there are no further nodes after "C". The same situation can arise when previousNode() has just returned the first node in the list, which is then removed. Hence: If there is no node in the original direction of the reference node, the nearest node in the opposite direction is selected as the reference node:
A [B] *
If the iterator is positioned within a block of nodes that is removed, the above rules clearly indicate what is to be done. For instance, suppose "C" is the parent node of "D", "E", and "F", and we remove "C", starting with the following state:
A B C [D] * E F G H I D
The resulting state is as follows:
A [B] * G H I D
The underlying data structure that is being iterated may contain nodes that are not part of the logical view, and therefore will not be returned by the iterator. If invisible nodes are present, nextNode() returns the next visible node, skipping over nodes that are to be excluded because of the value of the whatToShow flag. If a filter is present, it is applied before returning a node; if the filter does not accept the node, the process is repeated until a node is accepted by the filter. That node is returned. If no visible nodes are encountered, a null is returned and the iterator is positioned at the end of the list. In this case, the reference node is the last node in the list, whether or not it is visible. The same approach is taken, in the opposite direction, for previousNode().
In the following examples, we will use lowercase letters to represent nodes that are in the data structure, but which are not in the logical view. For instance, consider the following list:
A [B] * c d E F G
A call to nextNode() returns E and advances to the following position:
A B c d [E] * F G
Nodes that are not visible may nevertheless be used as reference nodes if a reference node is removed. Suppose node "E" is removed, started from the state given above. The resulting state is:
A B c [d] * F G
Suppose a new node "X", which is visible, is inserted before "d". The resulting state is:
A B c X [d] * F G
Note that a call to previousNode() now returns node X. It is important not to skip over invisible nodes when the reference node is removed, because there are cases, like the one just given above, where the wrong results will be returned. When "E" was removed, if the new reference node had been "B" rather than "d", calling previousNode() would not return "X".
Filters allow the user to create objects that "filter out" nodes. Each filter contains a user-written function that looks at a node and determines whether or not it should be filtered out. To use a filter, you create a NodeIterator or a TreeWalker that uses the filter. The Iterator or TreeWalker applies the filter to each node, and if the filter does not accept the node, the iterator or TreeWalker skips over the node as though it were not present in the document. Filters need not know how to navigate the structure that contains the nodes on which they operate.
Filters will be consulted when a traversal operation is performed, or when a NodeIterator's reference node is removed from the subtree being iterated over and it must select a new one. However, the exact timing of these filter calls may vary from one DOM implementation to another. For that reason, filters should not attempt to maintain state based on the history of past invocations; the resulting behavior may not be portable.
Similarly, TreeWalkers and NodeIterators should behave as if they have no memory of past filter results, and no anticipation of future results. If the conditions a filter is examining have changed (e.g., an attribute which it tests has been added or removed) since the last time the traversal logic examined this node, this change in visibility will be discovered only when the next traversal operation is performed. For example: if the filtering for the current node changes from FILTER_SHOW to FILTER_SKIP, a TreeWalker will be able to navigate off that node in any direction, but not back to it unless the filtering conditions change again. Filters which change during a traversal can be written, but their behavior may be confusing and they should be avoided when possible.
A Filter contains one method named acceptNode(), which allows an iterator or TreeWalker to pass a Node to a filter and ask whether it should be present in the logical view. The acceptNode() function returns one of three values to state how the Node should be treated. If acceptNode() returns FILTER_ACCEPT, the Node will be present in the logical view; if it returns FILTER_SKIP, the Node will not be present in the logical view, but the children of the Node may; if it returns FILTER_REJECT, neither the Node nor its descendants will be present in the logical view. Since iterators present nodes as an ordered list, without hierarchy, FILTER_REJECT and FILTER_SKIP are synonyms for iterators, skipping only the single current node.
Consider a filter that accepts the named anchors in an HTML document. In HTML, an HREF can refer to any A element that has a NAME attribute. Here is a filter in Java that looks at a node and determines whether it is a named anchor:
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; } }
If the above Filter were to be used only with NodeIterators, it could have used FILTER_REJECT wherever FILTER_SKIP is used, and the behavior would not change. For TreeWalker, though, FILTER_REJECT would reject the children of any element that is not a named anchor, and since named anchors are always contained within other elements, this would have meant that no named anchors would be found. FILTER_SKIP rejects the given node, but continues to examine the children; therefore, the above filter will work with either a NodeIterator or a TreeWalker.
To use this filter, the user would create an instance of the filter and create an iterator using it:
NamedAnchorFilter myFilter = new NamedAnchorFilter(); NodeIterator iter=((DocumentTraversal)document).createNodeIterator(node, NodeFilter.SHOW_ELEMENT, myFilter);
Note that the use of the SHOW_ELEMENT flag is not strictly necessary in this example, since our sample Filter tests the nodeType. However, some implementations of the Traversal interfaces may be able to improve whatToShow performance by taking advantage of knowledge of the document's structure, which makes the use of SHOW_ELEMENT worthwhile. Conversely, while we could remove the nodeType test from our Filter, that would make it dependent upon whatToShow to distinguish between Elements, Attr's, and ProcessingInstructions.
When writing a Filter, users should avoid writing code that can throw an exception. However, because an implementation can not prevent users from doing so, it is important that the behavior of filters that throw an exception be well-defined. A TreeWalker or NodeIterator does not catch or alter an exception thrown by a filter, but lets it propagate up to the user's code. The following functions may invoke a Filter, and may therefore propagate an exception if one is thrown by a Filter:
Well-designed Filters do not modify the underlying document structure, but a Filter implementation can not prevent a user from writing code that does modify the document structure. Filters do not provide any special processing to handle this case. For instance, if a Filter removes a node from a document, it can still accept the node, which means that the node may be returned by the NodeIterator or TreeWalker even though it is no longer in the document. In general, this may lead to inconsistent, confusing results, so we encourage users to write Filters that make no changes to document structures.
Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is skipped by the active whatToShow flags, a Filter will not be called to evaluate that node. Please note that this behavior is similar to that of FILTER_SKIP; children of that node will be considered, and Filters may be called to evaluate them. Also note that it will in fact be a "skip" even if the Filter would have preferred to reject the entire subtree; if this would cause a problem in your application, consider setting whatToShow to SHOW_ALL and performing the nodeType test inside your filter.
The TreeWalker
interface provides many of the same benefits as
the NodeIterator interface. The main difference between these two interfaces is
that the TreeWalker
presents a tree-oriented view of the nodes in
a subtree, and an iterator presents a list-oriented view. In other words, an
iterator allows you to move forward or back, but a TreeWalker
allows you to move to the parent of a node, to one of its children, or to a
sibling.
Using a TreeWalker
is quite similar to navigation using the
Node directly, and the navigation methods for the two interfaces are analogous.
For instance, here is a function that walks over a tree of nodes in document
order, taking separate actions when first entering a node and after processing
any children:
processMe(Node n) { nodeStartActions(n); for (Node child=n.firstChild(); child != null; child=child.nextSibling()) processMe(child); } nodeEndActions(n); }
Doing the same thing using a TreeWalker
is quite similar. There
is one difference: since navigation on the TreeWalker
changes the
current position, the position at the end of the function has changed. A
read/write attribute named currentNode
allows the current node for
a TreeWalker
to be set. We will use this to ensure that the
position of the TreeWalker
is restored when this function is
completed:
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); }
The advantage of using a TreeWalker
instead of direct Node
navigation is that the TreeWalker
allows the user to choose an
appropriate view of the tree. Flags may be used to show or hide comments or
processing instructions, entities may be expanded or left as entity references.
In addition, Filters may be used to present a custom view of the tree. Suppose
a program needs a view of a document that shows which tables occur in each
chapter, listed by chapter. In this view, only the chapter elements and the
tables that they contain are seen. The first step is to write an appropriate
filter:
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; } }
This filter assumes that TABLE elements are contained directly in CHAPTER or SECTn elements. If another kind of element is encountered, it and its children are rejected. If a SECTn element is encountered, it is skipped, but its children are explored to see if they contain any TABLE elements.
Now the program can create an instance of this Filter, create a
TreeWalker
that uses it, and pass this TreeWalker
to
our ProcessMe() function:
TablesInChapters tablesInChapters = new TablesInChapters(); TreeWalker tw = ((DocumentTraversal)document).createTreeWalker(root, NodeFilter.SHOW_ELEMENT, tablesInChapters); processMe(tw);
(Again, we've chosen to both test the nodeType in the filter's logic and use SHOW_ELEMENT, for the reasons discussed in the earlier NodeIterator example.)
Without making any changes to the above ProcessMe() function, it now
processes only the CHAPTER and TABLE elements. The programmer can write other
filters or set other flags to choose different sets of nodes; if functions use
TreeWalker
to navigate, they will support any view of the document
defined with a TreeWalker
.
Note that the structure of a TreeWalker
's filtered view of a
document may differ significantly from that of the document itself. For
example, a TreeWalker
with only SHOW_TEXT specified in its
whatToShow parameter would present all the Text Nodes as if they were siblings
of each other yet had no parent.
As with iterators, a TreeWalker
may be active while the data
structure it navigates is being edited, and must behave gracefully in the face
of change. Additions and removals in the underlying data structure do not
invalidate a TreeWalker
; in fact, a TreeWalker
is
never invalidated.
But a TreeWalker
's response to these changes is quite different
from that of a NodeIterator
. While NodeIterator
s
respond to editing by maintaining their position within the subtree that they
are iterating over, TreeWalker
s will instead remain attached to
their currentNode. All the TreeWalker
's navigation methods operate
in terms of the context of the currentNode at the time they are invoked, no
matter what has happened to, or around, that node since the last time the
TreeWalker
was accessed. This remains true even if the currentNode
is moved out of its original subtree.
As an example, consider the following document fragment:
... <subtree> <twRoot> <currentNode/> <anotherNode/> </twRoot> </subtree> ...
Let's say we have created a TreeWalker
whose root node is the
<twRoot/> element and whose currentNode is the <currentNode/>
element. For this illustration, we will assume that all the nodes shown above
are accepted by the TreeWalker
's whatToShow and filter
settings.
If we use removeChild() to remove the <currentNode/> element from its
parent, that element remains the TreeWalker
's currentNode, even
though it is no longer within the root node's subtree. We can still use the
TreeWalker
to navigate through any children that the orphaned
currentNode may have, but are no longer able to navigate outward from the
currentNode since there is no parent available.
If we use insertBefore() or appendChild() to give the <currentNode/> a
new parent, then TreeWalker
navigation will operate from the
currentNode's new location. For example, if we inserted the <currentNode>
immediately after the <anotherNode/> element, the
TreeWalker
's previousSibling() operation would move it back to the
<anotherNode/>, and calling parentNode() would move it up to the
<twRoot/>.
If we instead insert the currentNode into the <subtree/> element, like so:
... <subtree> <currentNode/> <twRoot> <anotherNode/> </twRoot> </subtree> ...
we have moved the currentNode out from under the TreeWalker
's
root node. This does not invalidate the TreeWalker; it may still be used to
navigate relative to the currentNode. Calling its parentNode() operation, for
example, would move it to the <subtree/> element, even though that too is
outside the original root node. However, if the TreeWalker's navigation should
take it back into the original root node's subtree -- for example, if rather
than calling parentNode() we called nextNode(), moving the TreeWalker to the
<twRoot/> element -- the root node will "recapture" the TreeWalker, and
prevent it from traversing back out.
This becomes a bit more complicated when filters are in use. Relocation of the currentNode -- or explicit selection of a new currentNode, or changes in the conditions that the filter is basing its decisions on -- can result in a TreeWalker having a currentNode which would not otherwise be visible in the filtered view of the document. This node can be thought of as a "transient member" of that view. When you ask the TreeWalker to navigate off this node the result will be just as if it had been visible, but you may be unable to navigate back to it unless conditions change to make it visible again.
In particular: If the currentNode becomes part of a subtree that would otherwise have been Rejected by the filter, that entire subtree may be added as transient members of the logical view. You will be able to navigate within that subtree (subject to all the usual filtering) until you move upward past the Rejected ancestor. The behavior is as if the Rejected node had only been Skipped (since we somehow wound up inside its subtree) until we leave it; thereafter, standard filtering applies.
NodeIterators are used to step through a set of nodes, e.g. the set of nodes in a NodeList, the document subtree governed by a particular node, the results of a query, or any other set of nodes. The set of nodes to be iterated is determined by the implementation of the NodeIterator. DOM Level 2 specifies a single NodeIterator implementation for document-order traversal of a document subtree. Instances of these iterators are created by calling DocumentTraversal.createNodeIterator().
// Introduced in DOM Level 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(); };
expandEntityReferences
of type boolean
, readonly
filter
of type NodeFilter
, readonly
root
of type Node
, readonly
whatToShow
of type unsigned long
, readonlyNodeFilter
interface.
Nodes not accepted by whatToShow will be skipped, but their children may still
be considered. Note that this skip takes precedence over the filter, if any.
detach
detach
has been invoked, calls to nextNode
or
previousNode
will raise the exception INVALID_STATE_ERR.nextNode
INVALID_STATE_ERR: Raised if this method is called after the
|
previousNode
INVALID_STATE_ERR: Raised if this method is called after the
|
Filters are objects that know how to "filter out" nodes. If a
NodeIterator
or TreeWalker
is given a filter, it
applies the filter before it returns the next node. If the filter says to
accept the node, the iterator returns it; otherwise, the iterator looks for the
next node and pretends that the node that was rejected was not there.
The DOM does not provide any filters. Filter is just an interface that users can implement to provide their own filters.
Filters do not need to know how to iterate, nor do they need to know anything about the data structure that is being iterated. This makes it very easy to write filters, since the only thing they have to know how to do is evaluate a single node. One filter may be used with a number of different kinds of iterators, encouraging code reuse.
Note: This is an ECMAScript function reference. This method returns a
short
. The parameter is of type Node
.
// Introduced in DOM Level 2: interface NodeFilter { // Constants returned by acceptNode const short FILTER_ACCEPT = 1; const short FILTER_REJECT = 2; const short FILTER_SKIP = 3; // Constants for 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); };
The following constants are returned by the acceptNode() method:
FILTER_ACCEPT |
Accept the node. Navigation methods defined for NodeIterator or
TreeWalker will return this node. |
FILTER_REJECT |
Reject the node. Navigation methods defined for NodeIterator or
TreeWalker will not return this node. For TreeWalker ,
the children of this node will also be rejected. Iterators treat this as a
synonym for FILTER_SKIP. |
FILTER_SKIP |
Skip this single node. Navigation methods defined for
NodeIterator or TreeWalker will not return this node.
For both NodeIterator and Treewalker, the children of this node will still be
considered. |
These are the available values for the whatToShow parameter used in TreeWalkers and Iterators. They are the same as the set of possible types for Node, and their values are derived by using a bit position corresponding to the value of Node.nodeType for the equivalent node type. If a bit in whatToShow is set false, that will be taken as a request to skip over this type of node; the behavior in that case is similar to that of FILTER_SKIP.
Note that if node types greater than 32 are ever introduced, they may not be individually testable via whatToShow. If that need should arise, it can be handled by selecting SHOW_ALL together with an appropriate NodeFilter.
SHOW_ALL | Show all nodes. |
SHOW_ATTRIBUTE | Show attribute nodes. This is meaningful only when creating an iterator or tree-walker with an attribute node as its root; in this case, it means that the attribute node will appear in the first position of the iteration or traversal. Since attributes are not part of the document tree, they do not appear when traversing over the document tree. |
SHOW_CDATA_SECTION | Show CDATASection nodes. |
SHOW_COMMENT | Show Comment nodes. |
SHOW_DOCUMENT | Show Document nodes. |
SHOW_DOCUMENT_FRAGMENT | Show DocumentFragment nodes. |
SHOW_DOCUMENT_TYPE | Show DocumentType nodes. |
SHOW_ELEMENT | Show element nodes. |
SHOW_ENTITY | Show Entity nodes. This is meaningful only when creating an iterator or tree-walker with an Entity node as its root; in this case, it means that the Entity node will appear in the first position of the traversal. Since entities are not part of the document tree, they do not appear when traversing over the document tree. |
SHOW_ENTITY_REFERENCE | Show Entity Reference nodes. |
SHOW_NOTATION | Show Notation nodes. This is meaningful only when creating an iterator or tree-walker with a Notation node as its root; in this case, it means that the Notation node will appear in the first position of the traversal. Since notations are not part of the document tree, they do not appear when traversing over the document tree. |
SHOW_PROCESSING_INSTRUCTION | Show ProcessingInstruction nodes. |
SHOW_TEXT | Show text nodes. |
acceptNode
| The node to check to see if it passes the filter or not. |
|
a constant to determine whether the node is accepted, rejected, or skipped, as defined above. |
TreeWalker
objects are used to navigate a document tree or
subtree using the view of the document defined by its whatToShow
flags and any filters that are defined for the TreeWalker
. Any
function which performs navigation using a TreeWalker
will
automatically support any view defined by a TreeWalker
.
Omitting nodes from the logical view of a subtree can result in a structure that is substantially different from the same subtree in the complete, unfiltered document. Nodes that are siblings in the TreeWalker view may be children of different, widely separated nodes in the original view. For instance, consider a Filter that skips all nodes except for Text nodes and the root node of a document. In the logical view that results, all text nodes will be siblings and appear as direct children of the root node, no matter how deeply nested the structure of the original document.
// Introduced in DOM Level 2: interface TreeWalker { readonly attribute Node root; readonly attribute unsigned long whatToShow; readonly attribute NodeFilter filter; readonly attribute boolean expandEntityReferences; attribute Node currentNode; // raises(DOMException) on setting Node parentNode(); Node firstChild(); Node lastChild(); Node previousSibling(); Node nextSibling(); Node previousNode(); Node nextNode(); };
currentNode
of type Node
NOT_SUPPORTED_ERR: Raised if the specified |
expandEntityReferences
of type boolean
, readonly
filter
of type NodeFilter
, readonly
root
of type Node
, readonly
whatToShow
of type unsigned long
, readonlyNodeFilter
interface. Nodes not accepted by
whatToShow will be skipped, but their children may still be considered. Note
that this skip takes precedence over the filter, if any.
firstChild
TreeWalker
to the first visible child of the current
node, and returns the new node. If the current node has no visible children,
returns null
, and retains the current node.
The new node, or |
lastChild
TreeWalker
to the last visible child of the current
node, and returns the new node. If the current node has no visible children,
returns null
, and retains the current node.
The new node, or |
nextNode
TreeWalker
to the next visible node in document order
relative to the current node, and returns the new node. If the current node has
no next node, or if the search for nextNode attempts to step upward from the
TreeWalker's root node, returns null
, and retains the current
node.
The new node, or |
nextSibling
TreeWalker
to the next sibling of the current node,
and returns the new node. If the current node has no visible next sibling,
returns null
, and retains the current node.
The new node, or |
parentNode
The new parent node, or null if the current node has no parent in the TreeWalker's logical view. |
previousNode
TreeWalker
to the previous visible node in document
order relative to the current node, and returns the new node. If the current
node has no previous node,
or if the search for previousNode attempts to step upward from the TreeWalker's
root node,
returns null
, and retains the current node.
The new node, or |
previousSibling
TreeWalker
to the previous sibling of the current
node, and returns the new node. If the current node has no visible previous
sibling, returns null
, and retains the current node.
The new node, or |
DocumentTraversal
contains methods that create iterators and
tree-walkers to traverse a node and its children in document order (depth
first, pre-order traversal, which is equivalent to the order in which the start
tags occur in the text representation of the document). In DOMs which support
the Traversal feature, DocumentTraversal will be implemented by the same
objects that implement the Document interface.
// Introduced in DOM Level 2: interface DocumentTraversal { NodeIterator createNodeIterator(in Node root, in unsigned long whatToShow, in NodeFilter filter, in boolean entityReferenceExpansion); TreeWalker createTreeWalker(in Node root, in unsigned long whatToShow, in NodeFilter filter, in boolean entityReferenceExpansion) raises(DOMException); };
createNodeIterator
| The node which will be iterated together with its children. The iterator is initially positioned just before this node. The whatToShow flags and the filter, if any, are not considered when setting this position. | |||
|
| This flag specifies which node types may appear in the logical view of the tree presented by the iterator. See the description of iterator for the set of possible values. These flags can be combined using | ||
| The Filter to be used with this TreeWalker, or null to indicate no filter. | |||
|
| The value of this flag determines whether entity reference nodes are expanded. |
The newly created |
createTreeWalker
| The node which will serve as the root for the | |||
|
| This flag specifies which node types may appear in the logical view of the tree presented by the iterator. See the description of TreeWalker for the set of possible values. These flags can be combined using | ||
| The Filter to be used with this TreeWalker, or null to indicate no filter. | |||
|
| The value of this flag determines whether entity reference nodes are expanded. |
The newly created |
Raises the exception NOT_SUPPORTED_ERR if the specified root node is null. |