I am trying to build an XML structure for a WSDL call, since there isn't a real proper way to send an arbitary size list of complex objects using the parameter passing method, I decided to use Json to XML. Here is my basic Json
school:{
teachers : [
{students :[{name: student1}, {name: student2}], name : teacher1},
{students :[{name: student3}, {name: student4}], name : teacher2}
]
}
and what I want to see as an end result is
<school>
<teachers>
<name>teacher1</name>
<students>
<name>student1</name>
<name>student2</name>
</students>
</teachers>
<teachers>
<name>teacher1</name>
<students>
<name>student1</name>
<name>student2</name>
</students>
</teachers>
</school>
Using what Apigee Documentation
<ArrayRootElementName>Teachers</ArrayRootElementName>
It still would handle the Students properly, in fact it changes my Students to Teachers. Can someone help please.
To get the XML you desire out of the JSONToXML Policy, you must shape the input JSON differently. The input to JSONToXML should look like this:
{
"school": {
"teachers": [
{
"students": {
"name": [
"student1",
"student2"
]
},
"name": "teacher1"
},
{
"students": {
"name": [
"student3",
"student4"
]
},
"name": "teacher2"
}
]
}
}
But your input isn't like that. How do you get it to look like that?
You can do it with a Javascript transform. Use a Javascript to re-map the original JSON to the JSON you want. Here's an example:
var c = context.getVariable('response.content') + '',
body = JSON.parse(c);
if (body.school) {
if (body.school.teachers) {
body.school.teachers.forEach(function(item){
if (item.students) {
item.students = fixupStudents(item.students);
}
});
//body.school.teachers = fixupTeachers(body.school.teachers);
}
}
the function fixupStudents looks like this:
function fixupArray(obj, propName, accessor) {
var type = Object.prototype.toString.call(obj), i,
a = [], rval = {};
if (null !== obj) {
if (type === "[object Array]") {
for (i=0; i<obj.length; i++) {
a.push(accessor(obj[i])); // string
}
rval[propName] = a;
}
}
return rval;
}
function fixupStudents(obj) {
return fixupArray(obj, 'name', function(o){return o.name;});
}
Here's a gist that will do the trick.
You must run this JS step BEFORE the JSONToXML step.