XStream: how to serialize objects to non XML formats

As you know, XStream makes it easy to serialize objects to XML:

Person person = createExamplePerson();
xstream.toXML(out);

Resulting in:

<com.blah.Person>
  <firstName>Joe</firstName>
  <lastName>Walnes</lastName>
  <homePhone>
    <areaCode>123</areaCode>
    <number>433535</number>
  </homePhone>
  <cellPhone>
    <areaCode>4545</areaCode>
    <number>4534</number>
  </cellPhone>
</com.blah.Person>

I often use this approach whilst debugging to dump out the contents of an object. I t works, but my eyes just aren’t that good at parsing XML.

By creating an alternative writer implementation, XStream can be used to serialize objects in other formats:

import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.io.PrintWriter;

/**
 * This XStream writer allows objects to be serialized to an alternative
 * indentation based syntax, rather than XML.
 *
 * DISCLAIMER: This class is provided as an example for how to create your
 * own HierarchicalStreamWriter in XStream...
 * IT IS BY NO MEANS A COMPLETE IMPLEMENTATION!
 *
 * @author Joe Walnes
 */
public class AnAlternativeWriter implements HierarchicalStreamWriter {

  private int indent;
  private final PrintWriter out;

  public AnAlternativeWriter(PrintWriter out) {
    this.out = out;
  }

  public void startNode(String name) {
    if (indent > 0) {
      out.println();
    }
    for (int i = 0; i < indent; i++) {
      out.print("  ");
    }
    out.print(name);
    indent++;
  }

  public void addAttribute(String name, String value) {
    out.print(" [" + name + "=" + value + "]");
  }

  public void setValue(String text) {
    out.print(" = " + text);
  }

  public void endNode() {
    indent--;
    if (indent == 0) {
      out.flush();
    }
  }
}

Which can be used like this:

Person person = createExamplePerson();
xstream.marshal(stuff, new AnAlternativeWriter(out));

Producing the slightly more digestible:

com.blah.Person
  firstName = Joe
  lastName = Walnes
  homePhone
    areaCode = 123
    number = 433535
  cellPhone
    areaCode = 4545
number = 4534

To gain roundtrip serialization/deserialization support in alternative formats to XML, you need to provide your own implementations of both HierarchicalStreamWriter and HierarchicalStreamReader.