- Simple API For XML Version 2 (SAX2)
- Auxiliary SAX Interfaces
- SAX and I/O
- SAX Error Handling
- The Glue of SAX: XMLReader
- The Document Object Model
- The Object Model
- The DOM and Factories
- The Node Interface
- Parents and Children
- Nonhierarchical Nodes
- Text Nodes
- Element and Attribute Nodes
- Document, Document Type, and Entity Nodes
- Bulk Insertion Using Document Fragment
- DOM Error Handling
- Implementation vs Interface
- DOM Traversal
- Where Are We?
DOM Traversal
DOM Level 2 defines an optional DOM feature referred to as DOM Traversal. DOM implementations can be tested for DOM Traversal support through the DOMImplementation.hasFeature method. Although DOM traversal can be accomplished through the Node and NodeList interfaces, the DOM WG decided it was beneficial to define standard traversal interfaces that simplify the process.
DOM Traversal defines two types of node traversal mechanisms: Node Iterators and TreeWalkers. NodeIterator traverses a list of nodes (much like the NodeList interface), whereas TreeWalker traverses a tree of nodes (much like the Node interface). The NodeIterator interface has two traversal methods, nextNode and previousNode, for moving back and forth through a list of nodes. The TreeWalker interface, on the other hand, contains the same traversal functionality as the Node interface (such as firstChild, lastChild, nextSibling, previousSibling, nextNode, previous Node, and so on) for moving throughout a tree hierarchy.
The DocumentTraversal interface is used to create NodeIterator and TreeWalker instances through the corresponding createXXX methods. Document implementations supporting DOM Traversal will also implement the DocumentTraversal interface.
package org.w3c.dom.traversal; 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); };
The main benefit that these traversal mechanisms have over using the standard Node/NodeList interfaces relates to filtering. When creating NodeIterators and TreeWalkerS, one can specify a bitmask (whatToShow) indicating which node types are desired. For example, the following code demonstrates how to create a NodeIterator that only traverses Text and Comment nodes:
import org.w3c.dom.traversal.NodeIterator; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.Document; NodeIterator getTextAndComments(Document doc) { try { DocumentTraversal dt = (DocumentTraversal)doc; return dt.createNodeIterator(doc, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT, null, true); } catch (ClassCastException ex) { return null; // traversal not supported } }
Applications can also write custom filters that extend the NodeFilter interface. The NodeFilter interface contains one method, acceptNode, which will be called during the traversal process to let the application decide whether to include/exclude a given node from the traversal. The following class, MyFilter, only includes nodes with a name of "author".
class MyFilter implements NodeFilter { public short acceptNode(Node p1) { if (p1.getNodeName() == "author") return NodeFilter.FILTER_ACCEPT; else return NodeFilter.FILTER_SKIP; } }
An instance of MyFilter can be passed to the createXXX methods of DocumentTraversal to further qualify the node subset as shown here.
NodeIterator iter = dt.createNodeIterator(rootNode, NodeFilter.SHOW_ALL, new MyFilter(), true); Node n = iter.nextNode(); while (n != null) { // do something here with "author" nodes n = iter.nextNode(); }
DOM Traversal filters make it possible to create customized and reusable traversal components that simplify the process of walking a DOM tree and locating specific DOM nodes.