[jdom-interest] element iterator - code
David Kavanagh
dak at dotech.com
Sat Jul 27 23:04:30 PDT 2002
I was in need of an element iterator (or tree walker) for JDOM and
searched the archives on that topic. I know one is not included with
JDOM. I just thought I'd post the one I wrote. I (or someone) could
refactor this to remove references to some interfaces I use (which I've
included for compilation reasons). Any interest in seeing this as port
of a org.jdom.util package? I'd certainly be willing to contribute it.
You'll notice it was called AnakinTreeWalker. I had another
implementation that was called LukeTreeWalker that used the crimson
TreeWalker as a delegate. If it were to be included in jdom.util, I'm
sure we could name it in the least humerous, and utilitarian way
possible! :-)
BTW, this basicly does an in-order traversal of the elements in the
tree, from a root provided. A tag name can be provided to filter the
responses. I often use it in this way to find all instances of a given tag.
David Kavanagh
-------------- next part --------------
// Copyright 1998,1999,2000 Xerox Corporation, All Rights Reserved
// Xerox Digital Imaging Business Unit
package com.xerox.pix.template.xml2;
import java.util.List;
import org.jdom.Element;
import com.xerox.pix.template.ElementIterator;
import com.xerox.pix.template.TemplateElement;
//import com.dotech.GenericFactory;
/**
* This class implements an ElementIterator
*
* @version $Revision$ $Date$
* @author D. Kavanagh
* @author developer at dotech.com
*/
public class AnakinTreeWalker implements ElementIterator {
private Element root;
private Element current;
private List sibs;
private boolean visitChildren;
private String tagTarget;
/**
* This method initializes the starting point for the search.
*
* @param root the starting element
*/
public void initialize(TemplateElement root) {
// GenericFactory.debugMax( this, "Root element is " + root.getClass().getName() );
this.root = (Element)root;
this.current = (Element)root;
this.sibs = null;
this.visitChildren = false;
this.tagTarget = null;
}
/**
* Returns the current element in the search.
*
* @return current search element
*/
public TemplateElement getCurrent() {
if (current == null)
throw new NullPointerException("Element not set.");
return (TemplateElement)this.current;
}
/**
* This method returns the next element matching the search
* criteria. It uses the last available tag target. If none
* is available, the next available element is returned.
*
* @return next search element, null if search complete
*/
public TemplateElement getNext() {
if (current == null)
throw new NullPointerException("Element not set.");
Element el = findNextElement();
while (el != null) {
if (this.tagTarget == null || el.getName().equals(this.tagTarget))
if (el instanceof TemplateElement)
break;
el = findNextElement();
}
// GenericFactory.debugMax(this, "returning : "+((el!=null)?el.getName():null));
return (TemplateElement)el;
}
/**
* This method returns the next element matching the tag
* passed in. The tag can be different each time this is
* method is called. The tag will be used in future calls
* to getNext().
*
* @param tag the target tag name
* @return next search element, null if search complete
*/
public TemplateElement getNextElement(String tag) {
if (current == null)
throw new NullPointerException("Element not set.");
this.tagTarget = tag;
return getNext();
}
/**
* This method resets the search to the initial node.
*/
public void reset() {
if (current == null)
throw new NullPointerException("Element not set.");
this.current = this.root;
this.sibs = null;
this.visitChildren = false;
}
private Element findNextElement() {
if (this.sibs == null) {
if (this.current.hasChildren()) {
this.sibs = this.current.getChildren();
this.current = (Element)this.sibs.get(0);
this.visitChildren = true;
// GenericFactory.debugMax(this, "returning first child");
return this.current;
}
else {
// GenericFactory.debugMax(this, "returning null - end");
return null;
}
}
else {
int idx = this.sibs.indexOf(this.current);
// GenericFactory.debugMax(this, "sibs : "+idx+" of "+this.sibs.size());
if (idx == (this.sibs.size()-1) && !visitChildren) { // pop back up a level
this.current = this.current.getParent();
if (this.current == this.root) {
// GenericFactory.debugMax(this, "returning null - end");
return null; // done.
}
else {
this.sibs = this.current.getParent().getChildren();
this.visitChildren = false;
return findNextElement();
}
}
else {
if (!this.visitChildren) { // return next sibling
this.current = (Element)this.sibs.get(idx+1);
this.visitChildren = true;
// GenericFactory.debugMax(this, "returning next sib");
return this.current;
}
else { // dive down
this.visitChildren = false;
if (this.current.hasChildren()) { // check early, save a call
this.sibs = null;
return findNextElement();
}
else {
return findNextElement();
}
}
}
}
}
}
-------------- next part --------------
// Copyright 1998,1999,2000 Xerox Corporation, All Rights Reserved
// Xerox Digital Imaging Business Unit
package com.xerox.pix.template;
/**
* This interface defines an iterator for retreiving elements from anwhere
* in the product tree.
*
* @version $Revision: 1.1.1.1 $ $Date: 2000/07/21 20:31:38 $
* @author D. Kavanagh
* @author developer at dotech.com
*/
public interface ElementIterator {
/**
* Sets the starting point in the product tree
*
* @param root the starting element
*/
public void initialize(TemplateElement root);
/**
* Returns the current elmeent
*/
public TemplateElement getCurrent();
/**
* Returns the next element in the product tree (becomes the current).
*/
public TemplateElement getNext();
/**
* Returns the next element by name (makes that current).
*
* @param tag the name of the element type to look for
*/
public TemplateElement getNextElement(String tag);
/**
* Sets the current node back to the root
*/
public void reset();
}
-------------- next part --------------
// Copyright 1998,1999,2000 Xerox Corporation, All Rights Reserved
// Xerox Digital Imaging Business Unit
package com.xerox.pix.template;
/**
* This interface is a base for all element interfaces.
*
* @version $Revision: 1.4 $ $Date: 2002/07/27 17:38:37 $
* @author D. Kavanagh
* @author developer at dotech.com
*/
public interface TemplateElement {
/**
* Get the direct children of this template element if there are any
* May return null if no children exist
**/
TemplateElement [] getChildElements();
/**
* Get the parent of this object if it has one
**/
TemplateElement getParentElement();
}
More information about the jdom-interest
mailing list