[jdom-interest] API Inertia

philip.nelson at omniresources.com philip.nelson at omniresources.com
Thu May 3 07:47:23 PDT 2001


> > So let's not be so sure that we really don't want client programmers
> > to create their own Node subclasses/implementations.
> 
> That seems weird to me. Why are these "Nodes" (i.e. XML 
> objects)? Can they be
> added to an XML document? What should XMLOutputter do when it 
> sees them?

We could do this with a Decorator.  In this scenario, each decorator would
be free to implement the Node interfaces it want's, or any other interface
for that matter.  I have included some code I threw together this AM as a
proof of concept.  This code does a full traversal of a simple document with
elements and attributes only and produces nodes of the JDOMNode type I show
here.  There are no subclasses of core JDOM types.  You could change the
node interface and implement it any way you want.  Because it's a decorator,
you could even add additional decorators to do other cool things like proxy,
validation, listeners etc..  The docorators can be added during the build,
as in this demo or at any point in the run time.

In this quicky demo, I have made partial decorators of Element and Attribute
that inherit from the underlying jdom classes.  This would probably be done
better if we go ahead and do the Factory method that Ken (?) submitted
because then the decorator could be based on a default decorator that would
have all the methods defaulted to delegate to the base type for you (and use
the Element/Attribute interfaces for type compatibility).  In addition,
there will be some problems where the decorator can't access protected
methods.  Decorator has some other consequences of course but since we
wouldn't have to make this a core change, a programmer could deal with it.

I based this on my version of JDOM with the EntityRef class included so you
have to incorporate that if you want to prove that this works, sorry.  The
method for building is a hack that we need to make a separate decision on:
how to allow use of subclasses, factory, subclass etc..


Here is how the example works

	public static void printNodes(List data) {

		Iterator it = data.iterator();

		while (it.hasNext()) {
			JDOMNode node = (JDOMNode) it.next();
			System.out.println(node.getName());
			System.out.println(node.getValue());
			List kids = node.getChildren();
			printNodes(kids);
		}

	}
	/**
	 * 
	 * Test building a JDOM document and traverse it.
	 * 
	 */
	public static void testBuilder() throws IOException, JDOMException {

		String data = (new StringBuffer("<?xml version=\"1.0\"
?><rootElement>")
				.append("<element name=\"1\"
attr=\"att1value1\" /><element name=\"2\" attr=\"att1value2\" />")
				.append("<element name=\"3\"
attr=\"att1value3\" >")
				.append("<child name=\"child1\" />")
				.append("</element>")
				.append("<element name=\"4\"
attr=\"att1value4\" />")
				.append("</rootElement>")
				.toString());

		SAXBuilder builder = new SAXBuilder();

		//hacky sillyness to get around the lack of a solution to
Builder/Factory methods
		Document doc = new Document(new Element("dummy"));
		builder.setSAXHandler(new TraversalSAXHandler(doc));

		builder.build(new StringReader(data));

		//let's get the nodes
		List list = doc.getMixedContent();
		printNodes(list);

	}
}

package org.jdom.contrib.traversal;

/**
 * Node interface for all JDOM types.
 * 
 * @author: Philip Nelson
 */

import java.util.List;

public interface JDOMNode {

    public List getChildren();
    public String getName();
    public String getValue();
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: traversal.zip
Type: application/octet-stream
Size: 31472 bytes
Desc: not available
Url : http://jdom.org/pipermail/jdom-interest/attachments/20010503/f6364b7f/traversal.obj


More information about the jdom-interest mailing list