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
- Overview
- Examples
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:
- Add the line "import com.machinedialog.xmlstream.* ;" to the
imports list..
- Add "implements IXMLize" to the object declaration
- 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
- Define the attributes for the object and any component objects. The
use of XML attributes makes the XML document much more readable.
- Implement asXML(...) method
- 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:
- Create an XMLSerializer. Use XMLSerializer.getWriter("filename")
to write; XMLSerializer.createReader("filename")
to read.
- Create the object you wish to read or write, call it myObject.
Be sure that it implements IXMLize
- 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:
- reading and writing simple variable types: int, long, double,
float, char
- reading and writing non-simple types: String, and other objects
that implement IXMLize
- reading and writing collections of objects, e.g. ArrayList. Note
that each object in the collection must implement IXMLize.
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:
- There is a default value to be used when reading if the
XML tag is not found in the stream
- 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:
- There is a default value to be used when reading if
the XML tag is not found in the stream
- 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