Dynamic adjustment of traversal depth
The task of selective traversal can be accomplished by dynamically changing the
depth of traversal for different nodes (branches). If we need to process only
the branch with ID="K.TAMURA", the initial maximum depth should be set to 2 (depth
of ID level). For the required selected ID node, depth should be adjusted to "unlimited
", so the tree iterator can process children of the node. With this approach,
maximum depth can't remain just a static parameter applied to the entire tree.
Instead, the original depth should be restored when iterator returns to the
level of parent node. In other words, depth becomes an attribute of a level and
should be kept in the stack along with other level information (such as current
node).
Calling program calls setLevelDepth() method of the iterator to
change the maximum depth value for the current node (control node). When all
children of the control node are processed and iterator returns to the control
node level, the corresponding maximum depth is restored.
import com.myarch.treeiterator.TreeIterator;
import com.myarch.treeiterator.DOMAdapter;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
/**
* Demonstrates the selecive traversal using setLevelDepth method of
* the TreeIterator .
*
*/
public class SelectiveSetDepthTraversal {
/**
* Selectively traverses the tree using setLevelDepth .
* Traverses only the branch of "K.Tamura" and ignores other branches.
*
* @param rootNode root of the DOM tree.
*/
public void traverse ( Node rootNode ) {
// create iterator, initially it is limited to the ID level
int idLevel =2;
TreeIterator tIterator = new TreeIterator ( rootNode, new DOMAdapter(), idLevel);
Node node = null;
while( ( node=(Node)tIterator.next() )!=null ){
// print node information
System.out.println( node.getNodeName()+"="+node.getNodeValue());
if ( tIterator.getDepth() == idLevel && (node instanceof Element &&
((Element)node).getAttribute( "id").equalsIgnoreCase("K.TAMURA" ))) {
// this allows iterator to traverse children of the current node
tIterator.setLevelDepth( TreeIterator.DEPTH_UNLIMITED);
}
}
}
In simple cases using skipChildren() method yields the same result. setLevelDepth() ,
however, provides much greater flexibility when it comes to more complex
selective processing. It allows for applying different maximum depth to
different branches of a tree. Some branches can be processed fully and some
partially, up to the required depth. For example, we might need to process all
levels for managers and only some levels for other entries in the personnel
file.
This approach also allows for depth nesting. setLevelDepth() can be
called multiple times, first for the topmost control node, then for the node
within the same branch that meets some additional criteria and so on. In other
words, coverage of the tree during traversal is defined by the combination of
depths specified for the given set of criteria. Every criterion in the set can
impose its own depth limitation on the tree. And no matter how complex these
criteria are, the traversal is still performed within one loop.
|