Java, XML and XStream

What’s an object/xml serializaing/deserializaing library?

If you’ve never worked with an object/xml serializer and are considering writing your own from scratch, you may want to consider using a library like XStream. XStream is very good at moving java into xml and back. It allows a high level of control over how the xml can be organized and structured and even allows the user to create their own converters for even more flexibility.

But still, why use something like this when you can be perfectly happy writing your own data conversion scheme? The problem really boils down to flexibility, and in reinventing the wheel. Ninety percent of the time you’re already interrogating a datasource (like some rdbm system like oracle, postgres or mysql) and will be using some kind of TransferObject or maybe an Entity persistence scheme built around pojos. If you write your own serializing engine from scratch by mapping pojos to dom4j nodes, constructing Document objects and then using them for stuff like xsl transformations, you end up missing out on a great tool.

It may not seem obvious right now, but a homegrown serializer is the kind of thing you can write once and forget about and then months or years down the line, when it comes time to update your data model or expand its framework, you end up rebuilding all the dom4j stuff from scratch. Unless you take the lazy route and append and new xml to the root node to save yourself the entire node refactor. Maybe simple objects with one or two simple nested objects wont seem like much, but if your object becomes anything close to approaching a complex lattice, then going back and tweaking the entire structure when you want to expand or refactor your xml can become quite perilous. Especially if you want to make your xml as xpath friendly as possible.

Edit:
As Felipe Gaucho has been kind enough to point out, Xstream only writes a text string as the serialized object. It will not preform any validation on your XML, so you’re left on your own validate it post serialization. Something like JAXP comes to mind to tackle XSD based validation, or JiBX if you’re looking for Data Binding.

So what does XStream do for me?

Consider these objects:

 public class MyClass {

	protected MyObject object;
	
}
public class MyObject {

	protected ArrayList Field;
	
}

XStream lets you do something like this if you want to serialize an object like MyClass to xml:

 XStream xstream = new XStream();
String myClassXML= xstream.toXML(myClassObject);

and if you want to go from xml back to a java object you can do this:

 XStream xstream = new XStream();
MyClass myClassObject= xstream.fromXML(myClassXML);

As you can see, all the plumbing goes away and you are now free to concentrate on writing the rest of your application. And if you want change your object model, consolidate nodes or rearrange the structure of your xml, all you have to do is update your pojo and your xml immediately will reflect the updated changes in the data model on serialization.

It should be noted that to completely deserialize xml, your object needs to correctly map all the data in the xml. If you have trouble deserializing try building a mock object and populating it with sample values and then serialize it to xml; then you can compare the test xml to what your actual xml is and make your changes.

Alilasing

XStream does not require any configuration, although the xml produced out of the box will likely not be the easiest to read. It will serialize objects into xml nodes according to their package names, usually making them very long as we can see from the following example:

<com.package.something.MyClass>
	<com.package.something.MyObject>
		<List>
			<com.package.something.Field/>
			<com.package.something.Field/>
		</List>
	</com.package.something.MyObject>
</com.package.something.MyClass>

Luckily XStream has a mechanism we can use to alias these long package names. It goes something like this:

XStream xstream = new XStream();
xstream.alias("MyClass", MyClass.class);
xstream.alias("MyObject", MyObject.class);
xstream.alias("Field", Field.class);

Adding an alias like this will let your xml come across nice and neat like this:

 <MyClass>
	<MyObject>
		<List>
			<Field/>
			<Field/>
		<List>
	</MyObject>
</MyClass>

Attributes

If you want to make a regular text node an attribute, you can use this call to configure it:

 xstream.useAttributeFor(Field.class, "name");

This will change make your xml change from this:

 <MyClass>
	<MyObject>
		<List>
			<Field/>
				<name>foo</name>
			<Field/>
		<List>
	</MyObject>
</MyClass>

into

 <MyClass>
	<MyObject>
		<List>
			<Field name="foo"/>
			<Field/>
		<List>
	</MyObject>
</MyClass>

ArrayList (implicit collections)

ArrayLists are a little tricker. This is what they look like out of the box:

 ...
	<MyObject>
		<List>
			<Field/>
			<Field/>
		</List>
	<MyObject>
...

Note theres an extra “List” node enclosing the List elements name “Field”. If we want to get rid of that node so that Field is right under Object, we could tell XStream to map an implicit collection by doing the following:

 xstream.addImplicitCollection(MyObject.class, "Field", "Field", Field.class);

where the addImplicitCollection method signature is the following:

 /**
	 * Appends an implicit collection to an object for serializaion
	 * 
	 * @param ownerType - class owning the implicit collection (class owner)
	 * @param fieldName - name of the field in the ownerType (Java field name)
	 * @param itemFieldName - name of the implicit collection (XML node name)
	 * @param itemType - item type to be aliases be the itemFieldName (class owned)
	 */
	public void addImplicitCollection(Class ownerType,
            String fieldName,
            String itemFieldName,
            Class itemType) 

Adding this implicit collection configuration will streamline the xml so that it looks like this now:

 
<MyClass>
	<MyObject>
		<Field/>
		<Field/>
	</MyObject>
</MyClass>

Notice the “List” node is gone, and “Field” is now directly under “MyObject”. You can find the complete documentation on the XStream website here.

There are plenty of more tricks you can use to configure/format your xml, and there are plenty of examples listed on the XStream website, but these three points here should cover the basics to get you started.



Related posts:

  1. API Links
  2. All things XPath
  3. Ejb3 basics: Entities

Comments (9)

  1. avatar

    5:33 pm, February 3, 2010Steve Mactaggart  / Reply

    Its also useful to know that there are annotations to do the configuration of the entities.

    • avatar

      7:34 pm, February 3, 2010Ant  / Reply

      Yes, you’re right. Thats one of the topics I want to cover soon. I’ve also been looking at the Simple API, its a pretty good alternative if you’re running 1.5+.

  2. avatar

    7:24 am, February 12, 2010Felipe Gaucho  / Reply

    Just include a hint to the readers about the lack of validation mechanism in XStream, so what the framework call XML it is in reality “plain text written in XML format”.. completely different things..

    • avatar

      10:33 am, February 12, 2010Ant  / Reply

      Quite correct – I will update the article to make that clear. Thanks!

  3. avatar

    9:29 am, February 12, 2010Brujo  / Reply

    Hi there, nice article, I like more Jibx to parse xml, but xstream it’s great too.

    Regards.

  4. avatar

    5:14 pm, February 12, 2010rich  / Reply

    I recently tried to use xstream in a live project and it was a bit of a nightmare. Wasted days building a framework around it for it to do what I wanted. Got jibx working in an hour and there is still a lot about jibx I don’t understand but I don’t need to because it just does what I want, easily out of the box. I’d recommend taking a look at it before xstream

    • avatar

      5:52 pm, February 12, 2010Ant  / Reply

      I’m surprised about your experience, what were you trying to do? JiBX is entirely different although serialization is a common feature amoung the two. One thing that really sticks out for me is that XStream doesn’t go into the xsd/validation space, as Felipe points out.

  5. avatar

    4:52 am, November 10, 2011jalpa bhaliya  / Reply

    This is the nice article. I have one problem that if once we created an xml file and if i want to add some more objects within it then how can we achieve it??
    for example, if i have xml file like…

    and if i want to add 1 new then how can i do this (without replacing whole list)?? so that my file can look like…

    • avatar

      1:15 am, January 4, 2012Ant  / Reply

      I can’t see your example, but If you’re talking about adding multiple objects as an array, then you would want to use a collections construct like an array to add multiple objects. In fact XStream has some useful annotations for handling implicit collections.

Pingbacks (2)

  1. 3:04 am, March 9, 2010Favicon of data.this1smyniche.infodata x stream | DATA