Java XML Tutorial

How to write XML file in Java (StAX Writer)

This tutorial shows how to use the Streaming API for XML (StAX) writer to write data to an XML file.

Table of contents

P.S All below examples are tested with Java 11.

1. Write to XML (StAX Writer APIs)

In Streaming API for XML (StAX), we can use StAX Cursor API or StAX Iterator API to write data to an XML file.

1.1 Below is the StAX Cursor API of writing data to XML.


  XMLOutputFactory output = XMLOutputFactory.newInstance();

  XMLStreamWriter writer = output.createXMLStreamWriter(
                              new FileOutputStream("/path/test.xml"));

  writer.writeStartDocument();

  writer.writeStartElement("test");

  // write other XML elements

  writer.writeEndDocument();

  writer.flush();

  writer.close();

1.2 Below is the StAX Iterator API of writing data to XML.


  XMLOutputFactory output = XMLOutputFactory.newInstance();

  XMLEventFactory eventFactory = XMLEventFactory.newInstance();

  XMLEventWriter writer = output.createXMLEventWriter(
                            new FileOutputStream("/path/test.xml"));

  XMLEvent event = eventFactory.createStartDocument();
  writer.add(event);

  // add other xml events

  writer.add(eventFactory.createEndDocument());

  writer.flush();

  writer.close();        

2. Write to XML (StAX Cursor API – XMLStreamWriter)

The below example uses StAX Cursor API XMLStreamWriter to write data to an XML file.

WriteXmlStAXCursor.java

package com.mkyong.xml.stax;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteXmlStAXCursor {

    public static void main(String[] args) throws XMLStreamException {

        // send the output to a xml file
        try(FileOutputStream out = new FileOutputStream("/home/mkyong/test.xml")){
            writeXml(out);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // send the output to System.out
        // writeXml(System.out);

    }

    // StAX Cursor API
    private static void writeXml(OutputStream out) throws XMLStreamException {

        XMLOutputFactory output = XMLOutputFactory.newInstance();

        XMLStreamWriter writer = output.createXMLStreamWriter(out);

        writer.writeStartDocument("utf-8", "1.0");

        // <company>
        writer.writeStartElement("company");

        // <staff>

        // add XML comment
        writer.writeComment("This is Staff 1001");

        writer.writeStartElement("staff");
        writer.writeAttribute("id", "1001");

        writer.writeStartElement("name");
        writer.writeCharacters("mkyong");
        writer.writeEndElement();

        writer.writeStartElement("salary");
        writer.writeAttribute("currency", "USD");
        writer.writeCharacters("5000");
        writer.writeEndElement();

        writer.writeStartElement("bio");
        writer.writeCData("HTML tag <code>testing</code>");
        writer.writeEndElement();

        writer.writeEndElement();
        // </staff>

        // <staff>
        writer.writeStartElement("staff");
        writer.writeAttribute("id", "1002");

        writer.writeStartElement("name");
        writer.writeCharacters("yflow");
        writer.writeEndElement();

        writer.writeStartElement("salary");
        writer.writeAttribute("currency", "EUR");
        writer.writeCharacters("8000");
        writer.writeEndElement();

        writer.writeStartElement("bio");
        writer.writeCData("a & b");
        writer.writeEndElement();

        writer.writeEndElement();
        // </staff>

        writer.writeEndDocument();
        // </company>

        writer.flush();

        writer.close();

    }

}

The XMLStreamWriter writes data to an XML file in compact mode, and later we will use Transformer to pretty-print the XML content.

/home/mkyong/test.xml

<?xml version="1.0" encoding="utf-8"?><company>
<!--This is Staff 1001--><staff id="1001"><name>mkyong</name><salary currency="USD">5000</salary>
<bio><![CDATA[HTML tag <code>testing</code>]]></bio></staff>
<staff id="1002"><name>yflow</name><salary currency="EUR">8000</salary>
<bio><![CDATA[a & b]]></bio></staff></company>

3. Write to XML (StAX Iterator API – XMLEventWriter)

The below example uses StAX Iterator API XMLEventWriter to write data to an XML file.

WriteXmlStAXIterator.java

package com.mkyong.xml.stax;

import javax.xml.stream.*;
import javax.xml.stream.events.XMLEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteXmlStAXIterator {

    public static void main(String[] args) throws XMLStreamException {

        // send the output to a xml file
        try(FileOutputStream out = new FileOutputStream("/home/mkyong/test.xml")){
            writeXml2(out);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // send the output to System.out
        // writeXml2(System.out);

    }

    // StAX Iterator API
    private static void writeXml2(OutputStream out) throws XMLStreamException {

        XMLOutputFactory output = XMLOutputFactory.newInstance();
        XMLEventFactory eventFactory = XMLEventFactory.newInstance();

        // StAX Iterator API
        XMLEventWriter writer = output.createXMLEventWriter(out);

        XMLEvent event = eventFactory.createStartDocument();
        // default
        //event = eventFactory.createStartDocument("utf-8", "1.0");
        writer.add(event);

        writer.add(eventFactory.createStartElement("", "", "company"));

        // write XML comment
        writer.add(eventFactory.createComment("This is staff 1001"));

        writer.add(eventFactory.createStartElement("", "", "staff"));
        // write XML attribute
        writer.add(eventFactory.createAttribute("id", "1001"));

        writer.add(eventFactory.createStartElement("", "", "name"));
        writer.add(eventFactory.createCharacters("mkyong"));
        writer.add(eventFactory.createEndElement("", "", "name"));

        writer.add(eventFactory.createStartElement("", "", "salary"));
        writer.add(eventFactory.createAttribute("currency", "USD"));
        writer.add(eventFactory.createCharacters("5000"));
        writer.add(eventFactory.createEndElement("", "", "salary"));

        writer.add(eventFactory.createStartElement("", "", "bio"));
        // write XML CData
        writer.add(eventFactory.createCData("HTML tag <code>testing</code>"));
        writer.add(eventFactory.createEndElement("", "", "bio"));

        // </staff>
        writer.add(eventFactory.createEndElement("", "", "staff"));

        // next staff, tired to write more
        // writer.add(eventFactory.createStartElement("", "", "staff"));
        // writer.add(eventFactory.createAttribute("id", "1002"));
        // writer.add(eventFactory.createEndElement("", "", "staff"));

        // end here.
        writer.add(eventFactory.createEndDocument());

        writer.flush();

        writer.close();

    }

}

Output

/home/mkyong/test.xml

<?xml version="1.0" encoding="UTF-8"?><company>
<!--This is staff 1001--><staff id="1001"><name>mkyong</name>
<salary currency="USD">5000</salary>
<bio><![CDATA[HTML tag <code>testing</code>]]></bio>
</staff></company>

4. Write and pretty print XML content (Transformer)

4.1 The below code snippets uses javax.xml.transform.Transformer to pretty print an XML content.


  private static String formatXML(String xml) throws TransformerException {

      // write data to xml file
      TransformerFactory transformerFactory = TransformerFactory.newInstance();

      Transformer transformer = transformerFactory.newTransformer();

      // alternative
      //Transformer transformer = SAXTransformerFactory.newInstance().newTransformer();

      // pretty print by indention
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");

      // add standalone="yes", add line break before the root element
      transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");

      /*transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
              "-//W3C//DTD XHTML 1.0 Transitional//EN");

      transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
              "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");*/

      // ignore <?xml version="1.0" encoding="UTF-8"?>
      //transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

      StreamSource source = new StreamSource(new StringReader(xml));
      StringWriter output = new StringWriter();
      transformer.transform(source, new StreamResult(output));

      return output.toString();

  }

4.2 Steps to pretty-print the XML content.

  1. Write data to a ByteArrayOutputStream variable.
  2. Convert the ByteArrayOutputStream variable to a String.
  3. Transformer to pretty-print the String and return a formatted XML String.
  4. Save the formatted XML String to a file.

The below example pretty print XML content and write to an XML file.

WriteXmlStAXPrettyPrint.java

package com.mkyong.xml.stax;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class WriteXmlStAXPrettyPrint {

    public static void main(String[] args) {

        try {

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            // write XML to ByteArrayOutputStream
            writeXml(out);

            // Java 10
            //String xml = out.toString(StandardCharsets.UTF_8);

            // standard way to convert byte array to String
            String xml = new String(out.toByteArray(), StandardCharsets.UTF_8);

            // System.out.println(formatXML(xml));

            String prettyPrintXML = formatXML(xml);

            // print to console
            // System.out.println(prettyPrintXML);

            // Java 11 - write to file
            Files.writeString(Paths.get("/home/mkyong/test.xml"),
                    prettyPrintXML, StandardCharsets.UTF_8);

            // Java 7 - write to file
            //Files.write(Paths.get("/home/mkyong/test.xml"),
            //    prettyPrintXML.getBytes(StandardCharsets.UTF_8));

            // BufferedWriter - write to file
            /*try (FileWriter writer = new FileWriter("/home/mkyong/test.xml");
                 BufferedWriter bw = new BufferedWriter(writer)) {
                bw.write(xml);
            } catch (IOException e) {
                e.printStackTrace();
            }*/

        } catch (TransformerException | XMLStreamException | IOException e) {
            e.printStackTrace();
        }

    }

    // StAX Cursor API
    private static void writeXml(OutputStream out) throws XMLStreamException {

        XMLOutputFactory output = XMLOutputFactory.newInstance();

        XMLStreamWriter writer = output.createXMLStreamWriter(out);

        writer.writeStartDocument("utf-8", "1.0");

        // <company>
        writer.writeStartElement("company");

        // <staff>
        // add XML comment
        writer.writeComment("This is Staff 1001");

        writer.writeStartElement("staff");
        writer.writeAttribute("id", "1001");

        writer.writeStartElement("name");
        writer.writeCharacters("mkyong");
        writer.writeEndElement();

        writer.writeStartElement("salary");
        writer.writeAttribute("currency", "USD");
        writer.writeCharacters("5000");
        writer.writeEndElement();

        writer.writeStartElement("bio");
        writer.writeCData("HTML tag <code>testing</code>");
        writer.writeEndElement();

        writer.writeEndElement();
        // </staff>

        // <staff>
        writer.writeStartElement("staff");
        writer.writeAttribute("id", "1002");

        writer.writeStartElement("name");
        writer.writeCharacters("yflow");
        writer.writeEndElement();

        writer.writeStartElement("salary");
        writer.writeAttribute("currency", "EUR");
        writer.writeCharacters("8000");
        writer.writeEndElement();

        writer.writeStartElement("bio");
        writer.writeCData("a & b");
        writer.writeEndElement();

        writer.writeEndElement();
        // </staff>

        writer.writeEndDocument();
        // </company>

        writer.flush();

        writer.close();

    }

    private static String formatXML(String xml) throws TransformerException {

        // write data to xml file
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();

        // pretty print by indention
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        // add standalone="yes", add line break before the root element
        transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");

        StreamSource source = new StreamSource(new StringReader(xml));
        StringWriter output = new StringWriter();
        transformer.transform(source, new StreamResult(output));

        return output.toString();

    }

}

Output

/home/mkyong/test.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<company>
    <!--This is Staff 1001-->
    <staff id="1001">
        <name>mkyong</name>
        <salary currency="USD">5000</salary>
        <bio>
            <![CDATA[HTML tag <code>testing</code>]]>
        </bio>
    </staff>
    <staff id="1002">
        <name>yflow</name>
        <salary currency="EUR">8000</salary>
        <bio>
            <![CDATA[a & b]]>
        </bio>
    </staff>
</company>

Convert XML to Java objects
Try Jakarta XML Binding (JAXB) to convert XML to/from Java objects.

5. Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-xml

$ cd src/main/java/com/mkyong/xml/stax/

6. References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments