Search code examples
wso2wso2-enterprise-integrator

WSO2, XML to JSON, force a single element to be treated as array


In Enterprise Integrator 6.6.0 I'm converting a XML to JSON payload.

If the XML source has a single element it gets obviously treated as a single object

<items>
 <item></item>
</items>

becomes

{
    "items": {
        "item": {}
    }
}

but if there are more element, the specific object is treated as an array

<items>
 <item></item>
 <item></item>
</items>

becomes

{
    "items": {
        "item": [{}, {}]
    }
}

Is there a way to align the conversion of a specific sub-object? In this case, I'm trying to always return an item array, even when there is only a single element.

I read about the xml-multiple property but I couldn't understand how to use it; is it to be set manually to the source xml payload?


Solution

  • You can use the Json transform mediator[1] to achieve your use-case. Here we need to define the json schema to match the expected data structure. For the above case you will be able to use a json schema similar to the following.

     {
      "$schema": "http://json-schema.org/draft-04/schema#",
      "type": "object",
      "properties": {
        "items": {
          "type": "object",
          "properties": {
            "item": {
              "type": "array",
              "items": [
                {
                  "type": "object"
                }
              ]
            }
          },
          "required": [
            "item"
          ]
        }
      },
      "required": [
        "items"
      ]
    }
    

    This specifies that the item is an array. Then the schema can be added to the registry [2] and referred in the json transform mediator. The Json transform mediator needs to be added after the xml to json transformation. Refer to the following sample proxy service.

    <?xml version="1.0" encoding="UTF-8"?>
    <proxy xmlns="http://ws.apache.org/ns/synapse"
           name="transform"
           startOnLoad="true"
           statistics="disable"
           trace="disable"
           transports="http,https">
       <target>
          <inSequence>
             <property name="messageType" scope="axis2" value="application/json"/>
             <property name="ContentType" scope="axis2" value="application/json"/>
             <jsontransform schema="conf:/schema.json"/>
             <respond/>
          </inSequence>
       </target>
       <description/>
    </proxy>
               
    

    input 1

    <items>
     <item><val1></val1></item>
     <item><val1></val1></item>
    </items>
    

    output 1

    {
        "items": {
            "item": [
                {
                    "val1": null
                },
                {
                    "val1": null
                }
            ]
        }
    }
            
    

    input 2

    <items>
     <item><val1></val1></item>
    </items>
    

    output 2

    {
        "items": {
            "item": [
                {
                    "val1": null
                }
            ]
        }
    }
    

    [1]-https://docs.wso2.com/display/EI660/JSON+Transform+Mediator

    [2]-https://docs.wso2.com/display/EI660/Managing+the+Registry+