how to enrich xml node value in mule [duplicate] - mule

This question already has an answer here:
replace xml particular node element value with other value in mule
(1 answer)
Closed 7 years ago.
input xml like below
<healthcare>
<plans>
<plan1>
<planid>100</planid>
<planname>medical</planname>
<desc>medical</desc>
<offerprice>3000</offerprice>
<area>texas</area>
</plan1>
<plan2>
<planid>101</planid>
<planname>dental</planname>
<desc>dental</desc>
<offerprice>4000</offerprice>
<area>texas</area>
</plan2>
</plans>
</healthcare>
<set-variable variableName="newoffer" value="2000" doc:name="Variable" />
<foreach doc:name="For Each" collection="#[xpath3('//healthcare/plans', message.payload, 'NODESET' )]">
<enricher source="#[flowVars.newoffer]" target="#[xpath3('offerprice', payload 'STRING')]" >
<logger message="...#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
</enricher>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
</foreach>
i want enrich xml element offerprice value as 2000 .but above doesn't do that. anybody have any suggestions. main thing is my expected output is like below. I'm new to mule .anyone shed light for my mule requirement.thanks in advance
<healthcare>
<plans>
<plan1>
<planid>100</planid>
<planname>medical</planname>
<desc>medical</desc>
**<offerprice>2000</offerprice>**
<area>texas</area>
</plan1>
<plan2>
<planid>101</planid>
<planname>dental</planname>
<desc>dental</desc>
**<offerprice>2000</offerprice>**
<area>texas</area>
</plan2>
</plans>
</healthcare>

To achieve your goal, remove the for-each / enricher elements and instead use the XSLT Transformer that comes bundled with Mule. This is your best choice for transforming XML to XML.

Related

How to concatenate in mule logger?

I need to concatenate text with json payload in logger component. I have tried below ways but no luck
<logger level="INFO" doc:name="Logger" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" message="#['payload is:' + payload]"/>
Even i don't see any transformers like 'object to string converter' in mule 3.
Please suggest syntax for mule 4
Try separating the text from your dataweave
i.e.
<logger level="INFO" doc:name="Logger" mesage="Payload is: #[payload]" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" />
All the various transformers were removed in Mule 4 due to the payload always being "accessible". That is, regardless of the payload type (XML, JSON, Java, CSV...) you can access fields through payload.{fieldname}. In Mule 3.x the payload had to be coerced to a Java object to allow that. You can explicitly set the output type of any dataweave expression, so you can also try:
mesage="Payload is: #[output application/java --- payload]"
It is working with below syntax
<logger level="INFO" doc:name="Logger" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" message="#['payload is:' ++ payload]"/>
I had the same issue and the below worked for me...
<logger level="INFO" doc:name="Logger" doc:id="35d4566e-02ba-495a-bd40-c30aa5a90413" message="#['Get Accounts Response Paylaod : #[payload]']"/>

Return individual values from linkedHashMap in Mule

I have an output from a webservice in Mule that returns a linkedHashMap and I need to get the individual values to be dynamically inserted into a template. The template is used to send email through the SMTP connector. I can get all values using MEL #[payload], but I can't get them one by one. I've tried #[payload.get(0)], #[payload[0]] but they all return null.
The Mule XML looks like this:
<flow name="MW_Flow">
<file:inbound-endpoint path="C:\....\1" connector- ref="File" responseTimeout="10000" doc:name="File" pollingFrequency="60000"/>
<ws:consumer config-ref="File_Read_WS" operation="all3" doc:name="FileRead DBWriter WS"/>
<dw:transform-message metadata:id="6ee92ba8-9f67-40d6-bfa3-3e237da20822" doc:name="Transform Message">
<foreach doc:name="For Each">
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<parse-template location="C:\.....\Templates\Mail.txt" metadata:id="b7d894eb-465b-47f7-a542-b49fc4fb53d9" doc:name="Parse Template"/>
<logger message="2: #[message.exception] #[message.dataType] #[payload]" level="INFO" doc:name="Logger"/>
</foreach>
</flow>
The template (plain text file) looks a bit like this:
Hello [name].
This is email from [name2]. The following event [event].....
All I get are null values except when using #[payload] which returns the whole row (4 values).
Any help greatly appreciated!
/Johan
If your payload is a Map then payload.get(0) or payload[0] will behave as if you are trying to get a value from map with 0 as key, which I guess doesn't exist in your map.
Try accessing it with name - #[payload.name] or #[payload.name2] or #[payload[name]]

Facing error in Batch Processing mule esb

I am facing problem in batch processing mule esb. If I set any payload in process record face and try to get that payload in oncomplete face then not getting that payload. same problem with variable and property.
If I set any property in process record phase and try to get in on complete phase then always get null value.
how to get those value in oncomplete phase?
below is flow..
<batch:job name="TestBatch" max-failed-records="-1">
<batch:input>
<component class="com.test.RecordTest"
doc:name="Java" />
<json:object-to-json-transformer
doc:name="Object to JSON" />
<custom-transformer class="com.test.CustomTr"
doc:name="Java" />
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step1" accept-policy="ALL">
<batch:commit size="5" doc:name="Batch Commit">
<!-- Insert record in Salesforce -->
</batch:commit>
</batch:step>
<batch:step name="Batch_Step2" accept-policy="ONLY_FAILURES">
<logger message="STEPP #[getStepExceptions()]" level="INFO" doc:name="Logger"/>
<set-property propertyName="error" value="STEPP #[getStepExceptions()]" doc:name="Property"/>
<set-payload value="#[getStepExceptions()]" doc:name="Set Payload"/>
</batch:step>
</batch:process-records>
<batch:on-complete>
<logger level="INFO" doc:name="Logger" message="--> #[payload.failedRecords] --> #[message.payload] "/>
<logger message="error--- #[message.outboundProperties['error']] " level="INFO" doc:name="Logger"/>
</batch:on-complete>
</batch:job>
I got null in property logger
How can I solve this?
I got some bad news from you :-).
Batch processing by design will not old any of the value you may try to set in steps, especially payload.
When I started working with it I was also expecting to have session variable on complete phase in a correct status but this is not the case, they are completely wiped at each step.
Now I don't think this is a bug, but it is really a design feature that I can understend even if I don't really love it.
I solved the same problem by using the object store connector.
It will allow you to access the mule Object Store API via nice XML configuration block, in this way you can store in memory variables that you can recover after in your on-complete without them being affected by flow logic.
Hope this helps

how to replace value using xpath3 expression in mule esb

<babyproducts>
<products>
<product1>
<productid>100</productid>
<productname>towel</productname>
<desc>towel</desc>
<discount>100</discount>
<validlity>10</validlity>
</product1>
<product2>
<productid>101</productid>
<productname>pillow</productname>
<desc>pillow</desc>
<discount>500</discount>
<validlity>5</validlity>
</product2>
</product>
</babyproducts>
I want to split above xml using xpath3 expression and replace the validlity value . after that i want whole set of above xml replaced values. I tried using xpath it is working fine. my requirement insists on doing using xpath3 mule expression
<splitter evaluator="xpath" expression="/babyproducts/products" doc:name="Splitter" />
<set-payload value="#[message.payload]" doc:name="Set Payload" />
<enricher source="#[flowVars.newvalidlity]" target="#[xpath('/products/validlity').text ]" doc:name="Message Enricher">
<logger level="INFO" message=" enricher done ~~~~~.." doc:name="Logger" />
</enricher>
above is my mule flow using xpath. my team wants to do using xpath3 (latest).
my expected outpu is like below with new validlity value 50 (comes from flow variable)
<babyproducts>
<products>
<product1>
<productid>100</productid>
<productname>towel</productname>
<desc>towel</desc>
<discount>100</discount>
<validlity>50</validlity>
</product1>
<product2>
<productid>101</productid>
<productname>pillow</productname>
<desc>pillow</desc>
<discount>500</discount>
<validlity>50</validlity>
</product2>
</product>
</babyproducts>
First of all your XML sample is invalid. There are unclosed tags and your xpath doesn't match the structure of the sample either.
Second of all I can only show the equivalent xpath3 expression of your xpath expression as I have already answered how to update an XML node in other questions of yours.
<splitter evaluator="xpath" expression="/babyproducts/products" doc:name="Splitter" />
Becomes:
<splitter expression="#[xpath3('/babyproducts/products/*', payload, 'NODESET')]"
doc:name="Splitter" />
And
#[xpath('/products/validlity').text]
Becomes:
#[xpath3('/products/validlity')]
No need for .text as by default returns the Stirng value. More info here: http://blogs.mulesoft.org/mule-3-6-xml-xpath-xslt-xquery3/

Mule foreach : Splitter returned no results

I get a list of files on amazon S3 and iterate over the list of files and process one file at a time. The corresponding flow is as follows --
<flow name="process-from-s3" doc:name="process-from-s3"
processingStrategy="synchronous">
<poll doc:name="Poll" frequency="${s3-poll-interval}">
<s3:list-objects config-ref="Amazon_S3" doc:name="Get List of files"
accessKey="${s3-access-key}" secretKey="${s3-secret-key}"
bucketName="${s3-read-bucket}" />
</poll>
<choice doc:name="Choice">
<foreach doc:name="For Each">
<set-session-variable variableName="s3_file_name" value="#[payload.getKey()]" doc:name="Session Variable"/>
<logger message="From bucket ( ${s3-read-bucket} ), received the file #[s3_file_name]" level="INFO" doc:name="Logger"/>
<flow-ref name="process_s3_file" doc:name="Flow Reference"/>
</foreach>
</choice>
</flow>
The flow works well, however it keeps on spitting the following log statements if there are no files found.
[03-06 21:52:05] WARN Foreach$CollectionMapSplitter
[[myapp].connector.polling.mule.default.receiver.01]: Splitter returned no results.
If this is not expected, please check your split expression
How can I avoid this annoying log message. Should I wrap the foreach within a choice router that processes the foreach if there is atleast one element in the list. Any suggestions are welcome.
I would rather set the log level for org.mule.routing.Foreach$CollectionMapSplitter to ERROR than configure any additional logic for this warning. See Mule docs for configuring logger/log4j if you need to.