How to convert properties from a properties file
creditmaster.metadata.AverageFicoScore=700
creditmaster.a.b.c=xyz
into this json format in a generic way
{
creditmasterMetaData: [
{
attributeKey: "AverageFicoScore",
attributeValue: 700
}
]
}
This script is generic in that it doesn't matter what are the parts of the key, it only groups by the first element (before of the first dot) and the key name after the last dot, it ignores everything in the middle:
%dw 2.3
output application/java
import * from dw::core::Strings
fun mapProperties(props) =
entriesOf(props) // since Mule 4.3 / DW 2.3
filter (substringAfter($.key, ".") startsWith "metadata.") // to filter keys with .metadata.
groupBy ((item, index) -> substringBefore(item.key, "."))
mapObject ((value, key, index) ->
(key): value map {
attributeKey: substringAfterLast($.key, "."),
attributeValue: if (isInteger($.value)) $.value as Number else $.value
}
)
---
mapProperties(payload)
Input file:
creditmaster.metadata.AverageFicoScore= 700
other.a.b= 123
creditmaster.a.b.c=xyz
something.metadata.another.maximum=456
creditmaster.metadata.different.minimum=500
Output (in JSON for clarity):
{
"something": [
{
"attributeKey": "maximum",
"attributeValue": "456"
}
],
"creditmaster": [
{
"attributeKey": "minimum",
"attributeValue": "500"
},
{
"attributeKey": "AverageFicoScore",
"attributeValue": "700"
}
]
}
One alternative is using the pluck function. It lets you iterate over an object receiving the entries.
If you have this input
{
"creditmaster": {
"metadata": {
"AverageFicoScore": "700",
"OtherData": "Some value"
}
}
}
with this transformation
{
creditmasterMetaData:
payload.creditmaster.metadata pluck ((value, key, index) ->
{
attributeKey: key,
attributeValue: value
}
)
}
you get this output
{
"creditmasterMetaData": [
{
"attributeKey": "AverageFicoScore",
"attributeValue": "700"
},
{
"attributeKey": "OtherData",
"attributeValue": "Some value"
}
]
}
Related
I'm new to dataweave and trying to transform the array and iterate over the "||" values
Input:
[
{
"card":"VISA$$0.0||MASTER$$140.0"
},
{
"card":"VISA$$0.0||MASTER$$147.0"
}
]
The DataWeave code that I tried:
%dw 2.0
output application/json
---
"CardList":payload map (data,index) ->
{
(data.card splitBy "||" map {
"sur": $
})
}
Expected response :
{
"cardList": [
{
"card": "VISA$$0.0"
},
{
"card": "MASTER$$140.0"
},
{
"card": "VISA$$0.0"
},
{
"card": "MASTER$$147.0"
}
]
}
Someone one could you please assist me here on mule 3 and 4.
thanks in advance.
Try as below - iterating through splitBy values (||)
%dw 2.0
output application/json
---
"CardList": flatten(payload map
( ($.card splitBy "||") map(item,index) ->
{
card : item
}))
I have the below dynamic response coming from third party API, now I need to transform only the particular JSON object ("MyValues") into an array.
The payload here is sample is is very large .
Current Output:
{
"Body": {
"Status": "200",
"Result": {
"MyValues":{
"Name":"ABC TEST",
"Phone":"1234"
}
}
}
}
Expected Output:
{
"Body": {
"Status": "200",
"Result": {
"MyValues":[{
"Name":"ABC TEST",
"Phone":"1234"
}]
}
}
}
You can use pattern matching based on the type received, array or object. I created a recursive function to find the instances of a key name and perform the change in a generic way.
Example:
%dw 1.0
%output application/json
%function convertToSingleArray(x, key)
x match {
// OPTIONAL :array -> x map convertToSingleArray($, key),
:object -> x mapObject {($$): [$] when ( (($$ as :string) == key) and ((typeOf $) as :string == ":object")) otherwise convertToSingleArray($, key)
},
default -> x
}
---
convertToSingleArray(payload, "MyValues")
My request payload looks something like below:
{
"AllCodes": [
{
"Code1": "ABC"
},
{
"Code2": "TUV"
},
{
"Code3": "XYZ"
}
]
}
I have a function which will replace the values in the above with a certain value. The code that I've now is below:
%dw 1.0
%output application/json
%function LookUp(codes) codes mapObject {($$): $.code} //function to return string values for above codes
%var codeLookup = LookUp(sessionVars.OutputCodes)
%var FinalCodes = payload.AllCodes map codeLookup[$] joinBy ';'
--
FinalCodes
The output of sessionVars.OutputCodes is:
{
"CodeMaster": {
"PrimaryCodes": {
"PrimarySpecCodes": {
"ABC": {
"code": "ABC-String1"
},
"TUV": {
"code": "TUV-String2"
}
}
}
}
}
The output that I am expecting is:
"ABC-String1;XYZ-String2;XYZ"
As you can see above, since the function is returning the values for only "ABC" and "TUV" codes, my final output should have the original value if no function value found.
I was trying to use a default value before map operator. But it doesn't seem to work.
We get all the values for allCodes with $ pluck $, then if codes[$] is not found, we default to the value $. I believe you just need to add default $ to your original dataweave for it to work, but I gave a complete solution for other users on StackOverflow.
%dw 1.0
%output application/json
%var outputCodes =
{
"CodeMaster": {
"PrimaryCodes": {
"PrimarySpecCodes": {
"ABC": {
"code": "ABC-String1"
},
"TUV": {
"code": "TUV-String2"
}
}
}
}
}
%var allCodes =
{
"AllCodes": [
{
"Code1": "ABC"
},
{
"Code2": "TUV"
},
{
"Code3": "XYZ"
}
]
}
%var codes = outputCodes.CodeMaster.PrimaryCodes.PrimarySpecCodes mapObject {
($$): $.code
}
---
(flatten (allCodes.AllCodes map ($ pluck $))) map (
codes[$] default $
) joinBy ';'
this produces:
"ABC-String1;TUV-String2;XYZ"
There are various ways to solve this. One could be as follows:
%dw 1.0
%output application/json
%var payload2= { "CodeMaster": { "PrimaryCodes": { "PrimarySpecCodes": { "ABC": {"code": "ABC-String1"}, "TUV": {"code": "TUV-String2"} } } } }
%var codes = payload2.CodeMaster.PrimaryCodes.PrimarySpecCodes mapObject {
($$) : $.code
}
%var finalCodes = (payload.AllCodes map {
a: $ mapObject {
a1: codes[$] default $
}
}.a.a1) joinBy ";"
---
finalCodes
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)
}
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.