Reputation: 427
I am using Mule 4.3 and Dataweave 2.x From database am getting following records example:
[
{
"gp": "G1",
"parent": "P1",
"child": "C1"
},
{
"gp": "G1",
"parent": "P1",
"child": "C2"
},
{
"gp": "G2",
"parent": "P1",
"child": "C3"
},
{
"gp": "G1",
"parent": "G1",
"child": "C4"
}
]
Each element in array represents a row of data and each row has hierarchical data (Grandparent , Parent and Child data)
I need to generate the output in XML as below:
<list>
<genealogy>
<code>G1</code>
<hierarchy>
<!-- here parent is not included in hierarchy as it has same value of grandparent -->
<genealogy>
<code>C4</code>
<hierarchy/>
</genealogy>
<!-- here 2 instances of P1 have become One value -- >
<genealogy>
<code>P1</code>
<hierarchy>
<genealogy>
<code>C1</code>
<hierarchy/>
</genealogy>
<genealogy>
<code>C2</code>
<hierarchy/>
</genealogy>
</hierarchy>
</genealogy>
</hierarchy>
</genealogy>
<genealogy>
<code>G2</code>
<hierarchy>
<genealogy>
<code>P1</code>
<hierarchy>
<genealogy>
<code>C3</code>
<hierarchy/>
</genealogy>
</hierarchy>
</genealogy>
</hierarchy>
</genealogy>
</list>
Here couple of challenges are:
I am stumped how to do the needful in Dataweave and have tried things like groupBy , pluck etc but am not able to get desired result
Upvotes: 1
Views: 185
Reputation: 3262
I have built a solution. Somehow, making this generic was more easier then make it specifically for 3 levels.
It is a bit complicated, I have explained the logic in comments within the script
%dw 2.0
output application/xml
// hierarchy's structure. If, lets say you add a "grand child" it should work. (haven't tested this though)
var hierarchy = {
gp: {
parent: {
child: null
}
}
}
fun getDirectGeanologies(records, hierarchyStructure) = do {
var topLevel = keysOf(hierarchyStructure)[0] as String
var secondLevel = keysOf(hierarchyStructure[topLevel])[0]
---
(records groupBy $[topLevel])
mapObject ((level1Childs, code) ->
genealogy: {
code: code,
hierarchy:
if(secondLevel != null) // If there are no more childs, do nothing.
(level1Childs groupBy ((item) -> item[secondLevel] ~= code) // This is to handle when parent = gp
mapObject ((value, hasSameParent) ->
// If parent = gp, we want to skip parent and link directly to child
if(hasSameParent as Boolean) getDirectGeanologies(value, hierarchyStructure[topLevel][secondLevel])
// recurrsively call the function with child records and going down the hierarchyStructure by one
else getDirectGeanologies(value, hierarchyStructure[topLevel])
))
else {}
}
)
}
---
list: getDirectGeanologies(payload,hierarchy)
Upvotes: 2