How can I convert the following SQL output into XML using Dataweave in Mule 4?
SELECT s.RefId
,s.LocalId
,s.StateProvinceId
,s.SchoolName
,e.Email
,e.EmailType
FROM SchoolInfo s
LEFT OUTER JOIN SchoolEmail e
ON e.SchoolRefId = s.RefId
WHERE s.RefId = :ref_id
The output in SQL is:
RefId LocalId StateProvinceId SchoolName Email Type
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School steven@gmail.com prm
7FDF722B-6BBA-4BF0-8205-A5380B269EF1 1 SA Steve's School test@gmail.com sec
The XML output should look like this:
<ns0:SchoolInfo xmlns:ns0="http://www.sifassociation.org/datamodel/au/3.4" RefId="7FDF722B-6BBA-4BF0-8205-A5380B269EF1">
<ns0:LocalId>1</ns0:LocalId>
<ns0:StateProvinceId>SA</ns0:StateProvinceId>
<ns0:SchoolName>Steve's School</ns0:SchoolName>
<ns0:SchoolEmailList>
<ns0:Email Type="prm">steven@gmail.com</ns0:Email>
<ns0:Email Type="sec">test@gmail.com</ns0:Email>
</ns0:SchoolEmailList>
</ns0:SchoolInfo>
Thanks, Steve
Here's the DW expression that will generate the same XML:
%dw 2.0
output application/xml
ns ns0 http://www.sifassociation.org/datamodel/au/3.4
var rId = payload[0].RefId
var lId = payload[0].LocalId
var sId = payload[0].StateProvinceId
---
ns0#SchoolInfo @(RefId: rId): {
ns0#LocalId: lId,
ns0#StateProvinceId: sId,
ns0#SchoolEmailList: payload reduce (e,acc={}) -> acc ++ {
ns0#Email @(Type: e.Type): e.Email
}
}
I assume the RefId
, LocalId
, and StateProvinceId
will always be same per query.
Explanation of reduce
:
reduce
is explained here in detail along with its theoretical foundations. Here's also reduce
's MuleSoft documentation page. This last page does a pretty good job explaining reduce
Now in my own words, reduce
takes as an input (1) an array and (2) a lambda function.
The array contains the elements reduce
will iterate over in a similar fashion as a map
function does. The similarities between the map
and reduce
functions ends here :).
The lambda function expects two arguments: (1) the current element you iterate from the array and (2) the accumulator. The accumulator can be initialized into a value (I set it to an object {}
in your use-case because XML does not like arrays). The result of the lambda function for this FIRST iteration is set as the accumulator for the next iteration and so on.
The result of reduce
is the accumulator once iterating over the array is done.
Thus, if I was to trace this specific reduce
it will look something like this and I simplify the denotation of these values:
/*
* 1st iteration: (e=steven@gmail.com, acc={}) -> acc + {Email: steven@gmail.com}
* 2nd iteration: (e=test@gmail.com, acc={Email: steven@gmail.com} -> acc + {Email: test@gmail.com}
* result: acc = {Email: steven@gmail.com, Email: test@gmail.com}
*/
Could you please explain the reduce function and your empty array?
I’ll add the expansion of
reduce
as part of the answer.Thanks George, great explanation - still getting my head around the functions.
There is training MuleSoft offers specifically for DW: training.mulesoft.com/instructor-led-training/apdev-dataweave4