XStream – Java to XML and Back

The Problem Statement

XStream can be used to convert a Java Object to XML and back. This tutorial aims to create a java representation of the BBC RSS. We will start with a Simple java class and gradually start adding complexity to it so that it can be converted to the BBC RSS. Note that if you are looking at a way to parse an XML, it would be a good idea to first build a java class that XStream can convert to the required XML. XStream can then use the same class to deserialize the XML. First, have a look at the BBC RSS. Your browser would have formatted it to html so look at the source to see the XML. The parent element is ‘rss’. It has a child element called ‘channel’. The ‘channel’ has some properties (title, link, image etc) and a list of news ‘item'(s). Each ‘item’ has properties set on it (title, description etc). The aim is to create a Java class that XStream can convert to the BBC RSS.

Creating an XStream Instance

The first step is to create an instance of com.thoughtworks.xstream.XStream. This class is a facade to the XStream API and provides all major functionalities. If this class does not solve your problem then you could directly call the API methods. After obtaining the instance of XStream use the fromXML method to convert the XML to a java object. Note that creating an XStream instance is an expensive operation. It is therefore advisable to create a proper instance once and then reuse it for multiple calls (even in parallel). The setup is not threadsafe but any subsequent marshalling/unmarshalling is threadsafe.

Aliases

XStream provides a very useful functionality called aliases. In our example we want to convert an instance of com.studytrails.xml.xstream.Rss to an rss element. We tell XStream that the element ‘rss’ is an ‘alias’ to ‘com.studytrails.xml.xstream.Rss’ so that XStream knows how to convert them. If we dont provide the alias while converting the object to XML then XStream would give the element the fully qualified name of the class. Aliases work for Classes as well as fields. The example below demonstrates the use of aliases.

Implicit Collection

The Channel element in BBC has a list of items. However, note that the XML stream does not have an &ltitems&gt element containing a list of &ltitem&gt elements. The XML stream just has a list of &ltitem&gt elements directly under the &ltChannel&gt element. We want to map them to the ‘items’ java.util.List of the Channel Object. To accomplish this we use a concept in XStream called Implicit Collection. we say that ‘items’ is an implicit collection. What that means is that there is actually no ‘items’ element in the XML, but put all XML elements with name ‘item’ (since the java property items is of type List&ltItem&gt) into the ‘items’ property of the java object. Look at the example to see how it works.

Attributes

Handling attributes is a little tricky. In this example we provide one way to handle attributes, however, we have a dedicated tutorial to explain how attributes can be handled using XStream.

Namespaces

Elements within a namespace can be handled by XStream by using aliases. In this example there is a link within the namespace atom. we just use an alias to read that

Example

Lets start building the java example. As a first step create a Java class for the root element i.e. RSS

The output

We dont want the fully qualified name of the class for Rss. Lets use alias to simplify the name. Add this line after creating the Rss instance

The output now becomes

The rss elmenent contains a Channel element. Lets create a Channel class. The channel element is a child of rss element. Create a field in the Rss class to hold an object of type Channel. Add these lines to the main method

Here’s how the Rss and Channel class looks now

Here’s how the XML looks now

Before we start adding fields to the classes lets look at an important field. The channel element contains this :

the link element belongs to a different namespace. There is a neat little trick to handle this.

Create a class called AtomLink.

Create an instance of AtomLink in the main class and assign it to a field in the Channel class

Use alias to give the element a namespace prefix

and now we want href, rel and type to be attributes instead of child elements, this is how we do that

Lets see how our XML looks now

Hope you are enjoying the example. It is important that you understand what’s happened so far. Go back to the example if you have any doubt since we will start picking up pace now.

The next important part is the
item
. The channel contains a list of items but the items are not included in a parent
‘items’
element. XStream handles this using a concept called
Implicit Collection
. Lets see how it works, first lets create the Item class

create a field in channel class to hold the list of items

In the main class we create an alias for Item and then add an implicit Collection for items. We add two items to the list and see how the XML looks.

The resulting XML

Next we add class for the Thumbnail which is part of the item element. An item can have multiple thumbnails. Lets use an array now instead of a Collection just to demonstrate how an ImplicitArray works.

The main method creates the array and adds thumbnails to it

We have almost built up the whole class. We can further add the Image class that stores the image in a channel. After creating all classes we start adding the other fields to them. Once the Rss class is ready you can then use it to read the BBC RRS! Heres the complete class and the main method that does the reading.

The classes

Leave a Reply

Your email address will not be published. Required fields are marked *