Mulesoft dataweave: How to convert xlsx file to JSON by including headers? - mule

I am trying convert xlsx to json with dataweave. JSON output is getting generated without headers from the xlsx file. My current code is skipping fisrt row of an excel file. I also need to include firstrow from the input file to output JSON. Below is my dataweave:
<dw:transform-message doc:name="Transform Message" metadata:id="8211af7d-2465-4ecd-80ea-3b6771d094e5">
<dw:input-payload mimeType="application/xlsx"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
Sheet1:payload.Sheet1 map
{
col1:$[0],
col2:$[1],
col3:$[2]
},
Sheet2:payload.Sheet2 map
{
col1:$[0],
col2:$[1],
col3:$[2]
}
}]]></dw:set-payload>
</dw:transform-message>
Input Excel file is as:
Total Value Count
Col1 Col2 Col3
Val Val Val

I was able to figure it out by adding below code to my xml:
<dw:input-payload mimeType="application/xlsx">
<dw:reader-property name="header" value="false" />
</dw:input-payload>
This worked for my requirement.

Related

how to use .equalsIgnoreCase in dw 1.0 then checking uri.params?

I have a sub flow where I want to do some action depending on uri.params values but facing issue then they are case sensitive that stop me to make a check as in some cases they come as AbcDef and sometimes as abcDef and also can be abcdef so is it possible to set value ignoring a case?
like:
%dw 1.0
%output application/java
---
{
MyKey: inboundProperties['http.uri.params'].equalsIgnoreCase(abcdef)
}
so in transform component I am expecting to receive such:
%dw 1.0
%output application/java
---
{
MyKey1: inboundProperties['http.uri.params'].abcd when
inboundProperties['http.uri.params'].abcd != null otherwise 0
MyKey2: inboundProperties['http.query.params'].efgh when
inboundProperties['http.query.params'].efgh != null otherwise 1
}
and then api call is:
http://*/flowName/{abcd}?efgh=SomeString
all working fine, but if
api call is:
http://*/flowName/{AbCd}?Efgh=SomeString
my subflow get nulls instead of values
in Dataweave there's no out-of-the-box function as in Java, but there's a simple alternative using either the upper or lower functions at the boolean condition, so you can compare both strings in the same representation.
e.g.
key: upper(inboundProperties['http.uri.params.ID']) == "ABCDEF"
The documentation for the upper function can be found here
The usual method to avoid case sensitiveness is to just change everything to lower or uppercase. In my example I just change the keys of the uri params map to lower case, so any later comparison should be made to lower case strings.
Example:
<http:listener config-ref="HTTP_Listener_Configuration" path="/test/{Param1}" doc:name="HTTP"/>
<dw:transform-message doc:name="Transform Message">
<dw:input-payload mimeType="application/java" />
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
inboundProperties['http.uri.params'] mapObject (lower $$): lower $
]]>
</dw:set-payload>
</dw:transform-message>
Test:
$ curl http://localhost:8081/test/aBc
{
"param1": "aBc"
}

Convert the values in .csv file to json format in a data weave based on the parameter in lookup function which is calling from another data weave

How to use the lookup function in data weave(1.0) which calls a flow with some parameters. Flow functionality is to convert the values in the .csv file to JSON based on the parameter in the lookup function.
The lookup fucntion docs are here:
https://docs.mulesoft.com/mule-runtime/3.9/dataweave-language-introduction
You pass in the payload as the second parameter as a Map (object):
%dw 1.0 %output application/json
---
{ a: lookup("mySecondFlow",{b:"Hello"}) }
Here is a Mule flow that can accept this object with the 'b' key:
<flow name="mySecondFlow">
<set-payload doc:name="Set Payload" value="#[payload.b + ' world!' ]"/>
</flow>
This example will produce this output:
{
"a": "Hello world!"
}

Dataweave get rid of empty lines when reading a file

I am processing a file where every other line is blank, how to get rid of these lines using dataweave or groovy?
My payload now looks like this
my transformer which is parsing the lines is:
%dw 1.0
%output application/java
---
payload map
{
line: $[0]
}
Thanks for the response
Try the same dataweave with filtering the payload. Check if anything in the incoming payload is empty or null kind of thing which is causing the issue.
%dw 1.0
%output application/java
---
payload filter ($ !=null and $ !='') map
{
line: $[0]
}

Substitute values in payload

I have an XML Message with two parameters in it which I use to call a REST service endpoint. However, if any of them are a certain value I would like to change them before my call, for example
<Interface Server="ABC" Server2="DEF"/>
If any of those have the value "ABC" it should always be replaced with "BC" and in my call to the REST service I would send param1="BC" and param2="DEF" in the above example.
I was thinking of a Choice router and check if Server is "ABC" then set a flow-variable param1="BC" but then I realized I would have to do the same again for Server2 if that one is "ABC" ...and that feels like.. it must be an easier way to achieve this?
Am I right? Could I use some clever MEL or XPATH3 expression to always substitue the values to "BC" if any of them are "ABC"?
Regards
You can try the following configuration:
<enricher doc:name="Message Enricher">
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
%var evaluation = "ABC"
%var substitution = "BC"
%function substitute(serverVal)(
serverVal when serverVal != evaluation otherwise substitution
)
---
payload.Interface.# mapObject {
($$): substitute($)
}
]]></dw:set-payload>
</dw:transform-message>
<enrich source="#[payload.Server]" target="#[variable:param1]"/>
<enrich source="#[payload.Server2]" target="#[variable:param2]"/>
</enricher>
Regardless how many attribute in your XML source, you just need to add the enricher element accordingly.
For example, you have a new XML source: <Interface Server="ABC" Server2="DEF" Server3="ABC"/>
Then you only need to add: <enrich source="#[payload.Server3]" target="#[variable:param3]"/> to set the new variable.
Notes: DataWeave is one of the EE features. For CE, you can replace it with other transformer, for example: Groovy. In the example below, the payload is in form of String. The original application/xml format is transformed to String using byte-array-to-string-transformer.
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[def attributeMap = new XmlSlurper().parseText(payload).attributes()
attributeMap.each() {
it.value = it.value == "ABC" ? "BC" : it.value
}
payload = attributeMap]]></scripting:script>
</scripting:component>

DataWeaver Mule Document section 1.1.2 and 3.4 examples not working?

Going through the Dataweaver documentaion
Link:https://developer.mulesoft.com/docs/dataweave#_attribute_selector_expressions
Section 3.4 Key Present
Trying out the example provide below .
Input:
<users>
<name>Mariano</name>
<name>Luis</name>
<name>Mariano</name>
</users>
Transform:
%dw 1.0
%input payload application/xml
%output application/xml
---
users: payload.users.name[?($ == "Mariano")]
when I try to give this expression in my DataWeaver it gives warning like cannot coerce a:string to a: array:(7,92).
Have given the same way mentioned in the document. Could anyone please advice.
Expected Response:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<name>Mariano</name>
<name>Mariano</name>
</users>
Also in the document 1.1.2 string manipulation example wasn't working for me
%dw 1.0
%input payload application/xml
%output application/json
%function words(name) name splitBy " "
---
contacts: payload.users.*user map using (parts = words($.name)){
firstName: parts[0],
(secondName: parts[1]) when (sizeOf parts) > 2,
lastName: parts[-1],
email: "$((lower $.name) replace " " with ".")#acme.com.ar",
address: $.street
}
showing error like multiple marker at this line missing '}' no viable alternative at input email
Started learning and working out the examples provided. Thanks.
The example in the docs has a typo, there is an * missing before name (it should be fixed):
%dw 1.0
%input payload application/xml
%output application/xml
---
users: payload.users.*name[?($ == "Mariano")]
The problem is that XML doesn't have a built-in list representation, so the list is represented by multiple occurences of a tag. The expression *name returns a list with the occurrences of name, the expression [?($ == "Mariano")] it's like a filter (I prefer filter since it is easier to understand).
The cryptic error message appears because the operator applies to a list, but payload.users.name returns the first appeareance of name. (That's why it says cannot coerce string to array).