A Simple XML Streaming Library

Nurul Choudhury,nurul@machinedialog.com
Copyright © 2001, Machine Dialog LLC

SourceForge Logo
javaxmlstream hosted by Source Forge

Download

Download xmlstream package (full source and doc 437KB)
Download jar (35 KB)

img 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)

img Contents



img 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.

xmlstream library


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.


img 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:

  1. Quick to implement
  2. As easy to use as object serialization.
  3. As fast as serialization.
  4. Make it easy to add XML streaming facility to any class.
  5. Make the library freely available to developers.
  6. Only one method does both Reading and writing.

What doesn't it do:

  1. Validate against a DTD (although it programmatically validates XML [TODO])
  2. Handle UTF-16 encoding (this should be added)
  3. Handle XML name space (TODO)
  4. 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.
.

img 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. 

i 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.

i 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    

i 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:

  1. 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.
  2. 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.

i 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.

i 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:
  1. XMLSerializer creates a writer using the getWriter(...) method. The getWriter is a static (factory) method for creating an instance of XMLWriteAdapter on a file.
  2. How to read and write an object (MyPerson) from an XML stream
  3. Use the asXML method of MyPerson object (MyPerson must implement IXMLize interface that contains the method)
  4. Assign the outer tag to an object  - "person"
  5. XMLSerializer creates a reader using the getReader(...) method.
  6. 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>


i 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 */


img 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.

i 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.

i 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).

i 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).

i 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:

  1. asXML(String tag, Object objectToSerialize)
  2. asXML(String tag, Object objectToSerialize, Object defaultValue)
  3. asXML(String tag, Object objectToSerialize, Class objClass)
  4. 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;
   }
 }

i 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.

i 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.

img How it works

The XMLSerializer as overloaded (abstract) method asXML for all the primitive data types for Java.

i 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

    …

i 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);


i Class Diagram

class diagram



i Object Interaction diagram
class 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", ...);

img 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)