http://www.w3.org/DOM/DOMTM git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@225913 13f79535-47bb-0310-9956-ffa450edef68
1440 lines
61 KiB
XML
1440 lines
61 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!-- $Id$ -->
|
|
<!--
|
|
|
|
*************************************************************************
|
|
|
|
* BEGINNING OF TRAVERSAL *
|
|
|
|
*************************************************************************
|
|
|
|
-->
|
|
<div1 id="Traversal">
|
|
<head>Document Object Model Traversal</head>
|
|
<orglist role="editors">
|
|
<member>
|
|
<name>Joe Kesselman</name>
|
|
<affiliation>IBM</affiliation>
|
|
</member>
|
|
<member>
|
|
<name>Jonathan Robie</name>
|
|
<affiliation>Software AG</affiliation>
|
|
</member>
|
|
<member>
|
|
<name>Mike Champion</name>
|
|
<affiliation>Software AG</affiliation>
|
|
</member>
|
|
</orglist><?GENERATE-MINI-TOC?>
|
|
<!--
|
|
|
|
******************************************************
|
|
|
|
| INTRODUCTION |
|
|
|
|
******************************************************
|
|
|
|
-->
|
|
<div2 id="Traversal-overview">
|
|
<head>Overview</head>
|
|
<p>This chapter describes the optional DOM Level 2 <emph>Traversal</emph>
|
|
feature. Its <code>TreeWalker</code>, <code>NodeIterator</code>, and
|
|
<code>NodeFilter</code> interfaces provide easy-to-use, robust, selective
|
|
traversal of a document's contents.</p>
|
|
|
|
<p>
|
|
The interfaces found within this section are not mandatory. A DOM
|
|
application may use the <code>hasFeature(feature, version)</code> method
|
|
of the <code>DOMImplementation</code> interface with parameter values
|
|
"Traversal" and "2.0" (respectively) to determine whether or not this module
|
|
is supported by the implementation. In order to fully support this
|
|
module, an implementation must also support the "Core" feature defined
|
|
defined in the DOM Level 2 Core specification <bibref
|
|
ref="DOMCore"/>. Please refer to additional information about <xspecref
|
|
href='&core.latest.url;/introduction.html#ID-Conformance'>conformance</xspecref>
|
|
in the DOM Level 2 Core specification <bibref ref="DOMCore"/>.
|
|
</p>
|
|
|
|
<p> <code>NodeIterators</code> and <code>TreeWalkers</code> are two
|
|
different ways of representing the nodes of a document subtree and a position
|
|
within the nodes they present. A <code>NodeIterator</code> presents a flattened
|
|
view of the subtree as an ordered sequence of 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.
|
|
Conversely, a <code>TreeWalker</code> maintains the hierarchical relationships
|
|
of the subtree, allowing navigation of this hierarchy. In general,
|
|
<code>TreeWalkers</code> are better for tasks in which the structure of the
|
|
document around selected nodes will be manipulated, while
|
|
<code>NodeIterators</code> are better for tasks that focus on the content of
|
|
each selected node. </p>
|
|
<p><code>NodeIterators</code> and <code>TreeWalkers</code> 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
|
|
<term id="Traversal-Logical-View">logical view</term> to distinguish it from
|
|
the <term>physical view</term>, which corresponds to the document subtree per
|
|
se. When an iterator or <code>TreeWalker</code> is created, it may be
|
|
associated with a <code>NodeFilter</code>, which examines each 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.</p>
|
|
<p><code>NodeIterators</code> and <code>TreeWalkers</code> are dynamic -
|
|
the logical view changes to reflect changes made to the underlying document.
|
|
However, they differ in how they respond to those changes.
|
|
<code>NodeIterators</code>, which present the nodes sequentially, attempt to
|
|
maintain their location relative to a position in that sequence when the
|
|
sequence's contents change. <code>TreeWalkers</code>, 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.</p>
|
|
<div3 id="Iterator-overview">
|
|
<head><code>NodeIterators</code></head>
|
|
<p>A <code>NodeIterator</code> 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 <termref def="dt-documentorder">document order</termref>. When an
|
|
iterator is first created, calling its <code>nextNode() </code>method returns
|
|
the first node in the logical view of the subtree; in most cases, this is the
|
|
root of the subtree. Each successive call advances the
|
|
<code></code><code>NodeIterator</code> through the list, returning the next
|
|
node available in the logical view. When no more nodes are visible,
|
|
<code>nextNode()</code> returns <code>null</code>.</p>
|
|
<p><code>NodeIterators</code> are created using the
|
|
<code>createNodeIterator</code> method found in the
|
|
<code>DocumentTraversal</code> interface. When a <code>NodeIterator</code> 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 <code>OR</code> operator. Nodes that are "invisible" are
|
|
skipped over by the iterator as though they did not exist. </p>
|
|
<p>The following code creates an iterator, then calls a function to print
|
|
the name of each element:</p>
|
|
<eg xml:space="preserve">
|
|
NodeIterator iter=
|
|
((DocumentTraversal)document).createNodeIterator(
|
|
root, NodeFilter.SHOW_ELEMENT, null);
|
|
|
|
while (Node n = iter.nextNode())
|
|
printMe(n);
|
|
</eg>
|
|
<div4 id="Iterator-Moving">
|
|
<head>Moving Forward and Backward</head>
|
|
<p><code>NodeIterators</code> present nodes as an ordered list, and
|
|
move forward and backward within this list. The iterator's position is always
|
|
either 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 '*' :</p>
|
|
<eg xml:space="preserve"> * A B C D E F G H I</eg>
|
|
<p>Each call to <code>nextNode()</code> returns the next node and
|
|
advances the position. For instance, if we start with the above position, the
|
|
first call to <code>nextNode()</code> returns "A" and advances the
|
|
iterator:</p>
|
|
<eg xml:space="preserve"> [A] * B C D E F G H I</eg>
|
|
<p>The position of a <code>NodeIterator</code> can best be described
|
|
with respect to the last node returned, which we will call the <term>reference
|
|
node</term>. 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.</p>
|
|
<p>A call to <code>previousNode()</code> returns the previous node and
|
|
moves the position backward. For instance, if we start with the
|
|
<code>NodeIterator</code> between "A" and "B", it would
|
|
return "A" and move to the position shown below:</p>
|
|
<eg xml:space="preserve"> * [A] B C D E F G H I</eg>
|
|
<p>If <code>nextNode()</code> is called at the end of a list, or
|
|
<code>previousNode()</code> is called at the beginning of a list, it returns
|
|
<code>null</code> and does not change the position of the iterator. When a
|
|
<code>NodeIterator</code> is first created, the reference node is the first
|
|
node:</p>
|
|
<eg xml:space="preserve"> * [A] B C D E F G H I</eg>
|
|
</div4>
|
|
<div4 id="Iterator-Robustness">
|
|
<head>Robustness</head>
|
|
<p>A <code>NodeIterator</code> 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 a <code>NodeIterator</code>; in fact, a <code>NodeIterator</code> is
|
|
never invalidated unless its <code>detach()</code> 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.</p>
|
|
<p>If changes to the iterated list do not remove the reference node, they do
|
|
not affect the state of the <code>NodeIterator</code>. 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:</p>
|
|
<eg xml:space="preserve">A B C [D] * E F G H I</eg>
|
|
<p>Now let's remove "E". The resulting state is:</p>
|
|
<eg xml:space="preserve">A B C [D] * F G H I</eg>
|
|
<p>If a new node is inserted, the <code>NodeIterator</code> stays close to the
|
|
reference node, so if a node is inserted between "D" and "F", it will occur
|
|
between the iterator and "F": </p>
|
|
<eg xml:space="preserve">A B C [D] * X F G H I</eg>
|
|
<p>Moving a node is equivalent to a removal followed by an insertion. If we
|
|
move "I" to the position before "X" the result is:</p>
|
|
<eg xml:space="preserve">A B C [D] * I X F G H</eg>
|
|
<p>If the reference node is removed from the list being iterated over, a
|
|
different node is selected as the reference node. If the reference node's
|
|
position is before that of the <code>NodeIterator</code>, which is usually the
|
|
case after <code>nextNode()</code> 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:</p>
|
|
<eg xml:space="preserve">A B C [D] * F G H I</eg>
|
|
<p>The "C" node becomes the new reference node, since it is the nearest node to
|
|
the <code>NodeIterator</code> that is before the iterator:</p>
|
|
<eg xml:space="preserve">A B [C] * F G H I</eg>
|
|
<p>If the reference node is after the <code>NodeIterator</code>, which is
|
|
usually the case after <code>previousNode()</code> 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:</p>
|
|
<eg xml:space="preserve">A B C D * [E] F G H I</eg>
|
|
<p>The "F" node becomes the new reference node, since it is the nearest node to
|
|
the <code>NodeIterator</code> that is after the iterator:</p>
|
|
<eg xml:space="preserve">A B C D * [F] G H I</eg>
|
|
<p>As noted above, 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:</p>
|
|
<eg xml:space="preserve">A B C [D] * F G H I C</eg>
|
|
<p>The resulting state is as follows:</p>
|
|
<eg xml:space="preserve">A B [C] * F G H I D</eg>
|
|
<p>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:</p>
|
|
<eg xml:space="preserve">A B * [C]</eg>
|
|
<p>According to the rules we have given, the new reference node should be the
|
|
nearest node after the <code>NodeIterator</code>, but there are no further
|
|
nodes after "C". The same situation can arise when <code>previousNode()</code>
|
|
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:</p>
|
|
<eg xml:space="preserve">A [B] *</eg>
|
|
<p>If the <code>NodeIterator</code> 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 <termref def="dt-parent">parent</termref> node of "D", "E", and "F", and we remove "C",
|
|
starting with the following state:</p>
|
|
<eg xml:space="preserve">A B C [D] * E F G H I D</eg>
|
|
<p>The resulting state is as follows:</p>
|
|
<eg xml:space="preserve">A [B] * G H I D</eg>
|
|
<p>Finally, note that removing a <code>NodeIterator</code>'s <code>root</code>
|
|
node from its <termref def="dt-parent">parent</termref> does not alter the list being iterated over, and thus does
|
|
not change the iterator's state.</p>
|
|
</div4>
|
|
<div4 id="Iterator-Visibility">
|
|
<head>Visibility of Nodes</head>
|
|
<p>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
|
|
<code>NodeIterator</code>. If nodes that are to be excluded because of the
|
|
value of the <code>whatToShow</code> flag, <code>nextNode()</code> returns the
|
|
next visible node, skipping over the excluded "invisible" nodes. If a
|
|
<code>NodeFilter</code> 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 and is returned. If no visible nodes are encountered, a
|
|
<code>null</code> 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
|
|
<code>previousNode()</code>.</p>
|
|
<p> 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:</p>
|
|
<eg xml:space="preserve">A [B] * c d E F G</eg>
|
|
<p>A call to <code>nextNode()</code> returns E and advances to the following
|
|
position:</p>
|
|
<eg xml:space="preserve">A B c d [E] * F G</eg>
|
|
<p> 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:</p>
|
|
<eg xml:space="preserve">A B c [d] * F G</eg>
|
|
<p>Suppose a new node "X", which is visible, is inserted before "d". The
|
|
resulting state is:</p>
|
|
<eg xml:space="preserve">A B c X [d] * F G</eg>
|
|
<p>Note that a call to <code>previousNode()</code> 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 <code>previousNode()</code> would not return "X".</p>
|
|
</div4>
|
|
</div3>
|
|
<div3 id="Traversal-Filters">
|
|
<head><code>NodeFilters</code></head>
|
|
<p><code>NodeFilters</code> 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 presented as part of the traversal's
|
|
logical view of the document. To use a <code>NodeFilter</code>, you create a
|
|
<code>NodeIterator</code> or a <code>TreeWalker</code> that uses the filter.
|
|
The traversal engine applies the filter to each node, and if the filter does
|
|
not accept the node, traversal skips over the node as though it were not
|
|
present in the document. <code>NodeFilters</code> need not know how to navigate
|
|
the structure that contains the nodes on which they operate. </p>
|
|
<!--JKESS 20000305: Traversal has no memory, and no anticipation,
|
|
of filters-->
|
|
<p>Filters will be consulted when a traversal operation is performed, or when a
|
|
<code>NodeIterator</code>'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,
|
|
<code>NodeFilters</code> should not attempt to maintain state based on the
|
|
history of past invocations; the resulting behavior may not be portable.</p>
|
|
<p>Similarly, <code>TreeWalkers</code> and <code>NodeIterators</code> should
|
|
behave as if they have no memory of past filter results, and no anticipation of
|
|
future results. If the conditions a <code>NodeFilter</code> 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
|
|
<code>FILTER_SHOW</code> to <code>FILTER_SKIP</code>, a <code>TreeWalker</code>
|
|
will be able to navigate off that node in any direction, but not back to it
|
|
unless the filtering conditions change again. <code>NodeFilters</code> which
|
|
change during a traversal can be written, but their behavior may be confusing
|
|
and they should be avoided when possible.</p>
|
|
<!-- End JKESS 20000305 -->
|
|
<div4 id="Traversal-Filters-Usage">
|
|
<head>Using <code>NodeFilters</code></head>
|
|
<p>A <code>NodeFilter</code> contains one method named
|
|
<code>acceptNode()</code>, which allows a <code>NodeIterator</code> or
|
|
<code>TreeWalker</code> to pass a <code>Node</code> to a filter and ask whether
|
|
it should be present in the logical view. The <code>acceptNode()</code>
|
|
function returns one of three values to state how the <code>Node</code> should
|
|
be treated. If <code>acceptNode()</code> returns <code>FILTER_ACCEPT</code>,
|
|
the <code>Node</code> will be present in the logical view; if it returns
|
|
<code>FILTER_SKIP</code>, the <code>Node</code> will not be present in the
|
|
logical view, but the children of the <code>Node</code> may; if it returns
|
|
<code>FILTER_REJECT</code>, neither the <code>Node</code> nor its
|
|
<termref def="dt-descendant">descendants</termref>
|
|
will be present in the logical view. Since iterators present nodes as an
|
|
ordered list, without hierarchy, <code>FILTER_REJECT</code> and
|
|
<code>FILTER_SKIP</code> are synonyms for <code>NodeIterators</code>, skipping
|
|
only the single current node.</p>
|
|
<p>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
|
|
<code>NodeFilter</code> in Java that looks at a node and determines whether it
|
|
is a named anchor:</p>
|
|
<eg xml:space="preserve">
|
|
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;
|
|
}
|
|
}</eg>
|
|
<p>If the above <code>NodeFilter</code> were to be used only with
|
|
<code>NodeIterators</code>, it could have used <code>FILTER_REJECT</code>
|
|
wherever <code>FILTER_SKIP</code> is used, and the behavior would not change.
|
|
For <code>TreeWalker</code>, though, <code>FILTER_REJECT</code> 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. <code>FILTER_SKIP</code> rejects the given node, but
|
|
continues to examine the children; therefore, the above filter will work with
|
|
either a <code>NodeIterator</code> or a <code>TreeWalker</code>.</p>
|
|
<p>To use this filter, the user would create an instance of the
|
|
<code>NodeFilter</code> and create a <code>NodeIterator</code> using it:</p>
|
|
<eg xml:space="preserve">
|
|
NamedAnchorFilter myFilter = new NamedAnchorFilter();
|
|
NodeIterator iter=
|
|
((DocumentTraversal)document).createNodeIterator(
|
|
node, NodeFilter.SHOW_ELEMENT, myFilter);
|
|
</eg>
|
|
<p>Note that the use of the <code>SHOW_ELEMENT</code> flag is not strictly
|
|
necessary in this example, since our sample <code>NodeFilter</code> tests the
|
|
<code>nodeType</code>. However, some implementations of the Traversal
|
|
interfaces may be able to improve <code>whatToShow</code> performance by taking
|
|
advantage of knowledge of the document's structure, which makes the use of
|
|
<code>SHOW_ELEMENT</code> worthwhile. Conversely, while we could remove the
|
|
<code>nodeType</code> test from our filter, that would make it dependent upon
|
|
<code>whatToShow</code> to distinguish between <code>Elements</code>,
|
|
<code>Attr</code>'s, and <code>ProcessingInstructions</code>. </p>
|
|
</div4>
|
|
<div4 id="Traversal-Filters-Exceptions">
|
|
<head><code>NodeFilters</code> and Exceptions</head>
|
|
<p>When writing a <code>NodeFilter</code>, users should avoid writing code that
|
|
can throw an exception. However, because a DOM implementation can not prevent
|
|
exceptions from being thrown, it is important that the behavior of filters that
|
|
throw an exception be well-defined. A <code>TreeWalker</code> or
|
|
<code>NodeIterator</code> 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 <code>NodeFilter</code>, and may therefore propagate an exception
|
|
if one is thrown by a filter:
|
|
<olist>
|
|
<item>
|
|
<p><code>NodeIterator</code><code>.nextNode()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>NodeIterator</code><code>.previousNode()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.firstChild()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.lastChild()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.nextSibling()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.previousSibling()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.nextNode()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.previousNode()</code> </p>
|
|
</item>
|
|
<item>
|
|
<p><code>TreeWalker</code><code>.parentNode()</code> </p>
|
|
</item>
|
|
</olist> </p>
|
|
</div4>
|
|
<div4 id="Traversal-Filters-Mutation">
|
|
<head><code>NodeFilters</code> and Document Mutation</head>
|
|
<p>Well-designed <code>NodeFilters</code> should not have to modify the
|
|
underlying structure of the document. But a DOM implementation can not prevent
|
|
a user from writing filter code that does alter the document structure.
|
|
Traversal does not provide any special processing to handle this case. For
|
|
instance, if a <code>NodeFilter</code> removes a node from a document, it can
|
|
still accept the node, which means that the node may be returned by the
|
|
<code>NodeIterator</code> or <code>TreeWalker</code> even though it is no
|
|
longer in the subtree being traversed. In general, this may lead to
|
|
inconsistent, confusing results, so we encourage users to write
|
|
<code>NodeFilters</code> that make no changes to document structures. Instead,
|
|
do your editing in the loop controlled by the traversal object.</p>
|
|
|
|
<!--A second case that was given by Andy was modifications that change
|
|
the node so that the filter's tests would no longer accept the
|
|
node. However, since the Filter makes the changes and applies the test,
|
|
it is the Filter function itself that defines whether a node is
|
|
accepted or rejected, so if the Filter modifies a node and then accepts
|
|
it, this is simply the definition of the Filter. We decided to omit the
|
|
case.-->
|
|
</div4>
|
|
<div4 id="Traversal-Filters-Flags">
|
|
<head><code>NodeFilters</code> and <code>whatToShow</code> flags </head>
|
|
<p><code>NodeIterator</code> and <code>TreeWalker</code> apply their
|
|
<code>whatToShow</code> flags before applying filters. If a node is
|
|
<!-- JKESS 20000217: Clarify whatToShow behavior,
|
|
potential interaction with FILTER_REJECT.
|
|
-->
|
|
skipped by the active <code>whatToShow</code> flags, a <code>NodeFilter</code>
|
|
will not be called to evaluate that node. Please note that this behavior is
|
|
similar to that of <code>FILTER_SKIP</code>; 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 <code>NodeFilter</code> would have preferred to
|
|
reject the entire subtree; if this would cause a problem in your application,
|
|
consider setting <code>whatToShow</code> to <code>SHOW_ALL</code> and
|
|
performing the <code>nodeType</code> test inside your filter.
|
|
<!-- End JKESS 20000217 -->
|
|
</p>
|
|
</div4>
|
|
</div3>
|
|
<div3 id="TreeWalker">
|
|
<head><code>TreeWalker</code></head>
|
|
<p>The <code>TreeWalker</code> interface provides many of the same benefits as
|
|
the <code>NodeIterator</code> interface. The main difference between these two
|
|
interfaces is that the <code>TreeWalker</code> presents a tree-oriented view of
|
|
the nodes in a subtree, rather than the iterator's list-oriented view. In other
|
|
words, an iterator allows you to move forward or back, but a
|
|
<code>TreeWalker</code> allows you to also move to the <termref def="dt-parent">parent</termref> of a node, to one
|
|
of its children, or to a <termref def="dt-sibling">sibling</termref>.</p>
|
|
<p>Using a <code>TreeWalker</code> 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 recursively walks over a tree of nodes in
|
|
document order, taking separate actions when first entering a node and after
|
|
processing any children:</p>
|
|
<eg xml:space="preserve">
|
|
processMe(Node n) {
|
|
nodeStartActions(n);
|
|
for (Node child=n.firstChild();
|
|
child != null;
|
|
child=child.nextSibling()) {
|
|
processMe(child);
|
|
}
|
|
nodeEndActions(n);
|
|
}</eg>
|
|
<p>Doing the same thing using a <code>TreeWalker</code> is quite similar. There
|
|
is one difference: since navigation on the <code>TreeWalker</code> changes the
|
|
current position, the position at the end of the function has changed. A
|
|
read/write attribute named <code>currentNode</code> allows the current node for
|
|
a <code>TreeWalker</code> to be both queried and set. We will use this to
|
|
ensure that the position of the <code>TreeWalker</code> is restored when this
|
|
function is completed:</p>
|
|
<eg xml:space="preserve">
|
|
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);
|
|
}</eg>
|
|
<p>The advantage of using a <code>TreeWalker</code> instead of direct
|
|
<code>Node</code> navigation is that the <code>TreeWalker</code> allows the
|
|
user to choose an appropriate view of the tree. Flags may be used to show or
|
|
hide <code>Comments</code> or <code>ProcessingInstructions</code>; entities may
|
|
be expanded or shown as <code>EntityReference</code> nodes. In addition,
|
|
<code>NodeFilters</code> 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:</p>
|
|
<eg xml:space="preserve">
|
|
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;
|
|
}
|
|
}</eg>
|
|
<p> </p>
|
|
<p>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.</p>
|
|
<p>Now the program can create an instance of this <code>NodeFilter</code>,
|
|
create a <code>TreeWalker</code> that uses it, and pass this
|
|
<code>TreeWalker</code> to our ProcessMe() function:</p>
|
|
<eg>TablesInChapters tablesInChapters = new TablesInChapters();
|
|
TreeWalker tw =
|
|
((DocumentTraversal)document).createTreeWalker(
|
|
root, NodeFilter.SHOW_ELEMENT, tablesInChapters);
|
|
processMe(tw);</eg>
|
|
<p>(Again, we've chosen to both test the <code>nodeType</code> in the filter's
|
|
logic and use <code>SHOW_ELEMENT</code>, for the reasons discussed in the
|
|
earlier <code>NodeIterator</code> example.)</p>
|
|
<p>Without making any changes to the above <code>ProcessMe()</code> 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 <code>TreeWalker</code> to navigate, they will support any view
|
|
of the document defined with a <code>TreeWalker</code>.</p>
|
|
<p>Note that the structure of a <code>TreeWalker</code>'s filtered view of a
|
|
document may differ significantly from that of the document itself. For
|
|
example, a <code>TreeWalker</code> with only <code>SHOW_TEXT</code> specified
|
|
in its <code>whatToShow</code> parameter would present all the
|
|
<code>Text</code> nodes as if they were <termref def="dt-sibling">siblings</termref> of each other yet had no
|
|
<termref def="dt-parent">parent</termref>.</p>
|
|
<div4 id="TreeWalker-Robustness">
|
|
<head>Robustness</head>
|
|
<p>As with <code>NodeIterators</code>, a <code>TreeWalker</code> 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 <code>TreeWalker</code>; in fact, a
|
|
<code>TreeWalker</code> is never invalidated.</p>
|
|
<p>But a <code>TreeWalker</code>'s response to these changes is quite different
|
|
from that of a <code>NodeIterator</code>. While <code>NodeIterators</code>
|
|
respond to editing by maintaining their position within the list that they are
|
|
iterating over, <code>TreeWalkers</code> will instead remain attached to their
|
|
<code>currentNode</code>. All the <code>TreeWalker</code>'s navigation methods
|
|
operate in terms of the context of the <code>currentNode</code> at the time
|
|
they are invoked, no matter what has happened to, or around, that node since
|
|
the last time the <code>TreeWalker</code> was accessed. This remains true even
|
|
if the <code>currentNode</code> is moved out of its original subtree.</p>
|
|
<p>As an example, consider the following document fragment:</p>
|
|
<eg xml:space="preserve">
|
|
...
|
|
<subtree>
|
|
<twRoot>
|
|
<currentNode/>
|
|
<anotherNode/>
|
|
</twRoot>
|
|
</subtree>
|
|
...
|
|
</eg>
|
|
<p>Let's say we have created a <code>TreeWalker</code> whose <code>root</code>
|
|
node is the <twRoot/> element and whose <code>currentNode</code> is the
|
|
<currentNode/> element. For this illustration, we will assume that all
|
|
the nodes shown above are accepted by the <code>TreeWalker</code>'s
|
|
<code>whatToShow</code> and filter settings.</p>
|
|
<p>If we use <code>removeChild()</code> to remove the <currentNode/>
|
|
element from its <termref def="dt-parent">parent</termref>, that element remains the <code>TreeWalker</code>'s
|
|
<code>currentNode</code>, even though it is no longer within the
|
|
<code>root</code> node's subtree. We can still use the <code>TreeWalker</code>
|
|
to navigate through any children that the orphaned <code>currentNode</code> may
|
|
have, but are no longer able to navigate outward from the
|
|
<code>currentNode</code> since there is no <termref def="dt-parent">parent</termref> available.</p>
|
|
<p>If we use <code>insertBefore()</code> or <code>appendChild()</code> to give
|
|
the <currentNode/> a new <termref def="dt-parent">parent</termref>, then <code>TreeWalker</code> navigation
|
|
will operate from the <code>currentNode</code>'s new location. For example, if
|
|
we inserted the <currentNode/> immediately after the <anotherNode/>
|
|
element, the <code>TreeWalker</code>'s <code>previousSibling()</code> operation
|
|
would move it back to the <anotherNode/>, and calling
|
|
<code>parentNode()</code> would move it up to the <twRoot/>.</p>
|
|
<p>If we instead insert the <code>currentNode</code> into the <subtree/>
|
|
element, like so:</p>
|
|
<eg xml:space="preserve">
|
|
...
|
|
<subtree>
|
|
<currentNode/>
|
|
<twRoot>
|
|
<anotherNode/>
|
|
</twRoot>
|
|
</subtree>
|
|
...</eg>
|
|
<p>we have moved the <code>currentNode</code> out from under the
|
|
<code>TreeWalker</code>'s <code>root</code> node. This does not invalidate the
|
|
<code>TreeWalker</code>; it may still be used to navigate relative to the
|
|
<code>currentNode</code>. Calling its <code>parentNode()</code> operation, for
|
|
example, would move it to the <subtree/> element, even though that too is
|
|
outside the original <code>root</code> node. However, if the
|
|
<code>TreeWalker</code>'s navigation should take it back into the original
|
|
<code>root</code> node's subtree -- for example, if rather than calling
|
|
<code>parentNode()</code> we called <code>nextNode()</code>, moving the
|
|
<code>TreeWalker</code> to the <twRoot/> element -- the <code>root</code>
|
|
node will "recapture" the <code>TreeWalker</code>, and prevent it from
|
|
traversing back out.</p>
|
|
<!--JKESS 20000301: Miles' "transient sibling" case-->
|
|
<p>This becomes a bit more complicated when filters are in use. Relocation of
|
|
the <code>currentNode</code> -- or explicit selection of a new
|
|
<code>currentNode</code>, or changes in the conditions that the
|
|
<code>NodeFilter</code> is basing its decisions on -- can result in a
|
|
<code>TreeWalker</code> having a <code>currentNode</code> which would not
|
|
otherwise be visible in the filtered (logical) view of the document. This node
|
|
can be thought of as a "transient member" of that view. When you ask the
|
|
<code>TreeWalker</code> 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.</p>
|
|
<p>In particular: If the <code>currentNode</code> 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 <termref def="dt-ancestor">ancestor</termref>. 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.</p>
|
|
<!--End JKESS 20000301-->
|
|
</div4>
|
|
</div3>
|
|
</div2>
|
|
<div2 id="Traversal-IDLDefinition">
|
|
<head>Formal Interface Definition</head>
|
|
<definitions>
|
|
<interface name="NodeIterator" id="Traversal-NodeIterator" since="DOM Level 2">
|
|
|
|
<descr>
|
|
<p><code>Iterators</code> are used to step through a set of nodes, e.g. the set
|
|
of nodes in a <code>NodeList</code>, the document subtree governed by a
|
|
particular <code>Node</code>, 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 <code>NodeIterator</code>. DOM Level 2 specifies a single
|
|
<code>NodeIterator</code> implementation for document-order traversal of a
|
|
document subtree. Instances of these iterators are created by calling
|
|
<code>DocumentTraversal</code><code>.createNodeIterator()</code>.</p>
|
|
</descr>
|
|
<!-- JKESS: 200000217: New attribute. Approved in 2/16 telecon -->
|
|
<attribute id="Traversal-NodeIterator-root" name="root" type="Node"
|
|
readonly="yes">
|
|
<descr>
|
|
<p>The root node of the <code>NodeIterator</code>, as specified when it was
|
|
created.</p>
|
|
</descr>
|
|
</attribute>
|
|
<!-- End JKESS: 200000217:-->
|
|
<!-- JKESS: 2/2/2000: whatToShow changed from long to unsigned long -->
|
|
<attribute id="Traversal-NodeIterator-whatToShow" name="whatToShow"
|
|
type="unsigned long" readonly="yes">
|
|
<descr>
|
|
<p>This attribute determines which node types are presented via the iterator.
|
|
The available set of constants is defined in the <code>NodeFilter</code>
|
|
interface.
|
|
|
|
<!--JKESS 20000228: Document interaction -->
|
|
Nodes not accepted by <code>whatToShow</code> will be skipped, but their
|
|
children may still be considered. Note that this skip takes precedence over the
|
|
filter, if any.
|
|
|
|
<!--End JKESS 20000228--></p>
|
|
</descr>
|
|
</attribute>
|
|
<attribute id="Traversal-NodeIterator-filter" name="filter" type="NodeFilter"
|
|
readonly="yes">
|
|
<descr>
|
|
<p>The <code>NodeFilter</code> used to screen nodes.</p>
|
|
</descr>
|
|
</attribute>
|
|
<attribute id="Traversal-NodeIterator-expandEntityReferences"
|
|
name="expandEntityReferences" type="boolean" readonly="yes">
|
|
<descr>
|
|
<p> The value of this flag determines whether the children of entity reference
|
|
nodes are visible to the iterator. If false, they
|
|
|
|
<!--JKESS 20000228: "will be skipped over" should be "rejected"-->
|
|
and their <termref def="dt-descendant">descendants</termref> will be rejected. Note that this rejection takes
|
|
precedence over <code>whatToShow</code> and the filter. Also note that this is
|
|
currently the only situation where <code>NodeIterators</code> may reject a
|
|
complete subtree rather than skipping individual nodes.
|
|
|
|
<!--end JKESS 20000228--></p>
|
|
<p></p>
|
|
<p> To produce a view of the document that has entity references expanded and
|
|
does not expose the entity reference node itself, use the
|
|
<code>whatToShow</code> flags to hide the entity reference node and set
|
|
<code>expandEntityReferences</code> to true when creating the iterator. To
|
|
produce a view of the document that has entity reference nodes but no entity
|
|
expansion, use the <code>whatToShow</code> flags to show the entity reference
|
|
node and set <code>expandEntityReferences</code> to false.</p>
|
|
</descr>
|
|
</attribute>
|
|
<method name="nextNode" id="Traversal-NodeIterator-nextNode">
|
|
<descr>
|
|
<p>Returns the next node in the set and advances the position of the iterator
|
|
in the set. After a <code>NodeIterator</code> is created, the first call to
|
|
<code>nextNode()</code> returns the first node in the set.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The next <code>Node</code> in the set being iterated over, or
|
|
<code>null</code> if there are no more members in that set.</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
<exception name="DOMException">
|
|
<descr>
|
|
<p>INVALID_STATE_ERR: Raised if this method is called after the
|
|
<code>detach</code> method was invoked.</p>
|
|
</descr>
|
|
</exception>
|
|
|
|
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="previousNode" id="Traversal-NodeIterator-previousNode">
|
|
<descr>
|
|
<p>Returns the previous node in the set and moves the position of the
|
|
<code>NodeIterator</code> backwards in the set.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The previous <code>Node</code> in the set being iterated over, or
|
|
<code>null</code> if there are no more members in that set. </p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
<exception name="DOMException">
|
|
<descr>
|
|
<p>INVALID_STATE_ERR: Raised if this method is called after the
|
|
<code>detach</code> method was invoked.</p>
|
|
</descr>
|
|
</exception>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="detach" id="Traversal-NodeIterator-detach">
|
|
<descr>
|
|
<p>Detaches the <code>NodeIterator</code> from the set which it iterated over,
|
|
releasing any computational resources and placing the iterator in the INVALID
|
|
state. After <code>detach</code> has been invoked, calls to
|
|
<code>nextNode</code> or <code>previousNode</code> will raise the exception
|
|
INVALID_STATE_ERR.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="void">
|
|
<descr>
|
|
<p></p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
</interface>
|
|
<interface name="NodeFilter" id="Traversal-NodeFilter"
|
|
since="DOM Level 2" role="special">
|
|
<descr>
|
|
<p>Filters are objects that know how to "filter out" nodes. If a
|
|
<code>NodeIterator</code> or <code>TreeWalker</code> is given a
|
|
<code>NodeFilter</code>, it applies the filter before it returns the next node.
|
|
If the filter says to accept the node, the traversal logic returns it;
|
|
otherwise, traversal looks for the next node and pretends that the node that
|
|
was rejected was not there.</p>
|
|
<p>The DOM does not provide any filters. <code>NodeFilter</code> is just an
|
|
interface that users can implement to provide their own filters. </p>
|
|
<p><code>NodeFilters</code> do not need to know how to traverse from node to
|
|
node, nor do they need to know anything about the data structure that is being
|
|
traversed. 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 traversals, encouraging code reuse.</p>
|
|
</descr>
|
|
<group name="Constants returned by acceptNode"
|
|
id="Traversal-NodeFilter-acceptNode-constants">
|
|
<descr>
|
|
<p>The following constants are returned by the acceptNode() method:</p>
|
|
</descr>
|
|
<constant name="FILTER_ACCEPT" type="short" value="1">
|
|
<descr>
|
|
<p>Accept the node. Navigation methods defined for <code>NodeIterator</code> or
|
|
<code>TreeWalker</code> will return this node.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="FILTER_REJECT" type="short" value="2">
|
|
<descr>
|
|
<p>Reject the node. Navigation methods defined for <code>NodeIterator</code> or
|
|
<code>TreeWalker</code> will not return this node. For <code>TreeWalker</code>,
|
|
the children of this node will also be rejected. <code>NodeIterators</code>
|
|
treat this as a synonym for <code>FILTER_SKIP</code>.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="FILTER_SKIP" type="short" value="3">
|
|
<descr>
|
|
<p>Skip this single node. Navigation methods defined for
|
|
<code>NodeIterator</code> or <code>TreeWalker</code> will not return this node.
|
|
For both <code>NodeIterator</code> and <code>TreeWalker</code>, the children of
|
|
this node will still be considered. </p>
|
|
</descr>
|
|
</constant>
|
|
</group>
|
|
<group id="Traversal-NodeFilter-whatToShow-constants"
|
|
name="Constants for whatToShow">
|
|
<descr>
|
|
<p>These are the available values for the <code>whatToShow</code> parameter
|
|
used in <code>TreeWalkers</code> and <code>NodeIterators</code>. They are the
|
|
same as the set of possible types for <code>Node</code>, and their values are
|
|
derived by using a bit position corresponding to the value of
|
|
<code>nodeType</code> for the equivalent node type.
|
|
|
|
<!-- JKESS 20000217: Added behavioral clarifications -->
|
|
If a bit in <code>whatToShow</code> 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 <code>FILTER_SKIP</code>. </p>
|
|
<p> Note that if node types greater than 32 are ever introduced, they may not
|
|
be individually testable via <code>whatToShow</code>. If that need should
|
|
arise, it can be handled by selecting <code>SHOW_ALL</code> together with an
|
|
appropriate <code>NodeFilter</code>.</p>
|
|
|
|
<!-- End JKESS 20000217 -->
|
|
</descr>
|
|
|
|
<!-- JKESS 20000217: Corrected from erroneous value 0x0000FFFF. Approved in 0216 telecon. -->
|
|
<constant name="SHOW_ALL" type="unsigned long" value="0xFFFFFFFF">
|
|
|
|
<!-- End JKESS 20000217 -->
|
|
<descr>
|
|
<p>Show all <code>Nodes</code>.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_ELEMENT" type="unsigned long" value="0x00000001">
|
|
<descr>
|
|
<p>Show <code>Element</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_ATTRIBUTE" type="unsigned long" value="0x00000002">
|
|
<descr>
|
|
<p>Show <code>Attr</code> nodes. This is meaningful only when creating an
|
|
iterator or tree-walker with an attribute node as its <code>root</code>; in
|
|
this case, it means that the attribute node will appear in the first position
|
|
of the iteration or traversal. Since attributes are never children of other
|
|
nodes, they do not appear when traversing over the document tree.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_TEXT" type="unsigned long" value="0x00000004">
|
|
<descr>
|
|
<p>Show <code>Text</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_CDATA_SECTION" type="unsigned long" value="0x00000008">
|
|
<descr>
|
|
<p>Show <code>CDATASection</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_ENTITY_REFERENCE" type="unsigned long" value="0x00000010">
|
|
|
|
<descr>
|
|
<p>Show <code>EntityReference</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_ENTITY" type="unsigned long" value="0x00000020">
|
|
<descr>
|
|
<p>Show <code>Entity</code> nodes. This is meaningful only when creating an
|
|
iterator or tree-walker with an<code> Entity</code> node as its
|
|
<code>root</code>; in this case, it means that the <code>Entity</code> 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.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_PROCESSING_INSTRUCTION" type="unsigned long"
|
|
value="0x00000040">
|
|
<descr>
|
|
<p>Show <code>ProcessingInstruction</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_COMMENT" type="unsigned long" value="0x00000080">
|
|
<descr>
|
|
<p>Show <code>Comment</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_DOCUMENT" type="unsigned long" value="0x00000100">
|
|
<descr>
|
|
<p>Show <code>Document</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_DOCUMENT_TYPE" type="unsigned long" value="0x00000200">
|
|
<descr>
|
|
<p>Show <code>DocumentType</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_DOCUMENT_FRAGMENT" type="unsigned long"
|
|
value="0x00000400">
|
|
<descr>
|
|
<p>Show <code>DocumentFragment</code> nodes.</p>
|
|
</descr>
|
|
</constant>
|
|
<constant name="SHOW_NOTATION" type="unsigned long" value="0x00000800">
|
|
<descr>
|
|
<p>Show <code>Notation</code> nodes. This is meaningful only when creating an
|
|
iterator or tree-walker with a <code>Notation</code> node as its
|
|
<code>root</code>; in this case, it means that the <code>Notation</code> 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.</p>
|
|
</descr>
|
|
</constant>
|
|
</group>
|
|
<method name="acceptNode" id="Traversal-NodeFilter-acceptNode">
|
|
<descr>
|
|
<p>Test whether a specified node is visible in the logical view of a
|
|
<code>TreeWalker</code> or <code>NodeIterator</code>. This function will be
|
|
called by the implementation of <code>TreeWalker</code> and
|
|
<code>NodeIterator</code>; it is not normally called directly from user code.
|
|
(Though you could do so if you wanted to use the same filter to guide your own
|
|
application logic.)</p>
|
|
</descr>
|
|
<parameters>
|
|
<param name="n" type="Node" attr="in">
|
|
<descr>
|
|
<p>The node to check to see if it passes the filter or not.</p>
|
|
</descr>
|
|
</param>
|
|
</parameters>
|
|
<returns type="short">
|
|
<descr>
|
|
<p>a constant to determine whether the node is accepted, rejected, or skipped,
|
|
as defined
|
|
<loc href="#Traversal-NodeFilter-acceptNode-constants">above</loc>.</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!-- No exceptions -->
|
|
</raises>
|
|
</method>
|
|
</interface>
|
|
<interface name="TreeWalker" id="Traversal-TreeWalker" since="DOM Level 2">
|
|
<descr>
|
|
<p><code>TreeWalker</code> objects are used to navigate a document tree or
|
|
subtree using the view of the document defined by their <code>whatToShow</code>
|
|
flags and filter (if any). Any function which performs navigation using a
|
|
<code>TreeWalker</code> will automatically support any view defined by a
|
|
<code>TreeWalker</code>.</p>
|
|
<p>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 <termref def="dt-sibling">siblings</termref> in the <code>TreeWalker</code>
|
|
view may be children of different, widely separated nodes in the original view.
|
|
For instance, consider a <code>NodeFilter</code> 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 <termref def="dt-sibling">siblings</termref> and appear as direct children of the
|
|
root node, no matter how deeply nested the structure of the original
|
|
document.</p>
|
|
</descr>
|
|
<!-- JKESS: 200000217: New attribute. Approved in 2/16 telecon -->
|
|
<attribute id="Traversal-TreeWalker-root" name="root" type="Node"
|
|
readonly="yes">
|
|
<descr>
|
|
<p>The <code>root</code> node of the <code>TreeWalker</code>, as specified when
|
|
it was created.</p>
|
|
</descr>
|
|
</attribute>
|
|
<!-- End JKESS: 200000217:-->
|
|
<!-- JKESS: 2/2/2000: whatToShow changed from long to unsigned long -->
|
|
<attribute id="Traversal-TreeWalker-whatToShow" name="whatToShow"
|
|
type="unsigned long" readonly="yes">
|
|
<descr>
|
|
<p>This attribute determines which node types are presented via the
|
|
<code>TreeWalker</code>. The available set of constants is defined in the
|
|
<code>NodeFilter</code> interface.
|
|
<!--JKESS 20000228: Document interaction -->
|
|
Nodes not accepted by <code>whatToShow</code> will be skipped, but their
|
|
children may still be considered. Note that this skip takes precedence over the
|
|
filter, if any.
|
|
<!--End JKESS 20000228--></p>
|
|
</descr>
|
|
</attribute>
|
|
<attribute id="Traversal-TreeWalker-filter" name="filter" type="NodeFilter"
|
|
readonly="yes">
|
|
<descr>
|
|
<p>The filter used to screen nodes.</p>
|
|
</descr>
|
|
</attribute>
|
|
<attribute id="Traversal-TreeWalker-expandEntityReferences"
|
|
name="expandEntityReferences" type="boolean" readonly="yes">
|
|
<descr>
|
|
<p>The value of this flag determines whether the children of entity reference
|
|
nodes are visible to the <code>TreeWalker</code>. If false, they
|
|
<!--JKESS 20000228: "will be skipped over" should be "rejected"-->
|
|
and their <termref def="dt-descendant">descendants</termref> will be rejected. Note that this rejection takes
|
|
precedence over <code>whatToShow</code> and the filter, if any.
|
|
<!--end JKESS 20000228--></p>
|
|
<p> To produce a view of the document that has entity references expanded and
|
|
does not expose the entity reference node itself, use the
|
|
<code>whatToShow</code> flags to hide the entity reference node and set
|
|
<code>expandEntityReferences</code> to true when creating the
|
|
<code>TreeWalker</code>. To produce a view of the document that has entity
|
|
reference nodes but no entity expansion, use the <code>whatToShow</code> flags
|
|
to show the entity reference node and set <code>expandEntityReferences</code>
|
|
to false.</p>
|
|
</descr>
|
|
</attribute>
|
|
<attribute id="Traversal-TreeWalker-currentNode" name="currentNode" type="Node"
|
|
readonly="no">
|
|
<descr>
|
|
<p>The node at which the <code>TreeWalker</code> is currently positioned.</p>
|
|
<p>Alterations to the DOM tree may cause the current node to no longer be
|
|
accepted by the <code>TreeWalker</code>'s associated filter.
|
|
<code>currentNode</code> may also be explicitly set to any node, whether or not
|
|
it is within the subtree specified by the <code>root</code> node or would be
|
|
accepted by the filter and <code>whatToShow</code> flags. Further traversal
|
|
occurs relative to <code>currentNode</code> even if it is not part of the
|
|
current view, by applying the filters in the requested direction; if no
|
|
traversal is possible, <code>currentNode</code> is not changed. </p>
|
|
</descr>
|
|
<setraises>
|
|
<exception name="DOMException">
|
|
<descr>
|
|
<p>NOT_SUPPORTED_ERR: Raised if an attempt is made to set
|
|
<code>currentNode</code> to <code>null</code>.</p>
|
|
</descr>
|
|
</exception>
|
|
</setraises>
|
|
</attribute>
|
|
<method name="parentNode" id="Traversal-TreeWalker-parentNode">
|
|
<descr>
|
|
<p>Moves to and returns the closest visible <termref def="dt-ancestor">ancestor</termref> node of the current node.
|
|
If the search for <code>parentNode</code> attempts to step upward from the
|
|
<code>TreeWalker</code>'s <code>root</code> node, or if it fails to find a
|
|
visible <termref def="dt-ancestor">ancestor</termref> node, this method retains the current position and returns
|
|
<code>null</code>.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new <termref def="dt-parent">parent</termref> node, or <code>null</code> if the current node has no parent
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="firstChild" id="Traversal-TreeWalker-firstChild">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> to the first visible <termref
|
|
def="dt-child">child</termref> of the current
|
|
node, and returns the new node. If the current node has no visible children,
|
|
returns <code>null</code>, and retains the current node.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no visible
|
|
children
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="lastChild" id="Traversal-TreeWalker-lastChild">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> to the last visible <termref
|
|
def="dt-child">child</termref> of the current
|
|
node, and returns the new node. If the current node has no visible children,
|
|
returns <code>null</code>, and retains the current node.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no children
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="previousSibling" id="Traversal-TreeWalker-previousSibling">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> to the previous <termref def="dt-sibling">sibling</termref> of the current
|
|
node, and returns the new node. If the current node has no visible previous
|
|
<termref def="dt-sibling">sibling</termref>, returns <code>null</code>, and retains the current node.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no previous
|
|
<termref def="dt-sibling">sibling</termref>.
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="nextSibling" id="Traversal-TreeWalker-nextSibling">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> to the next <termref def="dt-sibling">sibling</termref> of the current node,
|
|
and returns the new node. If the current node has no visible next <termref def="dt-sibling">sibling</termref>,
|
|
returns <code>null</code>, and retains the current node.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no next <termref def="dt-sibling">sibling</termref>.
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="previousNode" id="Traversal-TreeWalker-previousNode">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> 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,
|
|
|
|
<!-- JKESS: Since this may involve an upward search... -->
|
|
or if the search for <code>previousNode</code> attempts to step upward from the
|
|
<code>TreeWalker</code>'s <code>root</code> node,
|
|
|
|
<!-- END JKESS -->
|
|
returns <code>null</code>, and retains the current node. </p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no previous node
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
<method name="nextNode" id="Traversal-TreeWalker-nextNode">
|
|
<descr>
|
|
<p>Moves the <code>TreeWalker</code> 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
|
|
<code>TreeWalker</code>'s <code>root</code> node, returns <code>null</code>,
|
|
and retains the current node.</p>
|
|
</descr>
|
|
<parameters>
|
|
</parameters>
|
|
<returns type="Node">
|
|
<descr>
|
|
<p>The new node, or <code>null</code> if the current node has no next node
|
|
|
|
<!-- JKESS20000217: Added phrase -->
|
|
in the <code>TreeWalker</code>'s logical view.
|
|
|
|
<!-- End JKESS20000217 -->
|
|
</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
|
|
<!--
|
|
|
|
<exception name="Exceptions from user code">
|
|
|
|
<descr><p>Any exceptions raised by a user-written Filter will
|
|
|
|
propagate through.</p></descr>
|
|
|
|
</exception>
|
|
|
|
-->
|
|
</raises>
|
|
</method>
|
|
</interface>
|
|
<interface name="DocumentTraversal" id="Traversal-Document"
|
|
since="DOM Level 2">
|
|
<descr>
|
|
<p><code>DocumentTraversal</code> 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, <code>DocumentTraversal</code> will be implemented by
|
|
the same objects that implement the Document interface.</p>
|
|
</descr>
|
|
<method name="createNodeIterator"
|
|
id="Traversal-NodeIteratorFactory-createNodeIterator">
|
|
<descr>
|
|
<p>Create a new <code>NodeIterator</code> over the subtree rooted at the
|
|
specified node.</p>
|
|
</descr>
|
|
<parameters>
|
|
<param name="root" type="Node" attr="in">
|
|
<descr>
|
|
<p>The node which will be iterated together with its children. The iterator is
|
|
initially positioned just before this node. The <code>whatToShow</code> flags
|
|
and the filter, if any, are not considered when setting this position. The root
|
|
must not be <code>null</code>.</p>
|
|
</descr>
|
|
</param>
|
|
|
|
<!-- JKESS: 2/2/2000: whatToShow changed from long to unsigned long -->
|
|
<param name="whatToShow" type="unsigned long" attr="in">
|
|
<descr>
|
|
<p>This flag specifies which node types may appear in the logical view of the
|
|
tree presented by the iterator. See the description of <code>NodeFilter</code>
|
|
for the set of possible <code>SHOW_</code> values.</p>
|
|
<p>These flags can be combined using <code>OR</code>.</p>
|
|
</descr>
|
|
</param>
|
|
<param name="filter" type="NodeFilter" attr="in">
|
|
<descr>
|
|
<p>The <code>NodeFilter</code> to be used with this <code>TreeWalker</code>, or
|
|
<code>null</code> to indicate no filter.</p>
|
|
</descr>
|
|
</param>
|
|
<param name="entityReferenceExpansion" type="boolean" attr="in">
|
|
<descr>
|
|
<p>The value of this flag determines whether entity reference nodes are
|
|
expanded.</p>
|
|
</descr>
|
|
</param>
|
|
</parameters>
|
|
<returns type="NodeIterator">
|
|
<descr>
|
|
<p>The newly created <code>NodeIterator</code>.</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
<exception name="DOMException">
|
|
<descr>
|
|
<p>NOT_SUPPORTED_ERR: Raised if the specified <code>root</code> is
|
|
<code>null</code>.</p>
|
|
</descr>
|
|
</exception>
|
|
</raises>
|
|
</method>
|
|
<method name="createTreeWalker" id="NodeIteratorFactory-createTreeWalker">
|
|
<descr>
|
|
<p>Create a new <code>TreeWalker</code> over the subtree rooted at the
|
|
specified node.</p>
|
|
</descr>
|
|
<parameters>
|
|
<param name="root" type="Node" attr="in">
|
|
<descr>
|
|
<p>The node which will serve as the <code>root</code> for the
|
|
<code>TreeWalker</code>. The <code>whatToShow</code> flags and the
|
|
<code>NodeFilter</code> are not considered when setting this value; any node
|
|
type will be accepted as the <code>root</code>. The <code>currentNode</code> of
|
|
the <code>TreeWalker</code> is initialized to this node, whether or not it is
|
|
visible. The <code>root</code> functions as a stopping point for traversal
|
|
methods that look upward in the document structure, such as
|
|
<code>parentNode</code> and nextNode. The <code>root</code> must not be
|
|
<code>null</code>.</p>
|
|
</descr>
|
|
</param>
|
|
|
|
<!-- JKESS: 2/2/2000: whatToShow changed from long to unsigned long -->
|
|
<param name="whatToShow" type="unsigned long" attr="in">
|
|
<descr>
|
|
<p>This flag specifies which node types may appear in the logical view of the
|
|
tree presented by the tree-walker. See the description of
|
|
<code>NodeFilter</code> for the set of possible SHOW_ values.</p>
|
|
<p>These flags can be combined using <code>OR</code>.</p>
|
|
</descr>
|
|
</param>
|
|
<param name="filter" type="NodeFilter" attr="in">
|
|
<descr>
|
|
<p>The <code>NodeFilter</code> to be used with this <code>TreeWalker</code>, or
|
|
<code>null</code> to indicate no filter.</p>
|
|
</descr>
|
|
</param>
|
|
<param name="entityReferenceExpansion" type="boolean" attr="in">
|
|
<descr>
|
|
<p>If this flag is false, the contents of <code>EntityReference</code> nodes
|
|
are not presented in the logical view.</p>
|
|
</descr>
|
|
</param>
|
|
</parameters>
|
|
<returns type="TreeWalker">
|
|
<descr>
|
|
<p>The newly created <code>TreeWalker</code>.</p>
|
|
</descr>
|
|
</returns>
|
|
<raises>
|
|
<exception name="DOMException">
|
|
<descr>
|
|
<p> NOT_SUPPORTED_ERR: Raised if the specified <code>root</code> is
|
|
<code>null</code>.</p>
|
|
</descr>
|
|
</exception>
|
|
</raises>
|
|
</method>
|
|
</interface>
|
|
</definitions>
|
|
</div2>
|
|
</div1>
|