Quick Introduction to generting XML with XmlPull v1 API
Author: Aleksander Slominski

# Quick Introduction to generating XML with XmlPull v1 API

This document describes how to use XmlSerializer that is part of XmlPull API to generate/write/serialize XML (If you want to do XML parsing read quick introduction to XML pull parsing)

## Main features of API

XmlSerializer provides:

- simple to use API that concentrates on how to generate correct XML quickly and in straightforward manner
- support for namespaces with automatic prefix declaration to make it as easy as possible to generate valid XML 1.0 documents with XML Namespaces
- control over namespace prefixes even though control over namespace prefixes is typically not needed but as prefixes are used in attribute values so it is important to allow control on how namespace prefixes are assigned if needed
- performance - the interface is designed to allow implementing very fast XML serializer
- minimal requirements - designed to be compatible with J2ME (Java 2 Micro Edition) to work on small devices and to allow creating XmlPull compliant serializer implementation with very small memory footprint.

## Requirements

Before running sample code make sure to have parser that implements XmlPull API 1.1.x (read relevant part from Quick Introduction)

## Writing XML: in few easy steps

All XML generating can be done by using XmlSerializer interface. However before we can start writing we need to obtain instance of class that implements this interface.

XmlPull API allows multiple implementations to be used. To achieve this flexibility serializer class is not created directly but by using configurable factory that is responsible for locating and creating implementation. In general that involves following steps:

- get instance of XmlPull factory - you can use system property as argument to configure factory with list of implementation to try and you can pass class to use as class loader context (important in servlet and application servers environments)
- create an instance of the serializer

In your code as the first thing make sure to import XmlPull v1 API classes:

    import org.xmlpull.v1.XmlPullParserException;
    import org.xmlpull.v1.XmlPullParserFactory;
    import org.xmlpull.v1.XmlSerializer;

and the code to create serializer may look like this:

            XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
                System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
            XmlSerializer serializer = factory.newSerializer();

Next step is to set serializer output - in this case it is set to write to standard output but can easily redirected to file or socket:

            serializer.setOutput(new PrintWriter( System.out ));

and now we can start using `serializer` to write XML!

Typical applicaition will write XML declaration and then follow with writing few element start and end tags and their content.

Output must always have at least one start tag:

            serializer.startTag(NAMESPACE, "poem");

then we cna start writing more start tags, text cotnent, and end tags:

            serializer.startTag(NAMESPACE, "title");
            serializer.text("Roses are Red");
            serializer.endTag(NAMESPACE, "title");

where namespace is declared as string constant

    private final static String NAMESPACE = "http://www.megginson.com/ns/exp/poetry";

it is possible to chain multiple calls:

            serializer.startTag(NAMESPACE, "l")
                .text("Roses are red,")
                .endTag(NAMESPACE, "l");

or put them even in one line:

            serializer.startTag(NAMESPACE, "l").text("Violets are blue;").endTag(NAMESPACE, "l");

but what make API really flexible and modular is to define functions that outputs well defined parts of XML, for example:

        private static void writeLine(XmlSerializer serializer, String line, boolean addNewLine)
            throws IOException {
            serializer.startTag(NAMESPACE, "l");
            serializer.text(line);
            serializer.endTag(NAMESPACE, "l");
            if(addNewLine) serializer.text("\n");
        }

and then to write chunkof XML output it is enough to simply call:

            writeLine(serializer, "Sugar is sweet,", addNewLine);
            writeLine(serializer, "And I love you.,", addNewLine);

Serializer will check that end tag name and namespace is the same as of matching start tag (very good to validate that XML output is correct) so to finish writing XML we should close top level start tag:

            serializer.endTag(NAMESPACE, "poem");

It is important to inform serializer when XML output is finished so any remianing buffered XML output is send to putput stream and serializer will not allow any more input to do this call endDocument():

            serializer.endDocument();

### Controlling namespace prefixes

There is no need to manually set prefixes as XmlSerializer will automatically declare prefixes when needed. However sometimes it is necessary to indicate what prefix should be used:

            serializer.setPrefix("ns", NAMESPACE);

or what namespace should be bound as default namespace (to special empty string prefix):

            serializer.setPrefix("", NAMESPACE);

Prefix declaration must be done just before call to start tag and the prefix declaration scope starts on this star tag and finishes when corresponding end tag is reached.

### Controlling output formatting

XmlSerializer allows to create any infoset so it is possible to add manually new lines or indentation. for exmaple if would like to have new line after every end tag it is as easy as to call text() with new line:

            if(addNewLine) serializer.text("\n");

If serializer supports optional formatting properties and features then they can be used to have output indented automatically. Read more about them:

- optional property: SERIALIZER INDENTATION
- optional property: SERIALIZER LINE SEPARATOR
- optional feature: SERIALIZER ATTVALUE USE APOSTROPHE

## Sample code

The finished working sample created that was described is in MyXmlWriteApp.java file in src/java/samples directory.

For more information about XmlPull API please visit http://www.xmlpull.org/.

## Output from sample application

When new lines are added manually:

    java MyXmlWriteApp -n
    serializer implementation class is class org.kxml2.io.KXmlSerializer
    <?xml version="1.0"?>

    <poem xmlns="http://www.megginson.com/ns/exp/poetry">
    <title>Roses are Red</title>
    <l>Roses are red,</l>
    <l>Violets are blue;</l>
    <l>Sugar is sweet,</l>
    <l>And I love you.,</l>
    </poem>

When using one of optional formatting properties to set indentation:

    java MyXmlWriteApp -i 4
    serializer implementation class is class org.xmlpull.mxp1_serializer.MXSerializer
    <?xml version="1.0"?>

    <poem xmlns="http://www.megginson.com/ns/exp/poetry">
        <title>Roses are Red</title>
        <l>Roses are red,</l>
        <l>Violets are blue;</l>
        <l>Sugar is sweet,</l>
        <l>And I love you.,</l>
    </poem>