XMLStream  Library Usage Examples


by John S. White,  www.machinedialog.com

This  page contains a set of examples for using  the Machine Dialog XMLStream library.  

Index

Introduction

For all but the advanced user,  use of this library is very  simple.  Suppose you have an object that you wish to serialize to an XML file
and  deserialize at a later time.  The steps you need to take are:
  1. Add the line "import com.machinedialog.xmlstream.* ;"  to the imports list..
  2. Add   "implements IXMLize"  to the object declaration
  3. Create the XMLMap objects  needed  to associate objects and tags.  Doing this once as a static method  reduces the number of  map creations and enhances readability
  4. Define the attributes for the object and any component objects.  The use of XML attributes makes the XML document much more readable.
  5. Implement asXML(...) method 
  6. Be sure to include the xmlstream library in the CLASSPATH
These steps just provide you with the capabilitiy of reading and wiriting XML streams.  Once you  have this capability you might want to use it.  The steps are quite straightforward:
  1. Create an XMLSerializer. Use  XMLSerializer.getWriter("filename") to write;  XMLSerializer.createReader("filename")  to read.
  2. Create the object you wish to read or write, call it myObject.   Be sure that it implements IXMLize
  3. Invoke the asXML( "outer tag",  myObject )  method on the XMLSerializer you created. 
The basis of this document is contained in the source DemoXML.java.   This demonstrates the most useful parts of the API including:
The code in DemoXML.java  is carefully presented and explained in  the package overview .  All users are strongly encouraged to read at least the Quick Start   section before  using the library.
.

Overview

DemoXML defines a  straightforward class for  describing a person.  A person has  a name, address, age, sex.  He or she may have a spouse, children and hobbies.  In this class, we create a DemoXML object, write it to a file, then read from the file into a new object, which we compare to the original.  At Machine Dialog, whenever we implement a class, we test the asXML(...)  method in precisely this way.   There are some additional test methods that we wrote to benchmark operations like reading and writing.  These are intended to show that the library is pretty fast, and could be suitable for use in real time.

The rest of this document consists of code fragments.

Examples

XMLSerializer.onStream(XMLIOStream strm)

// create the XMLWriteStream  
XMLWriteStream strm = new XMLWriteStream();
//create DemoXML object john and get the XMLWriteAdapter
DemoXML john = DemoXML.create("John White", 200021, true, -1000.3, 'D');
if ( strm.open("john.xml"))
{
XMLSerializer xml = XMLSerializer.onStream(strm);
// write the object to the file
john = (DemoXML)xml.asXML("Person", john);
}

XMLSerializer.getWriter(String filename)

// create XMLWriteAdapter using a filename.
XMLReadAdapter xml = XMLSerializer.getWriter("john.xml");
// create the DemoXML object john
DemoXML john = DemoXML.create("John White", 200021, true, -1000.3, 'D')
// write the object john into the file john.xml
john = xml.asXML("person", john);

XMLSerializer.getReader(String filename)

// create XMLReadAdapter using a filename.
XMLReadAdapter xml = XMLSerializer.getReader("john.xml");
DemoXML john = new DemoXML(); // create empty object
// read the file john.xml into the object john
john = xml.asXML("person", john);


XMLSerializer.close()

// create XMLReadAdapter using a filename.
XMLReadAdapter xml = XMLSerializer.getReader("john.xml");
DemoXML john = new DemoXML(); // create empty object
// read the file john.xml into the object john
john = xml.asXML("person", john);
// close the stream
xml.close();

XMLSerializer.attributes(String attr)

This method is used to set the attributes for the outer xml tag of an XMLSerializer(). The idea is to create an XMLSerializer (either read or write), then invoke this method to set the attributes.
// create XMLWriteAdapter using a filename.
XMLWriteAdapter xml = XMLSerializer.getWriter("john.xml");
// designate name, age as attributes
xml=xml.attributes("name age");
// create the DemoXML object john
DemoXML john = DemoXML.create("John White", 45, true, 160000, 'D');
// now write it out. Note that the attributes will be name, age
// the sex, income and marital status will be normal inner tags
john = xml.asXML("person", john);

Another way to use this is to create a HashSet with XMLMap.attributes() and pass the HashSet as an argument.  Truthfully, it is probably just as efficient to use a String as in the example above.
// make this a static variable
static final private HashSet Only_Name_and_Age_are_attributes = XMLMap.attributes("name age");
// create XMLWriteAdapter using a filename.
XMLWriteAdapter xml = XMLSerializer.getWriter("john.xml");
// designate name, age as attributes
xml=xml.attributes(Only_Name_and_Age_are_attributes);
...

XMLSerializer.setDefaultAttributes(HashSet attr)

Set the default attributes for a serializer . The  way to use this is to create a HashSet with XMLMap.attributes() and pass the HashSet as an argument.  
// make this a static variable
static final private HashSet Only_Name_and_Age_are_attributes = XMLMap.attributes("name age");
// create XMLWriteAdapter using a filename.
XMLWriteAdapter xml = XMLSerializer.getWriter("john.xml");
// designate name, age as attributes
xml=xml.setDefaultAttributes(Only_Name_and_Age_are_attributes);
...

XMLSerializer.asXML(String tag, primitiveType, defaultValue)


This usage note covers the asXML(..) invocation for strings and  all java primitives types: int, long, boolean, double, float , char.  Remember, you need to use this when you are implementing asXML(...) for your class.  There are two cases:
  1. There is a default value to be used when reading if the XML tag is not found in the stream
  2. There is no default value.
This section covers the first case, where there is a default value.  The general form for this in the body of your asXML(,,,) method is
   
v = asXML("tag-name", PrimitiveType v, PrimitiveType deflt)
Where PrimitiveType is any of string,  int, long, boolean, double, float , char.  So suppose the PrimitiveType is int, and the member variable we wish to serialize is called m_age,  with a default value of 31:
// define a member variable of type int
int m_age;
// ... rest of code
// implement the asXML(...) method for this object
public Object asXML(XMLSerializer xml) throws IOException{
// set the default attributes (defined elsewhere)
// This will treat Name .. marital.status as attributes
xml.setDefaultAttributes(Name_to_marital_status_are_attributes);
// other stuff
m_age = xml.asXML("Age", m_age, 31);
// and so on and so forth...
}

All the rest: long, boolean, double, float, char  look the same.  If the XMLSerializer can't find the tag it will use the default value instead.


XMLSerializer.asXML(String tag, primitiveType)


This usage note covers the asXML(..) invocation for strings and all java primitives types: int, long, boolean, double, float , char  Remember, you need to use this when you are implementing asXML(...) for your class.  There are two cases:
  1. There is a default value to be used when reading if the XML tag is not found in the stream
  2. There is no default value.
This section covers the second case, where there is no default value.  The difference between this and the first case is that when the XMLReadAdapter cannot find the XML tag-name, an exception will be thrown.  The general form for this in the body of your asXML(,,,) method is
   
v = asXML("tag-name", PrimitiveType v)
Where PrimitiveType is any of  string, int, long, boolean, double, float , char.  So suppose the PrimitiveType is int, and the member variable we wish to serialize is called m_age,  with no default value:
// define a member variable of type int
int m_age;
// ... rest of code
// implement the asXML(...) method for this object
public Object asXML(XMLSerializer xml) throws IOException{
// set the default attributes (defined elsewhere)
xml.setDefaultAttributes(Name_to_marital_status_are_attributes); // This will treat Name .. marital.status as attributes
// other stuff
m_age = xml.asXML("Age", m_age);
// and so on and so forth...
}

All the rest: string,  long, boolean, double, float, char  look the same.  If the XMLSerializer can't find the tag it will thow an IOException.


XMLSerializer.asXMLString(String aString)


This method is used to serialize  raw strings to the XML stream.  Mostly, it is used to write XML meta information  at the top of an XML file.  It will write or read the raw string at  the current document cursor.
Typical  usage is :
XMLWriteAdapter xwa=XMLSerializer.getWriter("foo.xml");
String doc_comment="<!-- This is a comment -->";
// write out the comment string
comment = xwa.asXMLString(comment);
... and so on and so forth

XMLSerializer.asXML(String tag, Object v)


This is the main method used to serialize a member object to and from an XML stream.  It is typically called from within the asXML(XMLStream strm) method that you are required by IXMLize to implement  within your class..  If your class  is a composite class with members that are objects,  those objects that you wish to serialize must  implement  this method as well.  There are four basic calls:
asXML(java.lang.String tag, java.lang.Object v);
asXML(java.lang.String tag,java.lang.Object v, java.lang.Class cls);
asXML(java.lang.Object v, XMLMap aMap);
asXML(java.lang.Object v, XMLMap aMap, java.lang.Object deflt);

The  first  just requires a tag and a reference to an  object that implements IMLize, e.g. it has an asXML(XMLSerializer xmls) method.  This is used when  the object v has already been instantiated, e.g v is not a null.. This can be used either inside the asXML(...) method defined in the class, or it can be used to populate or write out an object that has been created by an application.  Note that on reading, the tag must be present in the stream. If not found, an IllegalArgumentException is thrown with a string message indicating the missing tag.  The second method  requires a tag,  an object reference and a class  as would be returned by Class.forName(...) call.  This can be used if the object reference v is a null.  In that case the method will instantiate a new object,  populate it and return it.  If  v is not null, then asXML(..) will just populate it on read, or write it out.

/* populate object of type XYZobject from an application pasing only an object reference */
XYZobject xyz = new XYZobject(); // instantiate the empty object
// get the reader
try {
XMLReadAdapter xra = XMLSerializer.getReader("xyz.xml");
xyz = (XYZobject) xra.asXML("xyz-stuff", xyz); // must cast object
}
catch Exception e {
// this could be an IOException - xyz.xml can't be found
// or it could be an IllegalParameterException -the tag "xyz-stuff" was not found
System.err.println (e.getMessage());
e.printStackTrace();
// exit or do something to recover
System.exit(-1);
}
Alternatively, using the second method  to create an object from a stream:
/* populate object of type XYZobject from an application pasing only an object reference */
XYZobject xyz = null // no object instantiation
// get the reader
try {
XMLReadAdapter xra = XMLSerializer.getReader("xyz.xml");
// here package_name might be
xyz = (XYZobject) xra.asXML("xyz-stuff", xyz, Class.forName("package_name.XYZobject"));
}
catch Exception e {
// this could be an IOException - xyz.xml can't be found
// or it could be an IllegalParameterException -the tag "xyz-stuff" was not found
// or it could be a ClassNotFoundException - the name given to Class.forName(...)
// is wrong, or your classpath is wrong.

System.err.println (e.getMessage());
e.printStackTrace();
// exit or do something to recover
System.exit(-1);
}

The  second method is not used inside the asXML(XMLSerializer xml) that you define for your class.  The first one is used. .
For example::
class XYZobject implements IXMLize {
/* define members */
UVWobject m_uvw; // UVWObject implements IXMLize
int m_count; // count - just for contrast
/* method declaration */
Object asXML(XMLSerializer xml){
m_uvw = asXML("uvw-stuff", m_uvw);
m_count = asXML("count", m_count);
return this;
}
}

XMLSerializer.asXML( Object v, XMLMap aMap)

The  third and fourth  call take as arguments an XMLMap,  which identifies the the tag names and objects associated with the tag names.  Typically it is used inside the asXML(XMLSerializer xml) method that you define in your class;

class XYZobject implements IXMLize {
/* define members */
UVWobject m_uvw; // UVWObject implements IXMLize
int m_count; // count - just for contrast
// define the map staticly to reduce tbe number of creations
static XMLMap uvwMap = new XMLMap("uvw-stuff=UVWObject");

 /* method declaration */
Object asXML(XMLSerializer xml){
m_uvw = (XYZObject)asXML(m_uvw, uvwMap);
m_count = asXML("count", m_count);
return this;
}
}
The fourth is just like the third, only you can add a default object.  To do that , instantiate an object, and set the default values, and pass it to asXML(...)
 e.g.
class XYZobject implements IXMLize {
/* define members */
UVWobject m_uvw; // UVWObject implements IXMLize
int m_count; // count - just for contrast
// define the map staticly to reduce tbe number of creations
static XMLMap uvwMap = new XMLMap("uvw-stuff=UVWObject");
// create the default object
static UVWobject m_uvwDefault = UVW.create(......);

 /* method declaration */
Object asXML(XMLSerializer xml){
m_uvw = asXML(m_uvw, uvwMap, m_uvwDefault);
m_count = asXML("count", m_count);
return this;
}
}


XMLSerializer.asXML(String tag, ArrayList aList, XMLMap aMap)


This is the method  for serializing an ArrayList  of objects , all of which implement IXMLize.  We use ArrayLists instead of arrays because an ArraryList is dynamicly expandable and  it  has a simple iterator.  In general, any Collection class which implements the List Interface can be used .
class XYZobject implements IXMLize {
/* define members */
ArrayList  m_uvwList = new ArrayList(); // list of UVWObjects
int m_count; // count - just for contrast
// define the map staticly to reduce tbe number of creations
static XMLMap uvwMap = new XMLMap("uvw-stuff=UVWObject");

/* method declaration */
Object asXML(XMLSerializer xml){
m_uvwList = asXML("uvw-objects", m_uvwList, uvwMap, 0, new ArrayList());
m_count = asXML("count", m_count);
return this;
}
}
Thie above example is very cumbersome.  Note that we don't really need the listTemplate because m_uvwList was created when the XYZobject was instantiated. The simplest and most common usage is as follows:
class XYZobject implements IXMLize {
/* define members */
ArrayList  m_uvwList = new ArrayList(); // list of UVWObjects
int m_count; // count - just for contrast
// define the map staticly to reduce tbe number of creations
static XMLMap uvwMap = new XMLMap("uvw-stuff=UVWObject");

/* method declaration */
Object asXML(XMLSerializer xml){
m_uvwList = asXML("uvw-objects", m_uvwList, uvwMap);
m_count = asXML("count", m_count);
return this;
}
}
Back to top