Download
Download
xmlstream package
(full source and doc 437KB)
Download
jar
(35 KB)
Summary
This document describes a fast object streaming
library for reading and writing XML documents. The library (xmlstream)
is designed to be simple to use and extend. The interface is very similar
to the object serialization capability found in most Object Oriented
languages. Unlike standard XML parsers that read objects into a standard
DOM format, the XML streaming reads and writes directly int your
application specific object structure. This greatly simplifies the
handling of XML documents in Java.
The library is very fast; writing out 100,000 objects (MyPerson)
into an XML document took only 20% longer (12.9 sec as opposed
to 10.8 sec) than serializing than using Java's native object serialization,
despite the fact that the XML file was over 3.4 times larger. Note,
if the size of the XML document becomes a major issue then you can stream
out to a compressed file; compression ratios of 15:1 is quite common.
Whenever it is appropriate, developers should consider using
this package in place of the standard serialization that has to
be shared by more than one application. Unfortunately XML (without
using some proprietary encoding) can only process structures that
can be represented as trees. Despite this limitation, XML is appropriate
in most cases.
The library is easier to use than standard XML parsers
when the XML document has to be converted into (or out of) your own
internal format, particularly when the document is large or complex.
The API documentation can be found at:
API Reference (index.html)
Contents
Introduction
Just show me how to use it
This is the first part of a three part
series on XML streaming libraries for Java, C++, and C. This document
covers the Java library. We hope that this will encourage developers
to use XML as their preferred data storage format more often so that
we don't get so many different application configuration formats that
we have in the current Linux environment. We hope that after reading this
article more open source development will adopt XML as their configuration
and data storage format. This is an open invitation the Linux community
to use XML as their configuration and storage format for all their tools.
Java makes it easy to serialize your data structures to a stream.
Unfortunately streams are not a good data interchange format, particularly
if non Java applications need to process the data. The xmlstream library
will allow you to add XML support easily to your application.
The primary goal of the library is to make it as easy
to store and retrieve data in XML as it is to serialize object in
Java. In this article I will assume that you are familiar with
XML ( http://www.w3.org/TR/REC-xml
). This library is not intended as replacement for general XML
parsing (see XML parsers such as
DOM, or a SAX 2 parser
(JAXP
). For processing arbitrary XML documents, a general purpose
XML parser is the best tool.
The code is freely available to the development
community under LGPL (
Lesser GNU Public
). We strongly encourage you use and improve on the library,
but please put back any changes or extensions into the public domain.
Motivation
XML streaming was developed for a large application
(written in C++) that had to send data from a Microsoft Windows system
to a Linux web application, where the information would be processed
and saved into a database.
The data represented about 150 different classes, each
each having between 10 and 25 member attributes. Typically, the application
sent 3MB of data in one exchange. It was easy to use standard serialization,
found in the MFC (Microsoft foundation Classes), to save the data; but
the serialization format was not compatible with tools on Linux.
The choice was to develop a Linux and Windows compatible
serialization format. XML was the logical for the serialization
format. But after some initial indications suggested that using a
standard XML parser would involve a great deal of programming. The
first version of the xmlstream library was developed for C++.
The java version documented here is a port of that
library. It thould be noted that the C++ library made extensive use of
templates and generic programming a facility that is not present (currently)
in Java; so some of the implementation techniques are very different.
The design requirements for the xmlstream library
was as follows:
- Quick to implement
- As easy to use as object serialization.
- As fast as serialization.
- Make it easy to add XML streaming facility to any
class.
- Make the library freely available to developers.
- Only one method does both Reading and writing.
What doesn't it do:
- Validate against a DTD (although it programmatically
validates XML [TODO])
- Handle UTF-16 encoding (this should be added)
- Handle XML name space (TODO)
- Be a replacement for a general purpose XML parser
( other tools
already available
)
The principles of the XML streaming library is
to mimic the way Object Oriented languages serialize classes. For
example, unlike Java C++ does not have object serialization built
into the language but is typically supplied in a library. Xmlstream
is similar to such a library. Serialization makes it easy to read and write
objects to a file or a stream. Since all objects are ultimately built
from primitive data type such as integer, character, floating point number,
and strings, the streaming library has built-in methods that handle these
types. User types (classes) have to implement a very simple interface to
support XML- IXMLize. This is almost as simple as an interface can
be; tt has only one method asXML.
.
Quick Start
Developres are an impatient lot; so this section
is designed to quickly show you how to use the XML streaming library. The
library is in the package com.machinedialog.xmlstream.It is contained
in the jar file md_xmlstream.jar. In this section most of the advanced
features are left out so that you can quickly get started. The xmlstream
knows how to read and write Java primitive data types. An object can be
serialized only if it implements the IXMLize interface.
IXMLize Interface
In order to serialize an object to an XML
stream, a class must implement the IXMLize interface:
interface
IXMLize {
Object
asXML
(XMLSerializer strm) throws IOException;
}
The interface has only one method asXML(...) this method
is used for both reading and writing. The parameter to this method
is XMLReadAdapter to reading an XML stream; for writing, you pass in
an XMLWriteAdapter.
Quick Start Example
The following is an example of how to add XML streaming capability
to a class. The example implements a simple class representing
a person. Subsequent will elaborate on this class to illustrate the full
capabilities of the XML streaming library. The XMLSerializer
is an abstract class from which two concrete classes, XMLReadAdapter
and XMLWriteAdapter, are derived.
Both classes implement a set of "overloaded" asXML methods. Invoking
one of these methods on XMLReadAdapter will read a tagged data item from
a stream; while the same method invoked from XMLWriteAdapter will write
data to a stream (along with its corresponding tags). This symetry is extensively
used by the xmlstream library.
In fact, you almost never need to be aware that you are using these
classes; you are simply aware that you have an XMLSreializer opened for
reading or writing. In the examples, you will never see explicit use
of XMLReadAdapter or XMLWriteAdapter.
/*MyPerson.java - a class with XML serialization
code */
import com.machinedialog.xmlstream.*;
import java.io.*;
class MyPerson
implements
IXMLize
{
private String
m_name = "";
private String
m_street = "";
private String
m_city = "";
private String
m_state = "";
private String
m_zip = "";
private int m_age
= 0;
private boolean
m_isMale = false ;
public MyPerson()
{ }
… more code here
/*
this
method will read or write the object into an XML
document
depending on the type of XMLSerializer uses
Reads - XMLReadAdapter
Writes - XMLWriteAdapter
*/
public Object asXML(XMLSerializer
xml)
throws IOException
{
/*
mandatory tags */
m_name = xml.asXML("
name ",m_name);
/*1 */
m_age = xml.asXML("
age ", m_age);
/*2 */
/* optional tags */
m_isMale = xml.asXML("
male ", m_isMale, false);
/*3 */
m_street = xml.asXML("
street ", m_street,"");
/*4 */
m_city = xml.asXML("
city ", m_city,"");
/*5
* /
m_state = xml.asXML("
state ", m_state,"");
/*6 */
m_zip = xml.asXML("
zip", m_zip,
"");
/*7 */
return this;
}
}
|
The following code fragment illustrate how to write an instance
of MyPerson object to an XML document.
MyPerson p = ...
// create and initialize
XMLSerializer
xml = XMLSerializer.getWriter("person.xml");
p = xml.asXML( "person", p); // write the object to
the document
xml.close(); // close the stream
The following code will read an instance of MyPerson from a stream:
MyPerson p = ...
// creat and initialize
XMLSerializer
xml = XMLSerializer.getWriter("person.xml");
p = xml.asXML( "person", p); // read an object from
the document
xml.close(); // close the stream
The asXML method
This method implements the
XML streaming code for the object (MyPerson). As you can see the code
is simple. The same code handles both reading and writing. The method
does not specify the outer tag for the object. It is the responsibility
for the caller to specify the tag.
The reason for this may not be immediately obvious. There are
two important reasons that the asXML(...) method for the class does not
specify its outer tag:
- You would not be able to reuse
the asXML method of of a class from any of its subclasses because the
class would end up writing the outer tag instead of the subclass.
- A more important reason is
because the outer tag actually gives the meaning of the object. That
meaning is determined by the user of the object and not the object itself.
To make this idea clearer, a standard Java String objects can be used
as a person's name, address, phone, etc;. the tag is obviously determoned
by its context.
Mandatory and Optional tags
The "MyPerson.java" example
demonstrates the use of manditory and optional tags;
/*1*/ and /*2*/
(name age) are mandatory
tags, that is, if these tags are not present an IllegalArgumentException("tag
not found" ) exception is thrown. We specify that these tags are mandatory
by not giving a default value(the third parameter).
The use of optional tags are shown in the following lines
/*2*/ - /*7*/
are optional tags, they do not have to be present, when reading,
if these tags are not present default values are used (the third
parameters). When we are writing if the second parameter matches
the default value nothing is written.
Testing the MyPerson XML Serialization
The next example (TestXML.java)
demonstrates how to serialize an instance of MyPerson object to an XML
stream. The main(...) method sets up the appropriate XMLSerializer
for reading or writing, and the serializeXML(...) method is used
to read or write the object.
The code demonstrates how to use the following:
-
XMLSerializer creates a writer using the getWriter(...)
method. The getWriter is a static (factory) method for creating an instance
of XMLWriteAdapter on a file.
- How to read and write
an object (MyPerson) from an XML stream
- Use the
asXML
method of MyPerson object (MyPerson must implement IXMLize
interface that contains the method)
- Assign the outer
tag to an object - "person"
-
XMLSerializer creates a reader using the getReader(...)
method.
- Shows that the name
method is used for both reading and writing.
We create a MyPerson
object and initialize it with data and write out the object to the
file "person.xml". We then read the newly created XML file.
/* TestXML.java - code to test the XML serialization*/
import com.machinedialog.xmlstream.*;
import
java.io.*;
public class
TestXML
{
static MyPerson
serializeXML(MyPerson
person , XMLSerializer xml
)
throws
IOException
{
/*
reads and writes depending on the type of adapter */
xml.asXML
("person", person);
/* 8 */
xml.close();
return
person;
}
public static void main(String[]
args)
throws
IOException {
/* create a person */
MyPerson p1 = new
MyPerson();
p1.init("
Fred Smith ", 21, true, "
1 Park Ave ", "
New York ",
"
NY", "10002");
/* write a person to XML */
serializeXML
(p1, XMLSerializer.createWriter(
"person.xml" ));
/* read back from XML */
MyPerson p2 = new MyPerson(); /* 9 */
p2 =
serializeXML
(p2, XMLSerializer.createReader("
person.xml "));
}
}
|
The main(...) method shows you how to write out the XML
file and then read it back in. The writing and subsequent reading
is done by the same code serializeXML(...).
You will notice /* 8
*/
is used for both reading and writing. For the purposes
of simplicity this example creates a MyPerson object
/* 9 */
before reading it - later in this article I will show
you how to avoid this step using XMLMap object ( a utility object
that maps tag name to class name).
The XML file the code above will generate is as follows
(the indentations were added for clarity)
person.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<person>
<name>
Fred Smith </name>
<age>
21</age>
<male>
true</male>
<street>
1 Park Ave</street>
<city>
New York</city>
<state>
NY</state>
<zip>
10002</zip>
</person>
|
Tag Attributes
The xmlstream
library supports XML attributes in a simple way. There a are no seperate
attribute read/write methods; the same element methods asXML are used for
attributes. You seperately sepcify the elements that are attributes. The
only restriction is that the attributes must be all at the begining.
Suppose we wanted to make the elements (name, age, male) attributes
of the outer tag. I that case we have one of two choices, firstly
to define the attributes from the caller:
xml.
attributes("name age male").asXML("person", person);
/*in the caller */
The XML file will be as follows:
<?xml version="1.0" encoding="ISO-8859-1"?>
<person name="Fred Smith" ag
e="21" male
="true">
<street>1 Park Ave</
stree t>
<city>New York</
city >
<state>NY</state
>
<zip>10002</zip
>
</person>
(NOTE: Indentations
have been added to the file for clarity)
The alternative technique is to set the attribute
in the asXML method for the class as follows:
MyPerson.java
public Object asXML(XMLSerializer xml) throws
IOException
{
xml.setDefaultAttributes
(" name age male");
m_name =
xml.asXML("name",m_name);
/*1 */
m_age = xml.asXML("age",
m_age);
/*2 */
m_isMale = xml.asXML("male", m_isMale,
false); /*3 */
…
This setDefaultAttributes method, as the name suggests
is the default for the object. The caller can override the defaults
by simply using the:
xml.attributes("name").asXML("person", person);
In this case only the name will be treated as an
attribute, and the XML file will have the following:
<? xml version="1.0" encoding="ISO-8859-1"?>
<person name="Fred Smith">
<age>21</age>
<male>true</male
>
<street>1 Park Ave</
street >
<city>New York</city
>
<state>NY</state
>
<zip>10002</zip
>
</person>
A restriction on the XML library is that only the
first set of tags can be attributes, for example, you can write the
following:
xml.attributes ("name zip").asXML("person",
person);
In this case only ‘name’ will be treated as an attribute,
the zip tag will be treated is a regular inner item despite the
fact that it is declared to be an attribute. The basic rule is the
attributes must be the first set of contiguous tags. You can force all
attribltes to tbe trested as tagged elements by setting the empty string:
xml.attributes ("").asXML("person", person);
/* suppress the attributes */
XML Serialization
This section describes the facilities in the xmlstream library
in more detail. Before you can read or write an XML document you must
acquire an XMLReadAdapter or an XMLWriteAdapter. The XMLSerializer
class has factory methods for creating the read or write adapter.
Opening an XML Stream
To read or write from an XML stream you use an XMLSerializer. The
is an abstract class that implements an XMLReadAdapter
or an XMLWriteAdapter. Normally, you do not create
the XMLReadAdapter or XMLWriteAdapter directly but use a static
(factory) method in XMLSerializer in the following manner:
1. Reading
XMLSerializer rs = XMLSerializer.getReader("file.xml");
2. Writing
XMLSerializer ws = XMLSerializer .getWriter("file.xml");
Once you have an appropriate serializer you use one the
many overloaded
asXML methods to read or write to the
XML document.
Serializing primitive Java data types
As stated earlier the xmlstream library has methods to serialize
all the primitive Java data types:
Primitive java types
int |
char
|
boolean
|
long
|
float
|
double
|
int asXML(String tag,
int
value);
long asXML(String tag,
long value);
String asXML(String
tag,
String value);
float asXML(String tag,
float
value);
char asXML(String tag,
char value);
boolean asXML(String tag,
boolean
value);
Writing
These methods are a part of the the XMLSerializer
interface
. The XMLWriteAdapter define these methods to write
the tagged value to the output stream and return the value
parameter
as the result. The usage idiom for all of
these methods is as follows:
varx = xml_adap.asXML( "some-tag", varx
);
Note: the result of the method should always be
reassigned to the variable that is being written. The reason for this
will be seen shortly; remember that the same code is used for both reading
and writing.
Reading
The XMLReadAdapter define these methods to read the tagged
values from an XML document and return it as the result. The usage idiom
for all of these methods is as follows:
varx = xml_adap.asXML( "some-tag", varx
);
In this case the value parameter only serves the purpose
of identifying the method signature and serves only that purpose.
For example, if varx is a boolean then the method,
boolean asXML(String
tag,
boolean
value);
method is used. The return value will be the boolean value
read from the stream. As you can see the semantics of the read and
write were chosen so that the same code will correctly write or read
the value in variable
varx. If the the tag "some-tag'"
is not found at the current position in the stream an IllegalArgumentException
will be throw; meaning the tag is mandatory. As you will see shortly,
there is a bunch of asXML(...) methods for dealing with optional tags
(may not be in the stream).
Handling optional tags (Default values )
The xmlstram library also has support for optional
tags. This are tags that may or may not be present. The semantics of
these methods have also been carefully chosen so that the same code will
handle both reading and writing depending on the type of adapter that
is used.
int asXML(String tag,
int
value,
int defaultIntValue);
long asXML(String tag,
long
value,
long
defaultLongValue
);
String
asXML(String tag,
String
value, String defaultStringValue
);
float asXML(String
tag,
float
value,
float defaultFloatValue);
char asXML(String tag,
char
value,
char defaultDoubleValue);
boolean asXML(String tag,
boolean
value, boolean defaultBoolValue);
Reading
When we are reading from a stream (XMLReadAdapter) the adapter
check to the tag, if the tag is found the value is read from the
stream and returned as the result of the method. If the tag is not
found then the appropriate default value is returned (the value of
the third parameter). This method always succeeds as long a no I/O
error is encountered. The second parameter is only used to identify
the method signature (which of the asXML method to use).
Serializing Objects
So far we have only handled primitive Java type. This
section will show you how to handle your own classes. To serialize
an object to an XML stream the object must implement the IXMLize interface
or be one of the following well know types:
Well known object types
String
|
Integer
|
Long
|
Boolean
|
Double
|
Float
|
As stated in an earlier section, a class must implement
the
IXMLize
interface before it can be serialized to an XML stream.
The XMLSerializer specifies the following methods to serialize an
object to an XML stream:
-
asXML(String tag, Object objectToSerialize)
-
asXML(String tag, Object objectToSerialize,
Object defaultValue)
-
asXML(String tag, Object objectToSerialize,
Class objClass)
-
asXML(Object objectToSerialize, XMLMap mapsTagsToClassName,
Object defaultValue)
Function
|
Read
|
Write
|
Comment
|
1
|
Object (to serialize) is not null
|
Object is not null
|
Tag is mandatory. If the tag is not present while reading, throw
an exception.
|
2
|
Object is not null
|
Object may be null
|
If the tag is not present then use the default value. While
writing if the object is equal to default value then nothing is written.
The equality is checked using the equals(...) method of the object.
|
3
|
Object may be null
|
Object may be null
|
The Class parameter is used to determine the class to instantiate
when reading from an XML document if the
Object parameter
is null.
|
4
|
Object may be null
|
Object may be null
|
This is the most general form of the
asXML
method.
XMLMap is a object that maps tags to objects in the following manner:
"tag1=ClassName1 tag2=ClassName2 ..."
Reading: if tag1 is found then create an object of
type ClassName1 and use its asXML method to read the object; if
tag2 is found instantiate an object of type ClassName2 and so
on. This method allows a variable to be of one of several types with each
type being represented by a unique tag.
Writing: if the class of the object is ClassName1
then write
tag1 and use its
asXML method to write it our; and if the object class is ClassNmae2
then
tag2 is written and so
on...
|
The following example will illustrate how to use the asXML
object interface of XMLSerializer. The most general of the interfaces
is (4) using the XMLMap
capability.
Suppose we wanted to add a m_spouse member to
MyPerson were the spouse may be simply the name of the
spouse stored as a string or a spouse may be a reference to a MyPerson
object, or m_spouse may be
null . The
way to code the capability is as follows:
so if the m_spouse is simply a a String
the following tag will be written:
<? xml version="1.0" encoding="ISO-8859-1"?>
<personname="Fred Smith" ag
e="21"
male ="true">
<street>1 Park Ave</
stree t>
<city>New York</
city >
<state>NY</state
>
<zip>10002</zip
>
<spouse-name>Mary Poppins</
spouse-name >
</person >
|
If m_spouse is a MyPerson object, the XML
document will be as follows:
<? xml version="1.0" encoding="ISO-8859-1"?>
<person name="Fred Smith" ag
e="21"
male ="true">
<street>1 Park Ave</
stree t>
<city>New York</
city >
<state>NY</state
>
<zip>10002</zip
>
<spouse name="Mary Poppins"
age="20" >
<street
>1 Park Ave</ street>
<city
>New York</ city>
<state>NY</
state >
<zip>10002</
zip >
</spouse>
</person >
|
Note: since the default for m_isMale is false, no <male>
tag is written.
The code additions to the class are as follows:
class
MyPerson
implements
IXMLize {
/* we just need a static XMLMap since all instances of
MyPerson require the same map */
static XMLMap
spouse_map =
new XMLMap(
"spouse-name=java.lang.String
" +
"spouse=MyPerson" );
privateObject m_spouse
=
null ;
...
public Object asXML( XMLSerializer strm ) {
...
m_spouse = strm.asXML(m_spouse,
spouse_map ,
null);
return this;
}
}
|
Serializing Lists
This section will show you how to serialize lists. In
the previous section we introduced the XMLMap, an object that associates
tags with classes. The rules for an XMLMap is that every tag and
class in the map must be unique, bucause the xmlstream package used the
tag to know which class to read, and uses the class to determine which
tag to write. Since a list can have several types of objects the XMLMap provides
the tag to class binding.
To illustrate the use of list let us add a list of hobbies
to a person. In order to keep things simple let us assume that a hobby
is just a String hobby name. The list of hobbies will be stored as
an ArrayList of hobbies. Let us assume that we add the member variable
m_hobbies to MyPerson as follows:
private ArrayList
m_hobbies = new ArrayList();
The XML document could list the hobbies is one of two
ways:
1. As a flat list of hobbies with a surrounding tag as
follows
<? xml version="1.0" encoding="ISO-8859-1"?>
<personname="Fred Smith" ag
e="21"
male ="true">
<street>1 Park Ave</
stree t>
<city>New York</
city >
<state>NY</state
>
<zip>10002</zip
>
<spouse-name
>Mary Poppins</spouse-name>
<hobby>Fishing</hobby
>
<hobby>Sailing</hobby
>
<hobby>Photography</hobby
>
</ person >
|
2. As a list of hobbies with a surrounding tag as
follows
<? xml version="1.0" encoding="ISO-8859-1"?>
<personname="Fred Smith" ag
e="21"
male ="true">
<street>1 Park Ave</
stree t>
<city>New York</
city >
<state>NY</state
>
<zip>10002</zip
>
<spouse-name
>Mary Poppins</spouse-name>
<hobbies>
<hobby>Fishing</hobby>
<hobby>Sailing</hobby>
<hobby>Photography</hobby>
</hobbies>
</ person >
|
The method for adding hobbies in the first form is to
use the XMLSerializer method:
asXML( List
aList,
XMLMap mapForInnerItems)
as shown earlier when we added the spouse attribute we
need a static XMLMap as follows:
static XMLMap
hobby_map = new XMLMap( "hobby=java.lang.String"
);
the code we add to the asXML method of MyPerson is as
follows:
The code aditions to the class are as follows:
private ArrayList m_hobbies = new ArrayList();
public ObjectasXML( sXMLSerializertrm
) {
...
m_hobbies = (ArrayList) strm.asXML(m_hobbies,
hobby_map );
return this;
|
The code to support the <hobbies> outer tag is as
follows:
private ArrayList m_hobbies = new ArrayList();
public Object asXML( sXMLSerializertrm
) {
...
m_hobbies =
(ArrayList)
strm.asXML("hobbies", m_hobbies,
hobby_map ) ;
|
If the list supports many object types we add the tag=className
mapping for all the types supported.
If the list can have several alternative tags, then the XMLMap
would list the tags and the associated classes in the following manner:
new XMLMap("child-name=java.lang.String child=MyPerson");
As you can see, xmlstream makes
it very easy to handle lists.
List size check
An additional capabilityof the library is to stipulate
the minimum number of elements in the list uusingthe following
method:
asXML (Stringtag, List
aLis t, XMLMap
aMap, int minListSize,
List aListConstructionTemplate);
The third parameter is the minimum number of elements that the
list must contain. The fourth parameter is an instance of a list that
will be used as a list construction template if aList is null. The actual
aListConstructorTemplate
object is left untouched but its class is used to construct a new list.
How it works
The XMLSerializer as overloaded (abstract)
method asXML for all the primitive data types for Java.
methods for primitive types These methods will
read (or write) a tag and its associated value. If no tag is found
white reading an IOException will be thrown.
int asXML(String tag,
int
value);
long asXML(String tag,
long
value);
String asXML(String
tag,
String
value);
float asXML(String
tag,
float
value);
char asXML(String tag,
char
value);
boolean asXML(String tag,
boolean
value);
Object Serialization
Object asXML(String tag,
Object
value);
Object asXML(String tag,
Object
value,
Class objClass);
Object asXML(Object
value,
XMLMap
mapTagToClass);
List Serialization
…
Default values (optional tags)
These method are used to support optional tags, that
is, the tag may be absent. If no tag is found while reading the
method returns the default value and continues. The behavior of
the method is a little different when writing. If the value being
written is equal to the default value nothing is written.
int
asXML(String tag,
int value,
int defaultValue);
long asXML(String tag,
long
value,
long
defaultValue );
String asXML(String tag,
String
value, String
defaultValue );
float asXML(String
tag,
float
value, float defaultValue);
char asXML(String tag,
char
value,
char defaultValue);
boolean asXML(String
tag, boolean
value);
Class Diagram
Object Interaction diagram
Let us look at the implementation of
one of these methods in XMLWriteAdapter
(pseudo code):
int asXML(
String tag,
int value)
Write Tag ( tag )
// writes the start tag e.g. <age>
Write Int ( value )
// convert the integer to a string
and write it out
Write End Tag (tag)
// write the end tag e.g. </age>
return
value
//
return the value that was passed in
Let us look at the implementation of
one of these methods in XMLReadAdapter
(pseudo code):
int asXML (
String tag,
int value)
CheckTag ( tag );
// check for tag
in the stream, e.g. <age>
nVal = Read Int()
// read a
string and convert it into an int
Check End Tag (tag )
// check for end tag e.g. </age>
return
nVal
// return
the integer that was just read in
As you can see the API will read or
write the value to an XML stream depending on the type of
adapter we are using, but the syntax is a little clumsy because
Java does not support parameters passed in by reference.
The library was originally developed for C++, that
supports passing parameters by reference (address of the variable).
The C++ interface to the asXML a simpler:
The interface for string type is as
follows
boolean asXML(
char *tag,
string& value);
(note: the boolean return indicates if the method succeed)
the interface is used as follows:
adap.asXML ("name
", m_name);
/*for both reading and
writing */
If we are writing to an XML stream the
contents of
m_name is simply written to the stream along with the
start and end tags <name> </name>. When we are reading
from the XML stream we match the <name> tag and then read
the value into the m_name variable (since we have the address of
the variable). Java only provides passing parameters by value (i.e.
the contents of m_name), so we cannot modify the m_name parameter
when we are reading from an XML stream. We get around the problem
by using the return value as follows:
m_name = adap. asXML ("name",
...);
|
Finally
The xmlstream library has remains to to be optimized fully. Although
it performs adequately in most circumstances. The most important facility
that is missing the the processing of XML namesapce. We hope to be able
to add the capability in the next release. Even without namespace the
library has been found to be extremely useful. We hope the documentation
that has been provided is sufficient for you to be able to use the library.
Nurul Choudhury nurul@machinedialog.com
Download
Download xmlstream package
(full source and doc 437KB)
Download jar
(35 KB)
|