| The Easiest Java XML Binding |
|
|
|
| Written by John Valentino |
| Monday, 23 February 2009 10:28 |
|
I have an XML document and I want to use that document to populate a corresponding set of Java objects. This is a commonly encountered scenario when working with Java, so what is the easiest method for Java XML Binding that requires the least amount of code? You can't answer that question without first defining what "easy" is in relation to the bindings between Java and XML. To me "easy" is synonymous with "simple," so I am equating easiness to complexity. Complexity is of interest because things that are complex take longer to implement and are generally harder to maintain, based on my experiences with software in a variety of languages and platforms. Less code written means less code to maintain, and less code to write means less time is required to write that code. So what are the methods for binding Java and XML?
I have used all of these methods in depth before, but this isn't exactly what I want though:
My usage of Adobe Flex (http://jvalentino.blogspot.com/2008/02/flex-tutorial-part-ii-language-concepts.html) over the last couple of years has spoiled my expectations for language and XML interaction; I want more with less. I know exactly what I want: I want to have a series of Java objects that are representations of nodes within an XML document, and pass the XML document to the Java object representing the root XML node and have all of the corresponding Java objects populate using that XML. I then want to be able to go from Java back to XML, and I don't want to have to do anything other then say "XML, go to Java" and then "Java, go to XML." Why should there need to be complex mappings and external definitions when Java and XML are being used to representing the same thing? Consider an RSS 2.0 document and what it represents: version="1.0"?> Document from http://en.wikipedia.org/wiki/RSS_(file_format) An "rss" node has a "channel" node, a "channel" node has "item" nodes, and every node has their own properties and attributes. These relationships can then be represented in terms of objects using a class diagram (ignoring methods for getters and setters): From this class diagram it is then possible to generate the corresponding Java classes, assuming that the class fields have the same names as their corresponding XML nodes. This can't always work though since class fields can be represented in XML as properties or attributes, so it would be necessary to designate this in Java. You may also not want to have the Java class field names the same as the XML node names, so there would need to be a way to designate this as well. One easy way to designate specific things about classes, fields, and methods is to use annotations, so consider the following 3 annotations:
@ClassXmlNodeName("rss") With the exception of the annotations, these Java classes are just like any other data transfer objects (DTOs) that would be used to represent a RSS XML document. These annotations act as the mappings between Java and XML when names and types do not provide enough information. With this information, the class representing the XML document root node, and the XML document it is possible to recursively map XML nodes to Java class fields and Java class fields back to XML nodes using Reflection. So using Reflection I wrote a library that can take any Plain Old Java Object (POJO) and an XML document, and use that XML document to populate that object and all of its child objects using one line of code. The same can then be done to convert a Java object back to its XML representation using a single line of code. All of this assuming that the Java classes correspond to the XML document. Using this "XML Binder" library the following code takes the the given instance of an Rss object and populates it and its channels and items using the given XML document: Rss rss = new Rss(); The following code can then be used to take that same Rss object once changes have been made to it and converts it back to XML: String xml = XmlBinderFactory.newInstance().toXML(rss); I assert that this can work with most XML documents that have appropriate corresponding Java classes, but I have only tested it out so far with RSS 1.0, RSS 2.0, and a general test XML document in no particular format. The question now is what do I do with this library; anyone interested? Since there seems to be some interest I have started a sourceforge.net project called "Really Easy Java XML Binding" or "RE:JAXB" since this is sort of a reply to JAXB. Here is the link I have included POJOs for RSS 1.0 and RSS 2.0 along with unit tests to verify that the mappings from XML and to XML are working correctly. What I am looking for are ways to improve the efficiency of the to and from binding code, as well as POJOs for other common XML formats. |



