json xml converter having array in json string
Asked Answered
S

4

1

I need to convert a json to xml and later on converting that json back to xml, but i am loosing the json array object while this conversion - I am using org.json lib.

Json String -

{
    "readResult": {
        "errors": [{
            "code": 400
        }]
    }
}

Codebase - using org.json lib

String xml = XML.toString(new JSONObject("inputjsonstring"));
String json = XML.toJSONObject(xml).toString();

Output xml and json -

XML - <readResult><errors><code>400</code></errors></readResult>
JSON - 
{
        "readResult": {
            "errors": {
                "code": 400
            }
        }
}

Here this json doesn't have any array as it was in original json. Please suggest alternate library to do the same.

Sponge answered 20/3, 2017 at 9:56 Comment(3)
Did you make a typo? You write "json back to xml", but it should probably be "xml back to json", right?Leacock
Maybe this issue can help you? https://mcmap.net/q/324619/-convert-json-to-xmlLeacock
Underscore-java library can convert json to xml and vice verse. Array with single element is supported.Bittersweet
S
2

Json specification says that json can have datatypes like string,number, boolean, array, object and null.

single element array in json is a special case which gives problem with some api like org.json. Because these library treat single element array as normal json object and not an json array object.

To solve this problem we need a library which support all the datatypes of a Json. We can use xslt transformation to solve this problem. In XSLT 3.0 there are 2 funtions json-to-xml() and xml-to-json() which works perfect for this problem. I have solved similar problem using this way. These functions transform json to xml and vice versa considering all the data type of json. for eg. In a json if you give value as number, boolean or string library will maintain these data types at the time of converstion (xml to json or vice versa so that after conversion in xml you can see particular datatype of a value in genrated xml). We can see in genrated xml that any key in json is always string type.

More on below link xslt 3.0 json-to-xml and xml-to-json conversion

Check both conversion examples on below xsltfiddle links

Json to xml convertion

https://xsltfiddle.liberty-development.net/6qVRKvS

get back Json from previous xml

https://xsltfiddle.liberty-development.net/94hvTyU

Below is a complete java example of this conversion using XSLT and Saxon 9.8 HE (HE means home edition. It's open source product provides implementations of XSLT (3.0)

First you need to run json2XML.java which will genrate outputSampleXML.xml. This outputSample.XML will have conversion from json to xml and it will be input of our next program named xml2json.java. This program will give you back your original json containing single array element.

pom.xml dependency

    <dependency>
        <groupId>net.sf.saxon</groupId>
        <artifactId>Saxon-HE</artifactId>
        <version>9.8.0-8</version>
    </dependency>
<!-- Below just to pretty print json on console-->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.2</version>
    </dependency>

inputJSON.xml

<your_data_here>
{
    "Request": [{
        "price": "1400",
        "test": "dummydata"
    }]
}
</your_data_here>

json2xml.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">
    <xsl:output indent="yes" />
    <xsl:template match="your_data_here">
        <xsl:copy-of select="json-to-xml(.)" />
    </xsl:template>
</xsl:stylesheet>

json2XML.java

public class json2XML {
public static void simpleTransform(String sourcePath, String xsltPath, String resultDir) {
    TransformerFactory tFactory = TransformerFactory.newInstance();
    try {
        Transformer transformer = tFactory.newTransformer(new StreamSource(new File(xsltPath)));
        transformer.transform(new StreamSource(new File(sourcePath)), new StreamResult(new File(resultDir)));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public static void main(String[] args) {
    simpleTransform("src/main/java/sampleJSON.xml", "src/main/java/json2xml.xsl",
            "src/main/java/outputSampleXML.xml");
    System.out.println("Done!!!");

}

}

outputSampleXML.xml

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <array key="Request">
      <map>
         <string key="price">1400</string>
         <string key="test">dummydata</string>
      </map>
   </array>
</map>

xml2json.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">
  <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="/">
      <xsl:value-of select="xml-to-json(., map { 'indent' : true() })"/>
  </xsl:template>
</xsl:stylesheet>

xml2JSON.java

public class json2XML {
public static void simpleTransform(String sourcePath, String xsltPath, String resultDir) {
    TransformerFactory tFactory = TransformerFactory.newInstance();
    try {
        Transformer transformer = tFactory.newTransformer(new StreamSource(new File(xsltPath)));
        transformer.transform(new StreamSource(new File(sourcePath)), new StreamResult(new File(resultDir)));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public static void main(String[] args) {
    simpleTransform("src/main/java/sampleJSON.xml", "src/main/java/json2xml.xsl",
            "src/main/java/outputSampleXML.xml");
    System.out.println("Done!!!");

}

}

Output on Console on running xml2JSON.java

{
    "Request": [{
        "price": "1400",
        "test": "dummydata"
    }]
}

Note you can keep both the xsl file in a java String object as a constant and use them as inputStream in transformer java code. So that you won't need to make seprate xsl files. But that is other part of problem and need not to concentrate here.

Stunner answered 24/4, 2018 at 20:2 Comment(0)
B
1

Underscore-java has the capability to convert JSON to XML and vice versa.

Resulted xml:

<?xml version="1.0" encoding="UTF-8"?>
<readResult>
  <errors array="true">
    <code number="true">400</code>
  </errors>
</readResult>
Bittersweet answered 12/11, 2019 at 0:39 Comment(0)
T
0

There is no way that from the XML string

<readResult>
     <errors>
           <code>400</code>
     </errors>
 </readResult>

, the library can "guess" that code is an array

To do these kind of things, you will need to go via a Java model and use a Library such as Jackson to regenerate the JSON

There are several alternatives to map from XML to Java: XStream is one of them

Transference answered 20/3, 2017 at 10:51 Comment(2)
I am having a json in the start, while converting json to xml, there should be some flag attribute that can define if the xml element is an array. I'll look into XStream if i can found some solution.Sponge
You can use json-to-xml() function from XSLT 3.0: w3.org/TR/xslt-30/#json-to-xml-mappingUnfleshly
L
0

Maybe you can be helped with the JSON-XML mapping described here:

The readers and writers produced by the JsonReaderWriterFactory provide an XML API over JavaScript Object Notation (JSON) content. (source)

It can convert:

{
    "readResult": {
        "errors": [{
            "code": 400
        }]
    }
}

to:

<root type="object">
    <readResult type="object">
        <errors type="array">
            <item type="object"><code type="number">400</code></item>
        </errors>
    </readResult>
</root>

NB: I also implemented this conversion in JavaScript and in PHP.

Leacock answered 25/3, 2017 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.