My Input
{
"Root": {
"order": [
{
"locale": "en-US",
"orderItems": [
{
"product": {
"partNumber": "23853864"
},
"itemSpecifics": {
"options": {
"color": "Olive",
"size": "S"
},
"actualPrice": "7",
"customItemData": {
"TEMP_8401": "8.95",
"TEMP_150207": "3.00"
}
}
}
]
}
... Large amount of JSON Data ...
]
}
}
Expected output
{
"Root": {
"order": [
{
"locale": "en-US",
"orderItems": [
{
"product": {
"partNumber": "23853864"
},
"itemSpecifics": {
"options": {
"color": "Olive",
"size": "S"
},
"actualPrice": "7",
"customItemData": {
"8401": "8.95",
"150207": "3.00"
}
}
}
]
}
... Large amount of JSON Data ...
]
}
}
I want to remove "TEMP_" in the "customItemData" object keys, but I don't want to manually remap the entire JSON object again, assigning properties one by one. Is there any alternative? Any shorter logic in DataWeave? I'm using Mule 3.9.0.
This uses recursion and pattern matching to walk through the data structure and modify the keys. If the key doesn't contain the string "TEMP" it leaves it as is, if it does, it modifies it according to your requirements.
%dw 1.0
%output application/json
%function applyToKeys(e, fn)
e match {
:array -> $ map ((v) -> applyToKeys(v, fn)),
:object -> $ mapObject ((v, k) -> {(fn(k)): applyToKeys(v, fn)}),
default -> $
}
---
applyToKeys(payload,
((key) -> ((key as :string) splitBy "_" )[1]
when ((key as :string) contains "TEMP")
otherwise key))
Please keep in mind the tradeoffs when using a solution like this. The code is certainly less verbose, but it requires a solid understanding of advanced concepts like recursion, pattern matching, lambdas, and higher order functions.
Related
I need to compare two fields in a array and replace their values with different data and output in separate objects
Here is my sample input array:
{
"data": [
{
"house": "house1",
"condition": "bad",
"age": "old",
},
{
"house": "house2",
"condition": "good",
"age": "new",
}
]
}
Output should be
{
"data": [
{
"house": "house1",
"condition": "repair"
},
{
"house": "house1",
"age": "over50",
},
{
"house": "house2",
"condition": "No repair",
},
{
"house": "house2",
"age": "recent"
}
]
}
If condition is "bad" I need to replace with "repair" else if condition is "good" I need to replace with "No repair".
Same type of logic. for the age field. If age is "old" I need to replace with "Over50" and if age is "new" I need to replace with "recent". The two fields(age and condition) are going to be in every iteration
As aled suggested, Map would do this along with OrderBy.
%dw 2.0
output application/json
var a=payload.data
---
"data":(a map{
"house": $.house,
"condition":if (($.condition)=="bad") "repair" else "No repair"
} ++ (a map{
"house": $.house,
"age":if (($.age)=="old") "over50" else "recent"
})orderBy $.house)
Output
{
"data": [
{
"house": "house1",
"condition": "repair"
},
{
"house": "house1",
"age": "over50"
},
{
"house": "house2",
"condition": "No repair"
},
{
"house": "house2",
"age": "recent"
}
]
}
Alternative solution with a single map (you map to an array of the 2 objects required and then flatten the result):
%dw 2.0
output application/json
fun mapCondition(cond : String) = if (cond == "bad") "repair" else "No repair"
fun mapAge(age : String) = if (age == "old") "over50" else "recent"
---
{
data : flatten(payload.data
map ((item, index) ->
[
{
house: item.house,
condition: mapCondition(item.condition)
},
{
house: item.house,
age: mapAge(item.age)
}
]))
}
Use map() over data array and use if conditions to transform the field of each element inside the map. Seems pretty direct.
You can also apply map and flatten with a single call to flatMap.
%dw 2.0
output application/json
---
data: payload.data flatMap [
{
house: $.house,
condition: $.condition match {
case 'bad' -> 'Repair'
else -> 'No Repair'
}
},
{
house: $.house,
age: $.age match {
case 'old' -> 'over50'
else -> 'new'
}
}
]
I have a requirement wherein I have to convert JSON data from one format to other.
I have to fetch corresponding values of JSON array and make them a key value pair.
Below are the required details:
Input:
"Headers": {
"Header": [
{
"Key": "SellerOrganization",
"Value": "XYZ"
},
{
"Key": "SellerType",
"Value": "B2C"
},
{
"Key": "Region",
"Value": "SOUTH"
},
{
"Key": "OrderType",
"Value": "RETURN"
},
{
"Key": "InvoiceType",
"Value": ""
},
{
"Key": "EventType",
"Value": "Created"
},
{
"Key": "EntryType",
"Value": "Call Center"
}
]
}
Expected Output:
{
SellerOrganization:XYZ,
SellerType: B2C,
Region:SOUTH,
OrderType:RETURN,
InvoiceType:"",
EventType:Created,
EntryType:Call Center
}
You can use the dynamic object that it will basically do what you want.
%dw 2.0
output application/json
---
{
(payload.Headers.Header map ((item, index) -> {
(item.Key): item.Value
})
)
}
You can take advantage of reduce function here which will let you convert your array to an key, value pair object
%dw 2.0
output application/json
---
payload.Header reduce ((item, acc = {}) -> acc ++ {
(item.Key): item.Value
})
Case
I have a json object (as imported from excell file, and it needs to be formatted like one as well afterwards). So i can not mess with the structure at all.
The input consists of a json formatted object with sheets, every sheet is an array of objects.
I want to add another object (the var 'append') to the array (as last item) when the sheetnumber equals the kwadrantcode in the 'append' object
input 1
The payload
{
"(sheet)1": [
{
"kwadrantId": 1.0,
"Team": "blauw1",
"timestamp": "2019-09-26T16:37:54",
"controlecode": 12431
}
],
"(sheet)2": [
{
"kwadrantId": 2.0,
"Team": "rood1",
"timestamp": "2019-09-26T16:37:54",
"controlecode": 81243
},
{
"kwadrantId": 2.0,
"Team": "blauw2",
"timestamp": "2019-09-26T18:00:54",
"controlecode": 67676
}
]
}
the code so far
%dw 2.0
output application/json
var append = {"kwadrant": "2",
"controlecode": "22222",
"kleur": "blauw",
"subteam": "1",
"form_id": "83177",
"submit": "Claim"
}
---
payload pluck($) map (sheet, sheetnumber)-> (sheet map (claim, claimcounter) -> claim) ++ [append]
This code succesfully appends the object to the array at the right location.
The Problem here is that this last part (the map target) does not seem to allow a conditional.
So it will always insert it at the end of every list, not just the one where i want it to end up.
[
[
{
"kwadrantId": 1.0,
"Team": "blauw1",
"timestamp": "2019-09-26T16:37:54",
"controlecode": "12431"
},
{
"kwadrant": "2",
"controlecode": "22222",
"kleur": "blauw",
"subteam": "1",
"form_id": "83177",
"submit": "Claim"
}
],
[
{
"kwadrantId": 2.0,
"Team": "rood1",
"timestamp": "2019-09-26T16:37:54",
"controlecode": "12431"
},
{
"kwadrantId": 2.0,
"Team": "blauw2",
"timestamp": "2019-09-26T18:00:54",
"controlecode": 67676.0
},
{
"kwadrant": "2",
"controlecode": "22222",
"kleur": "blauw",
"subteam": "1",
"form_id": "83177",
"submit": "Claim"
}
]
]
A few things i have tried
honestly, i think i've tried everything the past two hours, but here are a few i can think of out of the top of my head.
++ [append] if (true)
(if true )++ [append]
payload pluck($) map (sheet, sheetnumber)-> (sheet map (claim, claimcounter) -> claim)((if true) ++ [append])
and most variations i can think of with brackets
I will worry about formatting the 'append' var to the right structure later, just getting it in the right spot is the issue i can't seem to get working.
The simplest way that I can think of is to use the mapObject function
%dw 2.0
output application/json
var append =
{
"kwadrant": "2",
"controlecode": "22222",
"kleur": "blauw",
"subteam": "1",
"form_id": "83177",
"submit": "Claim"
}
fun extractNumber(pageName: Key) =
(pageName as String match /\(sheet\)([0-9]+)/)[1]
---
payload mapObject ((value, key, index) -> do {
if(extractNumber(key) == append.kwadrant)
{(key): value << append}
else
{(key): value}
})
So basically I will go for every sheet in the root and when it matches the one I need to add append it to the value using the <<
Hi I need to transform the following JSON object:
{
"products": [
{
"itemno": "123131",
"description" : "Big Widget",
"attributes": [
{
"color": [
{
"value": "Red",
"codeValue": "RED_NO2"
},
{
"value": "Blue Licorice",
"codeValue": "BLUE-355"
}
]
},
{
"chemicals": [
{
"value": "Red Phosphorous",
"codeValue": "RED_PHOS"
},
{
"value": "Chlorine Bleach",
"codeValue": "CHLRN_BLCH"
}
]
}
]
}
]
}
I am trying to transform this with each attribute having an array of values where their value is the codeValue and it's an array of those string values.
This is the desired output:
{
"products": [
{
"itemno": "123131",
"description: : "Big Widget",
"attributes": [
{
"color": ["RED_NO2", "BLUE-355"]
},
{
"chemicals": ["RED_PHOS", "CHLRN_BLCH"]
}
]
}
]
}
This is the Dataweave. I cannot determine how to get the attribute names (i.e. color, chemicals as keys with the desired data.
There is not a lot of good examples on transforming data with Dataweave and I have spent a lot of time trying to figure this out.
This is one of the dataweaves that got there somewhat, but isn't the solution:
%dw 1.0
%output application/json
---
payload.products map
{
"ItemNo" : $.sku,
"Desc" : $.description,
"Test" : "Value",
"Attributes" : $.attributes map
{
'$$' : $ pluck $.value
}
}
Your help is greatly appreciated.
You can do something like this:
%dw 1.0
%output application/json
%function attributeCodeValues(attributes)
attributes map ((attr) ->
attr mapObject ((values, descriptor) ->
{
(descriptor): values map $.codeValue
}
)
)
---
payload.products map {
"ItemNo" : $.sku,
"Desc" : $.description,
"Test" : "Value",
"Attributes" : attributeCodeValues($.attributes)
}
Im am new to MuleSoft.I am trying to transform a JSON payload,using transform.
I want to transform my payload as below
Input:
{
"ResponseStatus": {
"Status": "SUCCESS",
"StatusText": "SUCCESS"
},
"Processes": {
"Process": [
{
"ProcessId": "1234567",
"ProcessProperties": {
"Property": [
{
"Name": "XXXXXXXXXXX",
"Value": "11111111",
"Desc": "YYYYYYYY"
},
{
"Name": "AAAAAAAAA",
"Value": "2222222",
"Desc": "BBBBBBBB"
},
{
"Name": "QQQQQQQQQ",
"Value": "#######",
"Desc": "CCCCCCCC"
},
{
"Name": "NNNNNNN",
"Value": "IIIIIIII",
"Desc": "UYUYUYUY"
}
]
},
"EditMode": "CCCCCC",
"ProcessType": "ABCD",
"AppName": "VFVFVGBG",
"StatusHistory": {
"STS": [
{
"Sts": "COMPLETED"
}
]
}
}
]
}
}
Output:
[
{
"ProcessId": "1234567",
"AAAAAAAAA": "2222222",
"QQQQQQQQQ": "#######"
}
]
I have read DWL reference from below Mulesoft link.Also reffered this SO link.
Below is what I have tried so far,
%dw 1.0
%output application/json
---
{
"ProcessId": (payload.Processes.Process.ProcessId)[0],
AAAAAAAAA: {
(payload.Processes.Process.ProcessProperties.Property mapObject {
($.Name):$.Value when $.Name =="AAAAAAAAA" otherwise ""
})
},
QQQQQQQQQ: {
(payload.Processes.Process.ProcessProperties.Property mapObject {
($.Name):$.Value when $.Name =="QQQQQQQQQ" otherwise ""
})
}
}
I am still not able to get the desired output.
It gives me "Cannot coerce a :array to a :key"
Can anyone please help me?
The "property" json element in your input json is "Array",which it is not able to parse to a single value.
Please try below snippet and let me know if that gives your deisred o/p.
payload.Processes.Process map (
(val , index) ->
{"ProcessId":(payload.Processes.Process.ProcessId)[0]
,
(val.ProcessProperties.Property map {
(($.Name) : $.Value) when $.Name =='AAAAAAAAA' }
),
(val.ProcessProperties.Property map {
(($.Name) : $.Value) when $.Name =='QQQQQQQQQ' }
)
}
)