Skip to content
This repository

There are two well known and simple ways to copy XML

  • Use XSLT with default templates (identity transform)
  • Use the StAX event API to copy all events from a reader to a writer

Let's see how we can use StAXON to convert JSON to XML using either of those techniques.

Consider the following JSON sample:

input.json

{
  "customer" : {
    "first-name" : "Jane",
    "last-name" : "Doe",
    "address" : {
      "street" : "123 A Street"
    },
    "phone-number" : [ {
      "@type" : "work",
      "$" : "555-1111"
    }, {
      "@type" : "cell",
      "$" : "555-2222"
    } ]
  }
}

With StAXON's Mapping Convention, fields prefixed with "@" are interpreted as attributes and the "$" field represents text content.

Therefore, converting the above to XML yields

output.xml

<?xml version="1.0"?>
<customer>
    <first-name>Jane</first-name>
    <last-name>Doe</last-name>
    <address>
        <street>123 A Street</street>
    </address>
    <phone-number type="work">555-1111</phone-number>
    <phone-number type="cell">555-2222</phone-number>
</customer>

Here's the code...

Copying JSON to XML via XSL Transformation

package de.odysseus.staxon.sample.copy;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;

import de.odysseus.staxon.json.JsonXMLConfig;
import de.odysseus.staxon.json.JsonXMLConfigBuilder;
import de.odysseus.staxon.json.JsonXMLInputFactory;
import de.odysseus.staxon.xml.util.PrettyXMLStreamWriter;

public class JSON2XML1 {
    /**
     * Copy/format JSON as XML using {@link Transformer#transform(Source, Result)}.
     * @param args ignored
     * @throws TransformerException
     * @throws XMLStreamException
     */
    public static void main(String[] args) throws Exception {
        InputStream input = JSON2XML1.class.getResourceAsStream("input.json");
        OutputStream output = System.out;
        /*
         * If the <code>multiplePI</code> property is
         * set to <code>true</code>, the StAXON reader will generate
         * <code>&lt;xml-multiple&gt;</code> processing instructions
         * which would be copied to the XML output.
         * These can be used by StAXON when converting back to JSON
         * to trigger array starts.
         * Set to <code>false</code> if you don't need to go back to JSON.
         */
        JsonXMLConfig config = new JsonXMLConfigBuilder().multiplePI(false).build();
        try {
            /*
             * Create source (JSON).
             */
            XMLStreamReader reader = new JsonXMLInputFactory(config).createXMLStreamReader(input);
            Source source = new StAXSource(reader);

            /*
             * Create result (XML).
             */
            XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(output);
            Result result = new StAXResult(new PrettyXMLStreamWriter(writer)); // format output

            /*
             * Copy source to result via "identity transform".
             */
            TransformerFactory.newInstance().newTransformer().transform(source, result);
        } finally {
            /*
             * As per StAX specification, XMLStreamReader/Writer.close() doesn't close
             * the underlying stream.
             */
            output.close();
            input.close();
        }
    }
}

Copying JSON to XML via StAX Event API

package de.odysseus.staxon.sample.copy;

import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;

import de.odysseus.staxon.json.JsonXMLConfig;
import de.odysseus.staxon.json.JsonXMLConfigBuilder;
import de.odysseus.staxon.json.JsonXMLInputFactory;
import de.odysseus.staxon.xml.util.PrettyXMLEventWriter;

public class JSON2XML2 {
    /**
     * Copy/format JSON as XML using {@link XMLEventWriter#add(XMLEventReader)}.
     * @param args ignored
     * @throws XMLStreamException
     */
    public static void main(String[] args) throws Exception {
        InputStream input = JSON2XML2.class.getResourceAsStream("input.json");
        OutputStream output = System.out;
        /*
         * If the <code>multiplePI</code> property is
         * set to <code>true</code>, the StAXON reader will generate
         * <code>&lt;xml-multiple&gt;</code> processing instructions
         * which would be copied to the XML output.
         * These can be used by StAXON when converting back to JSON
         * to trigger array starts.
         * Set to <code>false</code> if you don't need to go back to JSON.
         */
        JsonXMLConfig config = new JsonXMLConfigBuilder().multiplePI(false).build();
        try {
            /*
             * Create reader (JSON).
             */
            XMLEventReader reader = new JsonXMLInputFactory(config).createXMLEventReader(input);

            /*
             * Create writer (XML).
             */
            XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(output);
            writer = new PrettyXMLEventWriter(writer); // format output

            /*
             * Copy events from reader to writer.
             */
            writer.add(reader);

            /*
             * Close reader/writer.
             */
            reader.close();
            writer.close();
        } finally {
            /*
             * As per StAX specification, XMLEventReader/Writer.close() doesn't close
             * the underlying stream.
             */
            output.close();
            input.close();
        }
    }
}
Something went wrong with that request. Please try again.