Search code examples
jsonxsltwso2wso2-enterprise-integratorwso2-micro-integrator

Transforming embeded JSON string to a proper JSON object


I am using an XSLT mediator to transform an XML payload into a JSON payload, but the resulting JSON output is not as expected since the whole JSON is wrapped as a field value. Also, I just need to use this XSLT mediator, not any others. Here is my XSLT code:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:ns="http://service.com">
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
{
    "response": {
        "animals": {
            "animal": [
                <xsl:for-each select="//ns:animal">
                {
                    "name": "<xsl:value-of select="ns:name"/>",
                    "color": "<xsl:value-of select="ns:color"/>",
                    "info": {
                        "animalInfo": [
                            <xsl:for-each select="ns:info/ns:animalInfo">
                            {
                                "someVal1": "<xsl:value-of select="ns:someVal1"/>",
                                "someVal2": "<xsl:value-of select="ns:someVal2"/>"
                            }<xsl:if test="position() != last()">,</xsl:if>
                            </xsl:for-each>
                        ]
                    }
                }<xsl:if test="position() != last()">,</xsl:if>
                </xsl:for-each>
            ]
        }
    }
}
</xsl:template>
</xsl:stylesheet>

And here is the resulting JSON output as a string inside a "text" field. The whole JSON is wrapped as a text field value:

NOTE: When it's wrapped there are escape characters \. I removed them to make the JSON clear.

{
   "text": "{
      "response":{
         "animals":{
            "animal":[
               {
                  "name": "name",
                  "color": "color",
                  "info":{
                     "animalInfo":[
                        {
                           "someVal1":"someVal1",
                           "someVal2":"someVal2"
                        },
                        {
                           "someVal1":"someVal3",
                           "someVal2":"someVal4"
                        }
                     ]
                  }
               },
               {
                  "name": "name",
                  "color": "color",
                  "info":{
                     "animalInfo":[
                        
                     ]
                  }
               }
            ]
         }
      }
   }"
}

The JSON response I need after removing the text field and unwrapping its value,

  {
    "response":{
             "animals":{
                "animal":[
                   {
                      "name": "name",
                      "color": "color",
                      "info":{
                         "animalInfo":[
                            {
                               "someVal1":"someVal1",
                               "someVal2":"someVal2"
                            },
                            {
                               "someVal1":"someVal3",
                               "someVal2":"someVal4"
                            }
                         ]
                      }
                   },
                   {
                      "name": "name",
                      "color": "color",
                      "info":{
                         "animalInfo":[
                            
                         ]
                      }
                   }
                ]
             }
          }
       }
    }

Unedited JSON Payload.

{
   "text": "{\"response\":{\"animals\":{\"animal\":[{\"name\":\"name\",\"color\":\"color\",\"info\":{\"animalInfo\":[{\"someVal1\":\"someVal1\",\"someVal2\":\"someVal2\"},{\"someVal1\":\"someVal3\",\"someVal2\":\"someVal4\"}]}},{\"name\":\"name\",\"color\":\"color\",\"info\":{\"animalInfo\":[]}}]}}}"
}

I tried so hard to unwrap the JSON from this text field but I am unable to resolve it and even not sure why this is keep happening. Can someone please help me to resolve this using XSLT? Thanks in advance.


Solution

  • You can use either the Payloadfactory Mediator or the Script Mediator here. Take a look at the following code.

    Payload Factory Mediator

    <payloadFactory media-type="json">
           <format>$1</format>
           <args>
             <arg expression="json-eval($.text)" evaluator="json"/>
           </args>
    </payloadFactory>
    

    Script Mediator

    <property expression="json-eval($.text)" name="jsonText" scope="default" type="STRING"/>
    <script language="nashornJs"><![CDATA[
        var pl = JSON.parse(mc.getProperty('jsonText'));
        mc.setPayloadJSON(pl);
    ]]></script>