Converting JSON to Xml in Java

Converting JSON to XML in Java

Use the (excellent) JSON-Java library from json.org then

JSONObject json = new JSONObject(str);
String xml = XML.toString(json);

toString can take a second argument to provide the name of the XML root node.

This library is also able to convert XML to JSON using XML.toJSONObject(java.lang.String string)

Check the Javadoc

Link to the the github repository

POM

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>

original post updated with new links

Converting multiple lines of JSON to XML using Java

This should solve your problem:

import org.json.JSONArray;
import org.json.JSONTokener;
import org.json.XML;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ConvertExample {
public static void main(String[] args) throws IOException {
JSONTokener tokener = new JSONTokener(Files.newInputStream(Paths.get("test.json")));
JSONArray array = new JSONArray();

while(tokener.nextClean() != '\u0000'){
tokener.back();
array.put(tokener.nextValue());
}

// Print XML with each array entry named node
System.out.println(XML.toString(array, "node"));
}
}

Updated for updated question
Here a JSONTokener is used to tokenize it top bottom. The loop checks whether the tokenizer is at end of file and if not, go a step back (unread the char) and parses the next value

Java implementation of JSON to XML conversion

Not a Java, but a pure XSLT 2.0 implementation:

Have a look at the f:json-document() from the FXSL 2.x library.

Using this function it is extremely easy to incorporate JSon and use it just as... XML.

For example, one can just write the following XPath expression:

f:json-document($vstrParam)/Students/*[sex = 'Female']

and get all children of Students with sex = 'Female'

Here is the complete example:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs"
>
<xsl:import href="../f/func-json-document.xsl"/>

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:variable name="vstrParam" as="xs:string">
{

"teacher":{
"name":
"Mr Borat",
"age":
"35",
"Nationality":
"Kazakhstan"
},

"Class":{
"Semester":
"Summer",
"Room":
null,
"Subject":
"Politics",
"Notes":
"We're happy, you happy?"
},

"Students":
{
"Smith":
{"First Name":"Mary","sex":"Female"},
"Brown":
{"First Name":"John","sex":"Male"},
"Jackson":
{"First Name":"Jackie","sex":"Female"}
}
,

"Grades":

{
"Test":
[
{"grade":"A","points":68,"grade":"B","points":25,"grade":"C","points":15},

{"grade":"C","points":2, "grade":"B","points":29, "grade":"A","points":55},

{"grade":"C","points":2, "grade":"A","points":72, "grade":"A","points":65}
]
}

}
</xsl:variable>

<xsl:template match="/">
<xsl:sequence select=
"f:json-document($vstrParam)/Students/*[sex = 'Female']"/>

</xsl:template>
</xsl:stylesheet>

When the above transformation is applied on any XML document (ignored), the correct result is produced:

<Smith>
<First_Name>Mary</First_Name>
<sex>Female</sex>
</Smith>
<Jackson>
<First_Name>Jackie</First_Name>
<sex>Female</sex>
</Jackson>

Convert JSON to XML in Java with different JSON object names

You need to read the JSON as a Map<String, Object> and create a Row object consisting of a caption and value field. After that you need to iterate over the entries in the map distinguishing between maps and lists of maps. In the case of maps, these need to be converted to Row objects and added to a collection of row objects. In the case of the lists of maps, the same thing needs to be done in an inner loop. When the iteration is done, the rows need to be added to a wrapper object which can then be converted to xml using an XmlMapper.

I've created a gist that works on your example:
https://gist.github.com/santmatthew/8f85399ad86fb45fec0be0c5df1a9825

Converting a JSON file to a specific XML format

One option is to use json-to-xml() in XSLT 3.0.

You'll need an XSLT 3.0 processor; I used Saxon-HE 9.8 in my example below.

You can pass the JSON in as a param.

The results of json-to-xml() will look something like this:

<map xmlns="http://www.w3.org/2005/xpath-functions">
<array key="playerStats">
<map>
<string key="jerseyNumber">23</string>
<number key="fgPercentage">60</number>
<string key="plusMinus">plus</string>
</map>
<map>
<string key="jerseyNumber">24</string>
<number key="fgPercentage">40</number>
<string key="plusMinus">minus</string>
</map>
</array>
</map>

You can process that XML to get your target XML.

Example...

Java

package so.test1;

import java.io.File;
import java.io.OutputStream;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.XsltTransformer;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;

/**
*
* @author dhaley
*
*/
public class SOTest1 {

public static void main(String[] args) throws SaxonApiException {
final String XSLT_PATH = "src/so/test1/test.xsl";
final String JSON = "{\"playerStats\": [\n" +
" {\"jerseyNumber\": \"23\", \"fgPercentage\": 60, \"plusMinus\": \"plus\"},\n" +
" {\"jerseyNumber\": \"24\", \"fgPercentage\": 40, \"plusMinus\": \"minus\"}\n" +
"]}";

OutputStream outputStream = System.out;
Processor processor = new Processor(false);
Serializer serializer = processor.newSerializer();
serializer.setOutputStream(outputStream);
XsltCompiler compiler = processor.newXsltCompiler();
XsltExecutable executable = compiler.compile(new StreamSource(new File(XSLT_PATH)));
XsltTransformer transformer = executable.load();
transformer.setInitialTemplate(new QName("init")); //<-- SET INITIAL TEMPLATE
transformer.setParameter(new QName("json"), new XdmAtomicValue(JSON)); //<-- PASS JSON IN AS PARAM
transformer.setDestination(serializer);
transformer.transform();
}

}

XSLT 3.0 (test.xsl)

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.w3.org/2005/xpath-functions">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="json"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template name="init">
<!--Only process playerStats-->
<xsl:apply-templates select="json-to-xml($json)//array[@key='playerStats']"/>
</xsl:template>

<xsl:template match="array">
<BallerStats>
<xsl:apply-templates/>
</BallerStats>
</xsl:template>

<xsl:template match="map">
<BallerStat>
<xsl:apply-templates/>
</BallerStat>
</xsl:template>

<xsl:template match="*[@key='jerseyNumber']">
<Baller>
<BallerJersey xsl:expand-text="true">{.}</BallerJersey>
<Type>Jersey</Type>
</Baller>
</xsl:template>

<xsl:template match="*[@key='fgPercentage']">
<fgPercentage>
<Type>PERCENT</Type>
<Value xsl:expand-text="true">{.}</Value>
</fgPercentage>
</xsl:template>

<xsl:template match="*[@key=('plusMinus')]"/>

</xsl:stylesheet>

Output (stdout)

<?xml version="1.0" encoding="UTF-8"?>
<BallerStats>
<BallerStat>
<Baller>
<BallerJersey>23</BallerJersey>
<Type>Jersey</Type>
</Baller>
<fgPercentage>
<Type>PERCENT</Type>
<Value>60</Value>
</fgPercentage>
</BallerStat>
<BallerStat>
<Baller>
<BallerJersey>24</BallerJersey>
<Type>Jersey</Type>
</Baller>
<fgPercentage>
<Type>PERCENT</Type>
<Value>40</Value>
</fgPercentage>
</BallerStat>
</BallerStats>

Add extra metadata while converting JSON to XML

Code:

    String xml ="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ " <soapenv:Header/>"
+ " <soapenv:Body><Cities><City></City></Cities>"
+ " <OperationResponse> <Type>SUCCESS</Type> <Code>0</Code> <ResponseDetails> <ResponseDetail> <Message>Operation completed successfully</Message> </ResponseDetail> </ResponseDetails> </OperationResponse>"
+ " </soapenv:Body>"
+ "</soapenv:Envelope>";
Map<String, Object> map = (Map<String, Object>) U.fromXml(xml);
String json = "[{\"id\":\"1\",\"name\":\"Bratislava\",\"population\":\"432000\"},{\"id\":\"2\",\"name\":\"Budapest\",\"population\":\"1759000\"},{\"id\":\"3\",\"name\":\"Prague\",\"population\":\"1280000\"},{\"id\":\"4\",\"name\":\"Warsaw\",\"population\":\"1748000\"},{\"id\":\"5\",\"name\":\"Los Angeles\",\"population\":\"3971000\"},{\"id\":\"6\",\"name\":\"New York\",\"population\":\"8550000\"},{\"id\":\"7\",\"name\":\"Edinburgh\",\"population\":\"464000\"},{\"id\":\"8\",\"name\":\"Berlin\",\"population\":\"3671000\"}]";
List<Object> list = (List<Object>) U.fromJson(json);
U.set(map, "soapenv:Envelope.soapenv:Body.Cities.City", list);
System.out.println(U.toXml(map));

Output:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header/>
<soapenv:Body>
<Cities>
<City>
<id>1</id>
<name>Bratislava</name>
<population>432000</population>
</City>
<City>
<id>2</id>
<name>Budapest</name>
<population>1759000</population>
</City>
<City>
<id>3</id>
<name>Prague</name>
<population>1280000</population>
</City>
<City>
<id>4</id>
<name>Warsaw</name>
<population>1748000</population>
</City>
<City>
<id>5</id>
<name>Los Angeles</name>
<population>3971000</population>
</City>
<City>
<id>6</id>
<name>New York</name>
<population>8550000</population>
</City>
<City>
<id>7</id>
<name>Edinburgh</name>
<population>464000</population>
</City>
<City>
<id>8</id>
<name>Berlin</name>
<population>3671000</population>
</City>
</Cities>
<OperationResponse>
<Type>SUCCESS</Type>
<Code>0</Code>
<ResponseDetails>
<ResponseDetail>
<Message>Operation completed successfully</Message>
</ResponseDetail>
</ResponseDetails>
</OperationResponse>
</soapenv:Body>
</soapenv:Envelope>


Related Topics



Leave a reply



Submit