I have recently had a chance to look into several XML object binding frameworks, including JAXB, Castor, and JiBX. As usual, each framework has its strengths and its weaknesses. I should add that our requirements are pretty special, as the classes that are bound to XML will form part of an SDK and therefore need to be clean, follow Java conventions, and contain good Javadocs that describe the XML properties that they are mapped to.
One of the main differences between these tools as well as some of the other tools I have investigated is whether they use a mapped approach or rely on code generation. Initially, code generation seemed like the way to go for us, because we don’t have an existing Java class hierarchy to map to and it would eliminate a lot of the tedious work. JAXB and Castor are both good code generation frameworks. For most purposes, JAXB seems like an ideal tool. First of all, it is an official Java standard. Second, it generates very clean code and interfaces, with appropriate Java naming conventions, Java 2 collection classes, etc. It is also fairly configurable, either by using a binding file or by using XML annotations inside the XML Schema document that is used as the basis for the code generation. Unfortunately, it has a few limitations that make it less ideal for our purpose, i.e. to generate classes for an SDK:
- Its support for XML lists is thoroughly lacking. For example, let’s assume the following XML structure:
<application> <user_list> <user> <name>John Doe</name> <email>email@example.com</email> <phone>123-456-7890</phone> </user> <user> <name>Robert Smith</name> <email>firstname.lastname@example.org</email> <phone>742-124-7364</phone> </user> </user_list> </application>
I would like the application element to map to a class called Application, which contains a getUserList() method that simply returns a list of User objects. However, JAXB insists on creating another class called UserList, which only contains a method called (by default) getUser() that returns the actual list of User objects. This would be fine in most cases, but it definitely would be weird in case of an SDK that is published to customers.
- The other problem is regarding Javadocs. While JAXB is smart enough to turn XML annotations into Javadocs, it also stores a lot of other junk inside the Javadocs, including the corresponding excerpt from the XML Schema. Again, normally not a problem but not ideal in our case.
Castor solves some of these problems but has its own quirks. It does not always follow Java conventions. For example, an XML element called user_list gets mapped to a Java class called User_list, rather than the desired and expected UserList. This behavior is configurable in JAXB but not in Castor. Its list support is slightly better in some ways, as the generated classes actually contain some useful methods for dealing with the list elements, but it uses old-style collection classes and Enumerators rather than Iterators.
JiBX was a very nice surprise. It follows a mapped approach (which Castor alternatively also supports) and thus requires Java classes to exist. But it is extremely flexible in how XML elements get mapped to Java properties and vice-versa. It is highly configurable, flexible, and fast. Its support for collections is by far the best I have seen in any XML object mapping framework. Using JiBX means that we will need to write Java classes after all, but they will be very lightweight JavaBeans that don’t really require any code. On the plus side, we will of course get full control over Javadocs. Also, if our XML format ever changes, we will be able to deal with most changes simply by midifying the mapping file, without having to change any code - another big plus for us, as it will allow us to more easily support a backwards-compatible SDK.
For quick and dirty (actually not all that dirty) internal XML mapping jobs, JAXB seems like the best choice. When tighter control over the mapped code is required, I strongly advise you to look into JiBX.