XStream is an open source library for serializing Java objects to and from XML. Compared to Castor, another similar library, it is simpler and requires less configuration. XStream can be downloaded from here.
The data in this example represents musical artists, their recordings, and tracks on those recordings. There is a Java Bean class for each of these kinds of data named Artist, Recording and Track.
The example is built and run using Ant. For details, see build.properties and build.xml.
A few utility classes were written to simplify the code. These include ObjectUtil, SystemUtil and
Once armed with the preceding code, using XStream can be as simple as the following code implemented as a JUnit 4 test case.
package com.ociweb.demo; import com.thoughtworks.xstream.XStream; import java.util.*; import org.junit.*; import static com.ociweb.lang.SystemUtil.*; import static org.junit.Assert.*; public class XStreamTest { private XStream xstream = new XStream(); @Before public void setup() { // Setting up these aliases isn't necesssary, // but it makes the XML look nicer. // Otherwise the element names are fully-qualfied class names. xstream.alias("artist", Artist.class); xstream.alias("recording", Recording.class); xstream.alias("track", Track.class); } /** * This tests converting a object to XStream when the object * has a field that holds a collection of references to other objects. */ @Test public void testObjectConvert() { Artist a = new Artist("Regina Spektor"); a.addRecording("Soviet Kitch", 2003); a.addRecording("Begin To Hope", 2006); Object expected = a; String xml = xstream.toXML(expected); out(xml + "\n"); // for debugging Object actual = xstream.fromXML(xml); assertEquals(expected, actual); } /** * This tests converting an array of objects to XStream when the objects * have a field that holds a collection of references to other objects. */ @Test public void testArrayConvert() { Listartists = new ArrayList (); Artist a = new Artist("Deathcab For Cutie"); artists.add(a); Recording r = a.addRecording("We Have the Facts and We're Voting Yes", 2000); a.addRecording("The Photo Album", 2001); a.addRecording("You Can Play These Songs With Chords", 2002); a.addRecording("Transatlanticism", 2003); a.addRecording("Plans", 2005); a = new Artist("Regina Spektor"); artists.add(a); r = a.addRecording("Begin To Hope", 2006); r.addTrack("20 Years Of Snow", 4); r = a.addRecording("Soviet Kitch", 2003); r.addTrack("Chemo Limo", 4); r.addTrack("Somedays", 5); Object[] expected = artists.toArray(); String xml = xstream.toXML(expected); out(xml + "\n"); // for debugging Object[] actual = (Object[]) xstream.fromXML(xml); assertEquals(expected, actual); } /** * This tests converting a collection to XStream. */ @Test public void testCollectionConvert() { List colors = new ArrayList (); colors.add("red"); colors.add("green"); colors.add("blue"); List expected = colors; String xml = xstream.toXML(expected); out(xml + "\n"); // for debugging Object actual = xstream.fromXML(xml); assertEquals(expected, actual); } }
Here's the XML that is produced by XStream in this example. It's very readable! Note the "reference" attributes that use relative XPath expressions to avoid circular references.
<artist> <name>Regina Spektor</name> <recordings> <recording> <artist reference="../../.."/> <tracks/> <title>Soviet Kitch</title> <year>2003</year> </recording> <recording> <artist reference="../../.."/> <tracks/> <title>Begin To Hope</title> <year>2006</year> </recording> </recordings> </artist> <object-array> <artist> <name>Deathcab For Cutie</name> <recordings> <recording> <artist reference="../../.."/> <tracks/> <title>We Have the Facts and We're Voting Yes</title> <year>2000</year> </recording> <recording> <artist reference="../../.."/> <tracks/> <title>The Photo Album</title> <year>2001</year> </recording> <recording> <artist reference="../../.."/> <tracks/> <title>You Can Play These Songs With Chords</title> <year>2002</year> </recording> <recording> <artist reference="../../.."/> <tracks/> <title>Transatlanticism</title> <year>2003</year> </recording> <recording> <artist reference="../../.."/> <tracks/> <title>Plans</title> <year>2005</year> </recording> </recordings> </artist> <artist> <name>Regina Spektor</name> <recordings> <recording> <artist reference="../../.."/> <tracks> <track> <recording reference="../../.."/> <name>20 Years Of Snow</name> <rating>4</rating> </track> </tracks> <title>Begin To Hope</title> <year>2006</year> </recording> <recording> <artist reference="../../.."/> <tracks> <track> <recording reference="../../.."/> <name>Chemo Limo</name> <rating>4</rating> </track> <track> <recording reference="../../.."/> <name>Somedays</name> <rating>5</rating> </track> </tracks> <title>Soviet Kitch</title> <year>2003</year> </recording> </recordings> </artist> </object-array> <list> <string>red</string> <string>green</string> <string>blue</string> </list>
An XStream object can be configured to output XML differently than the default. Common examples include the following.
xstream.useAttributeFor(MyClass.class, "fieldName");
xstream.omitField(MyClass.class, "fieldName");
Copyright © 2007 Object Computing, Inc. All rights reserved.