ssc ssc - 2 months ago 8
Groovy Question

Convert JSON Array to XML - Groovy

Hi I'm new to REST and JSON response. I have done SOAP based work before. I am trying to convert a JSON Array body into XML. Could someone please guide me with the kind of code to use in Groovy? I have seen several answers out there but I'm not able to modify them aptly for the JSON body I have. Any help will be much appreciated. Thanks!

Sample JSON:

[
{
"field": "GULP",
"baseDT": {
"name": "HaveAGulp",
"descriptionTx": "Gulp the water",
"flow": {
"beginDate": "2016-08-31",
"endDate": "9999-12-31"
},
"check": {
"createUserId": "GULPUSER",
"createTs": "2016-08-30 11:08:56.985204",
"lastModifiedUser": "GULPUSER",
"lastModifiedTs": "2016-08-30 11:08:56.985204"
}
}
},
{
"field": "HELP",
"baseDT": {
"name": "HelpSomeone",
"descriptionTx": "Help Help Help",
"flow": {
"beginDate": "2016-08-31",
"endDate": "9999-12-31"
},
"check": {
"createUserId": "HELPUSER",
"createTs": "2016-08-30 11:08:56.985204",
"lastModifiedUser": "HELPUSER",
"lastModifiedTs": "2016-08-30 11:08:56.985204"
}
}
}
]


Expecting XML: Since there are no node names from the JSON we still want to have serialized index for each set within the JSON array.

<jsonAsXML>
<0>
<field>GULP</field>
<baseDT>
<name>HaveAGulp</name>
<descriptionTx>Gulp the water</descriptionTx>
<flow>
<beginDate>2016-08-31</beginDate>
<endDate>9999-12-31</endDate>
</flow>
<check>
<createUserId>HELPUSER</createUserId>
<createTs>2016-08-30 11:08:56.985204</createTs>
<lastModifiedUser>HELPUSER</lastModifiedUser>
<lastModifiedTs>2016-08-30 11:08:56.985204</lastModifiedTs>
</baseDT>
</0>
<1>...
</1>
</jsonAsXML>

Answer

You can try using JsonSlurper to get the JSON to traverse it, and Markupbuilder to save it as a XML. This is only an example and doesn't take in account all possibilities since I'm supposing as you show in your example that your JSON root is always an Array.

import groovy.json.*
import groovy.xml.*

def json = '''[
      {
      "field": "GULP",
      "baseDT":       {
         "name": "HaveAGulp",
         "descriptionTx": "Gulp the water",
         "flow":          {
            "beginDate": "2016-08-31",
            "endDate": "9999-12-31"
         },
         "check":          {
            "createUserId": "GULPUSER",
            "createTs": "2016-08-30 11:08:56.985204",
            "lastModifiedUser": "GULPUSER",
            "lastModifiedTs": "2016-08-30 11:08:56.985204"
         }
      }
   }
]'''

// parse your json
def slurper = new JsonSlurper().parseText(json)

// recursive helper to traverse the structure
def helper(map){
    return {
        map.each{ k,v ->
            println "$k $v"
            if(v instanceof Map){
                "$k" helper(v)
            }else if(v instanceof List){
                v.each{ element ->
                    "$k" helper(element)
                }
            }else{
                "$k"("$v")
            }
        }
    }
}

StringWriter writer = new StringWriter()
new MarkupBuilder(writer).jsonAsXml {
    // for each element in the json array
    slurper.eachWithIndex { content, index ->
        "$index"( helper(content) )
    }
}

println writer.toString()

This code returns your JSON transformed in the follow XML:

<jsonAsXml>
  <0>
    <baseDT>
      <check>
        <createTs>2016-08-30 11:08:56.985204</createTs>
        <createUserId>GULPUSER</createUserId>
        <lastModifiedTs>2016-08-30 11:08:56.985204</lastModifiedTs>
        <lastModifiedUser>GULPUSER</lastModifiedUser>
      </check>
      <descriptionTx>Gulp the water</descriptionTx>
      <flow>
        <beginDate>2016-08-31</beginDate>
        <endDate>9999-12-31</endDate>
      </flow>
      <name>HaveAGulp</name>
    </baseDT>
    <field>GULP</field>
  </0>
</jsonAsXml>

NOTE: The XML normally has an xsd however JSON is a more "free" format, so in it's spec attribute order is not mandatory due to this JsonSlurper returns a groovy.json.internal.LazyMap which don't care about. This is why the XML elements are not in the order you expect.

Comments