3

The contract with the client is to send JSON payload in rest web service call. In my Mule flow, I process XML and before doing web service call, convert it into JSON using

<json:xml-to-json-transformer>

which was working fine barring couple of issues. One of that is in XSD an element is defined with maxOccurs="5", but most of the time this element occurs in XML only 1 time. So the problem is:

  1. When an array has more than 1 entry, it is serialized correctly
  2. When the array has only 1 entry, it is serialized not as an array, but as a single dictionary.

So, for this XML:

<team>
 <employee>
  <name>Joe</name>
  <surname>Bloggs</surname>
 </employee>
 <employee>
  <name>Jane</name>
  <surname>Doe</surname>
 </employee>
</team>

JSON is:

{
team:{
 employee:[
  {
    name:'Joe',
    surname:'Bloggs'
  },
  {
    name:'Jane',
    surname:'Doe'
   }
  ]
 }
}

but for this XML

<team>
 <employee>
  <name>Joe</name>
  <surname>Bloggs</surname>
 </employee>
</team>

the JSON produced is:

{
  team:{
    employee:{
      name:'Joe',
      surname:'Bloggs'
    }
  }
}

The problem here is that client expects the value of employee to be an array (which it isn’t), violating the contract.

I read with the custom-transformer and Object Mapper, may be there is a way to specify which single element in XML should be forced to array in JSON or inject XSD. Is there a way?

3 Answers 3

1

Unfortunately there is no direct way of telling the JSON XML to JSON transformer to treat the element as an Array.

There are two options:

1. Implement a custom JSON transformer of Jackson and use the Force Array option. Please refer to the Jackson webpages for more detials.

2. If possible convert your XML to Java Object. 
The object will definitely would have defined the elements as an array or colelction.
Then convert the object to JSON which would be the final expected result of sinngle element as Array in JSON.


 <mulexml:jaxb-xml-to-object-transformer name="XmlToObject" jaxbContext-ref="JAXBContext" returnClass="java.lang.Object"/>
 <json:object-to-json-transformer doc:name="Object to JSON"/>

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Using the Force Array option, how would it differentiate the element with single value which needs to convert to array versus which do not?
Even I got the same question, but haven't looked into that option in-depth. Give it a try. Option two is what I have executed and verfiied that it works.
1

here is a different approach using dataweave.

%dw 1.0
%output application/json
---
{
    team: {
        employee: payload.team.*employee default []
    }
}

result is a employee attribute, wich always contains a list.

for default [] to work you must specify the reader configuration like this:

<dw:transform-message metadata:id="06021518-b51d-4dbf-983d-b47ed5ffd0bc" doc:name="Transform Message">
    <dw:input-payload doc:sample="team.xml" mimeType="application/xml">
        <dw:reader-property name="nullValueOn" value="blank"/>
    </dw:input-payload>
    <dw:set-payload><!-- content of dataweave left out --></dw:set-payload>
</dw:transform-message>

enter image description here

Comments

0

I implemented this by adding an attribute to the element that needs to be treated as array and handling this by writing a custom Jackson transformer by extending the

Blockquote com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer .

Hope this helps anyone trying to achieve this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.