xml-general mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Pickering <mp_s...@yahoo.com>
Subject Re: Using XML to create Java objects
Date Thu, 31 Oct 2002 22:31:21 GMT
I think a xml to object mapper that doesn't need any
config filoes like Digester is worthwile, and I would
love to try it out.&nbsp; I like Digester and JAXB,
JAXme, etc, but I still think these are not the end of
the story.

If had known about Digester, I probably have never
written Alchemy.  I wanted a way to load object
structures easily without the hassle of writing a
serialization tool and have something that lets me
tweak values easily.

Maybe it will help if I describe what my engine does
and then you can contrast it with Digester.  The two
could certainly be considered complementary.

You register the tags that serve as the start of an
object mapping.  You can do this either
programmatically by calling addMapping() in the engine
or via a set of directives you embed in your XML
document.  This is the only configuration information
the engine needs.  You can do other things (such as
add constant redefines and method name prefixes, but
out of the box the engine is functional with minimal
config).  The embedded configuration is my preferred

Once you register the object mappings, you set an
object listener on the engine.  This listener is where
the engine will send the instantiated objects.  Once
registered, you call transmuteXML() with the path to
the XML file or an InputStream to read the XML from. 
The engine does the rest and broadcasts the objects it
creates to the listener.  It is up to you to react to
the incoming objects.

The XML itself defines the methods that get called and
the parameters to use.  The names of the tags
correspond to the names of the methods in the object
you want to call.  Attributes and tag values become
arguments to the method.  The engine uses bean
patterns to determine the method name.  Several
default method name prefixes are provided.  For
example, if the tag <amount>15</amount> appears in the
XML, the engine will look for a method that takes a
single argument with one of the following names:
setAmount, addAmount, putAmount, isAmount, amount.  It
takes the first match it finds in name and number of

Once it has the method, it asks the method for the
number and type of arguments and translates all the
arguments into their appropriate types.  An internal
parameter factory constructs the argument list and the
method gets called.  

For methods that take objects as arguments, you
provide a mapping for the object type and nest the XML
that defines it under its parent tag.

This is kind of a high level view.  An example here
helps illustrate:

Here is an XML document you can use to create a Java
Properties object.

  <twgp:mapping parentTag="*" tag="myprops"
    <property key="prop1" value="value1"/>
    <property key="prop2" value="value2"/>
    <put key="prop3" value="value3"/>

>From a code perspective, you would do this:

public void objectExtracted(Object obj)
  // Objects created by the engine from XML get
  // broadcast here.

AlchemyEngine engine = AlchemyEngine.getInstance();

That's it.

If you were to run this sample, a Properties object
would be set to objectExtracted() with the values
prop1=value1, prop2=value2, prop3=value3.  You add
additional property sets with the myprops tag or add
new objects.  Tags that don't have mappings are simply

Admittedly, this is a simple example, but serves to
illustrate how the engine resolves method names and
parameter types automatically.  I don't want to chew
up list space with too much chatter.

The engine can handle very deep object hierarchies. 
Bascially, the structure of your code determines the
engine's behavior.  I've been writing up a user's
guide for it for those that might be interested.

The difference I see between my work and Digester is I
only need to tell Alchemy what tag serves as the start
of an object.  That's what the mapping does.  From
there, Alchemy instantiates the object (default and
multiargument constructors are supported) and then
uses the tag names, attributes and values to
interrogate the object and determine the best method
to call.  It operates in both strict and open modes. 
Strict mode (the default) fails any XML document that
doesn't conform to the object's structure.  Open mode
broadcasts warnings, will do partial initialization
and ignore very broken object mappings.  I do not need
to tell the engine about parameter names or types.  It
figures it out via reflection and constructs the
appropriate parameter lists itself.

Consider my work "Digester Lite" or "Digester + self
writing mapping rules".  I could probably use my work
to build an extension to Digester that writes its own
mapping rules on the fly for an arbitrary XML

I see them as complementary.  XML used by Alchemy maps
directly onto method names.  Digester lets you alias
tags to methods.  Alchemy support constant definition
(i.e.  define a human value like 'Yes' for a tag value
and have it map to the value 1 when the method is
actually called) and the ability to add your own
method name prefixes.  Using Digester as inspiration,
I could easily add tag name aliasing to allow tag A to
map to a specific method with a different name than
the tag, but that crosses into what Digester does with
a rules file.  My goal was to have little to no rules.
 Alchemy is more interactive and looser than Digester.
 Alchemy even runs standalone to let you play with the
XML and see what comes out without having to write a
separate program.

If Alchemy interests anyone, I'll happily make the
code available.  My work can at least serve as yet
another approach to the problem of mapping XML onto

Matt Pickering

Do you Yahoo!?
HotJobs - Search new jobs daily now

In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          general-unsubscribe@xml.apache.org
For additional commands, e-mail: general-help@xml.apache.org

View raw message