I am facing one issue while xml format conversion in mule transform message.
I am having one input xml file.
and I have to convert the input xml to output xml where the node structure is different and node names are different.
I used data transform message for this conversion, But at one point, it is showing expected format is object and found string.
Can any one please help me for the same.
"Type mismatch
found :name, :string
required :name, :object (com.mulesoft.weave.mule.exception.WeaveExecutionException). Message payload is of type: WeaveMessageProcessor$WeaveOutputHandler"
input payload
<?xml version="1.0" encoding="utf-8"?>
<AGREEMENT>
<details>
<newTransaction>N</newTransaction>
<type>ddd</type>
</details>
</AGREEMENT>
output Payload
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<TestHeader xmlns="TestWebService">
<Username>aaa</Username>
<Password>aaa</Password>
</TestHeader>
</soap:Header>
<soap:Body>
<AGRMNT>
<testId>
<_-Test_Agrmnt- SEGMENT="1">
<transaction>N</transaction>
</__-Test_Agrmnt->
</testId>
</AGRMNT>
</soap:Body>
</soap:Envelope>
DataWeave code
%dw 1.0
%output application/xml
%namespace soap http://schemas.xmlsoap.org/soap/envelope/
{
soap#Envelope: {
soap#Body: {
AGREEMENT: {
testId: {
'_-Test_Agrmnt-': {
transaction: payload.AGREEMENT.details.newTransaction as :string
}
}
}
}}
I have got following output with your input and script
<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AGREEMENT>
<testId>
<_-Test_Agrmnt->
<transaction>N</transaction>
</_-Test_Agrmnt->
</testId>
</AGREEMENT>
</soap:Body>
</soap:Envelope>
The only change is adding --- in script
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace soap http://schemas.xmlsoap.org/soap/envelope/
---
{
soap#Envelope: {
soap#Body: {
AGREEMENT: {
testId: {
'_-Test_Agrmnt-': {
transaction: payload.AGREEMENT.details.newTransaction as :string
}
}
}
}}}]]>
</dw:set-payload>
</dw:transform-message>
Related
I am trying to set the payload with a soap envelope, header, and body.
then substring payload by payload.indexOf("?>")+2
Based on the following expression:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://decisionresearch.com/RateMaker">
<soapenv:Header/>
<soapenv:Body>
#[payload.substring(payload.indexOf("?>")+2)]
</soapenv:Body>
</soapenv:Envelope>
Input Request: https://github.com/Manikandan99/Map_request/blob/main/Request_map.xml
Expected output: https://github.com/Manikandan99/Map_request/blob/main/Response_map.xml
Mule FLow:
<flow name="map_requestFlow" doc:id="21d0d652-3766-47ed-95aa-a451f62c5776" >
<http:listener doc:name="Listener" doc:id="7312114b-2857-40b3-98cd-f52b628b3a28" config-ref="HTTP_Listener_config" path="/map"/>
<ee:transform doc:name="Transform Message" doc:id="7f061325-473b-4f63-8e95-990827b03259" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/xml
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" doc:name="Logger" doc:id="21051f39-bb9f-412c-af73-f65051317757" message="#[payload]"/>
<set-payload value='#[<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://decisionresearch.com/RateMaker">
<soapenv:Header/>
<soapenv:Body>
#[payload.substring(payload.indexOf("?>")+2)]
</soapenv:Body>
</soapenv:Envelope>]' doc:name="Set Payload" doc:id="faf2bc3b-e7a3-4708-910b-daeb05bb5f6e" />
</flow>
Error message : https://github.com/Manikandan99/Map_request/blob/main/Error.txt
How to encapsulate soap with current payload?
That's wrong because of several reasons. First you can not use an expression inside an expression. Second you are trying to generate XML with strings, when DataWeave already does generates valid XML. Using strings directly is very very error prone. Whenever you see string manipulation to generate or parse XML, you should be questioning the reason.
Instead use DataWeave to generate the XML completely in a simple transform:
%dw 2.0
output application/xml
ns soapenv http://schemas.xmlsoap.org/soap/envelope/
---
{
soapenv#Envelop: {
soapenv#Header: null,
soapenv#Body: payload
}
}
Output (assuming the input has format application/xml):
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelop xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns0:rate xmlns:ns0="http://decisionresearch.com/RateMaker">
<ns0:BrokerData>
<ns0:taxa>TOPA/CISG01/ALL</ns0:taxa>
<ns0:effectiveMode>effective</ns0:effectiveMode>
<ns0:requestDate>20190101</ns0:requestDate>
<ns0:function>rate</ns0:function>
</ns0:BrokerData>
<ns0:RateRequest>
<ns0:Policy>
<PolType>CNPK</PolType>
<ClassCode>CANDIS</ClassCode>
<Zip>80003</Zip>
<State>CO</State>
<EffDate>20211117</EffDate>
<ExpDate>20221117</ExpDate>
<Payroll>1200</Payroll>
<OHPayroll/>
<WAPayroll/>
<FTE>5</FTE>
<OccAgg>1000000/2000000</OccAgg>
<DmgPrem>500000</DmgPrem>
<MedPay>10000</MedPay>
<EmpBen>Yes</EmpBen>
<StopGap>None</StopGap>
<OHStopGap>None</OHStopGap>
<WAStopGap>None</WAStopGap>
<HNO>1000000</HNO>
<AssBat>100000/200000</AssBat>
<PerLocAgg>Yes</PerLocAgg>
<NumLoc>1</NumLoc>
<WSUB>0</WSUB>
<PICO>No</PICO>
<AIML>0</AIML>
<AIVS>0</AIVS>
<AIPA>0</AIPA>
<AIMA>0</AIMA>
<AILL>0</AILL>
<LLEA>0</LLEA>
<AIDP>0</AIDP>
<BAIV>No</BAIV>
<WACombo>No</WACombo>
<IRPMGL>2</IRPMGL>
<LPDPGL>1.00</LPDPGL>
</ns0:Policy>
<ns0:Location>
<LocationRef>Location-465697646-800339871</LocationRef>
<State>CO</State>
<Zip>80003</Zip>
</ns0:Location>
<ns0:Class>
<Id>Risk-1296379588-1802098261</Id>
<Number>1</Number>
<ClassCode>CANDIS</ClassCode>
<Exposure>2000000</Exposure>
<GLBR>25</GLBR>
<IsPrimary>Yes</IsPrimary>
</ns0:Class>
</ns0:RateRequest>
</ns0:rate>
</soapenv:Body>
</soapenv:Envelop>
Please find my request having tag <Date xsi:nil="true"/> when it crosses the Multipart/form-data dataweave it is removing the xsi:nil="true part which is not expected in my scenario. I wanted that to be out as the same.
Also it is removing the namespace which is not the expected case. If i trying declaring ns xsi http://www.w3.org/2001/XMLSchema-instance in the first dataweave. In the response root element it is prefixing xsi:Locations.
Im struggling with this.
Wanted the response as mentioned below, whatever the input is same should come out without altering.
Using writeNilOnNull=true is putting nill on all the fields which i dont want either, wanted only for date.
Could anyone help on this. Thank you.
Input:
<Locations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Location>
<Id>2</Id>
<CarId>78</CarId>
<Packages>1</Packages>
<Date xsi:nil="true"/>
</Location>
</Locations>
Expected Response:
<Locations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Location>
<Id>2</Id>
<CarId>78</CarId>
<Packages/>
<Date xsi:nil="true"/>
</Location>
</Locations>
Flow:
<flow name="question" doc:id="8c836a85-9d0a-47a8-8e5a-f670b16f91eb" >
<http:listener doc:name="Listener" doc:id="52ffdb08-9587-4cb2-8232-9467e85ea0dc" config-ref="HTTP_Listener_config" path="/question"/>
<ee:transform doc:name="Transform Message" doc:id="da995adf-196b-4c7b-a265-874f059ed1bb" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/xml
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="75e5d876-855e-4d38-8468-3484c859f36e" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output multipart/form-data
---
{
"parts": {
"file": {
"headers": {
"Content-Disposition": {
"name": "file",
"filename": "",
"subtype": "form-data"
},
"Content-Type": "application/xml"
},
"content": payload
}
}
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
Add writeNilOnNull=true on your transformation. Like this
%dw 2.0
var x=read('<Locations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Location>
<Id>2</Id>
<CarId>78</CarId>
<Packages>1</Packages>
<Date xsi:nil="true"/>
</Location>
</Locations>','application/xml')
output application/xml writeNilOnNull=true
---
x
I already read the documentation about the new way to create soap web service using newest mule (https://docs.mulesoft.com/apikit/4.x/apikit-4-soap-prerequisites-task), but it doesn't really help.
Because I try to do following, using that tutorial as example, when user enter the name, the size, the email and send the request in OrderTshirt function, my flow will call method in a java class, probably int OrderTShirt.order(String input) where input concat all the name, size, and email information, and return back the orderId, and submit back to the response to user. How I can approach this?
Here is the code that what I have right now, but I don't know how to use that datawave component really well, can someone give me an example for that?
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:apikit-soap="http://www.mulesoft.org/schema/mule/apikit-soap" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/apikit-soap http://www.mulesoft.org/schema/mule/apikit-soap/current/mule-apikit-soap.xsd http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:listener-config name="api-httpListenerConfig">
<http:listener-connection host="0.0.0.0" port="9999"/>
</http:listener-config>
<apikit-soap:config name="soapkit-config" port="TshirtServicePort" service="TshirtService" wsdlLocation="Tshirt2.wsdl"/>
<flow name="api-main">
<http:listener config-ref="api-httpListenerConfig" path="/TshirtService/TshirtServicePort">
<http:response>
<http:body>#[payload]</http:body>
<http:headers>#[attributes.protocolHeaders default {}]</http:headers>
</http:response>
<http:error-response>
<http:body>#[payload]</http:body>
<http:headers>#[attributes.protocolHeaders default {}]</http:headers>
</http:error-response>
</http:listener>
<apikit-soap:router config-ref="soapkit-config">
<apikit-soap:message>#[payload]</apikit-soap:message>
<apikit-soap:attributes>#[
%dw 2.0
output application/java
---
{
headers: attributes.headers,
method: attributes.method,
queryString: attributes.queryString
}]</apikit-soap:attributes>
</apikit-soap:router>
</flow>
<flow name="OrderTshirt:\soapkit-config" doc:id="969489c2-709c-43b7-915c-cc92d9f3c8c9">
<ee:transform doc:name="Transform Message" doc:id="5771f4b9-0060-4658-aa8a-fee10efc02c5" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
ns ns0 http://schemas.xmlsoap.org/soap/envelope
---
{
body:{
ns0#orderTshirtResponse:{
orderId:"10"
}
} write "application/xml"
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
<flow name="ListInventory:\soapkit-config">
<ee:transform doc:id="431ad9c7-f0bf-4b32-88bc-bbe8c6815317">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
ns soap http://schemas.xmlsoap.org/soap/envelope
---
{
body: {
soap#Fault: {
faultcode: "soap:Server",
faultstring: "Operation [ListInventory:\soapkit-config] not implemented"
}
} write "application/xml"
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
<flow name="TrackOrder:\soapkit-config">
<ee:transform doc:id="a09a0cc3-f28a-49aa-bb32-77368340a522">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
ns soap http://schemas.xmlsoap.org/soap/envelope
---
{
body: {
soap#Fault: {
faultcode: "soap:Server",
faultstring: "Operation [TrackOrder:\soapkit-config] not implemented"
}
} write "application/xml"
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
I'm trying to embed a literal CDATA value in a Mulesoft flow and cannot figure out how to do so.
My desired output (in an HTTP request body) is:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<query xmlns="http://autotask.net/ATWS/v1_5/">
<sXML>
<![CDATA[<queryxml><entity>ticket</entity><query><condition><field>id<expression op="equals">12345</expression></field></condition></query></queryxml>]]>
</sXML>
</query>
</soap:Body>
</soap:Envelope>
My Dataweave transformation looks as follows:
%dw 1.0
%output application/xml
%namespace soap http://schemas.xmlsoap.org/soap/envelope
---
{
soap#Envelope #(version: "1.0") : {
soap#Header: {},
soap#Body: {
query: {
sXML: "<queryxml><entity>ticket</entity><query><condition><field>id<expression op=\"equals\">12345</expression></field></condition></query></queryxml>"
}
}
}
}
But when I send this request to requestb.in (to inspect the contents), I can see it's coming through like this (focus on the sXML entity):
<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" version="1.0">
<soap:Header/>
<soap:Body>
<query>
<sXML><queryxml><entity>ticket</entity><query><condition><field>id<expression op="equals">12345</expression></field></condition></query></queryxml></sXML>
</query>
</soap:Body>
</soap:Envelope>
How can I get a literal CDATA value in there via dataweave / MEL?
Thank you.
I would try:
sXML: "<queryxml> .... </queryxml>" as :cdata
See https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-formats#custom-types-2 for more information.
handleInteractiveOrder:
write(vars.subm.soap#Envelope.soap#Body.cp#handleInteractiveOrder,"application/xml")
as CData
in mule 4 we can do like this. I kept my XML in subm variable.
I have used to do create XML using "Transform Message" Node in Mule ESB.
%dw 1.0
%output application/xml
item: {
name: payload."profile_name",
id: payload."profile_Id"
}
This shown a preview of output xml as
<?xml version='1.0' encoding='windows-1252'?>
<item>
<name>
<profile_name>????</profile_name>
</name>
<id>
<profile_Id>1</profile_Id>
</id>
</item>
This resulted encoding as 'windows-1252' how can i change encoding as 'UTF-8' in my outpout xml ?
Go to your Anypoint Studio folder.
Edit AnypointStudio.ini
Add:
-Dfile.encoding=UTF-8
Restart
Easy, define encoding in the output line:
%dw 1.0
%output application/xml encoding="utf-8"
---
name: payload.name?
the result:
<?xml version='1.0' encoding='utf-8'?>
<name>false</name>
For dataweave in runtime above 3.8.4 I implemented this solution:
set output as variable:
Output FlowVar - fv_itemName_xml
inside of Transform Message:
'%output application/xml writeDeclaration=false
item: { name: payload."profile_name", id: payload."profile_Id" }
and output will be:
<item>
<name>
<profile_name>????</profile_name>
</name>
<id>
<profile_Id>1</profile_Id>
</id>
</item>
Then define a variable as below:
Name: fv_outputName_xml
Value: #[flowVars.fv_itemName_xml]
Encoding: ISO 10646/Unicode(UTF-8)
Mime type: application/xml
And you have better control of Encoding and Mime type.
In my case I was need to feed that into Stored Procedure and without this workarround constantly receiving error:
System.Data.SqlClient.SqlException (0x80131904): XML parsing: line 1,
character 39, unable to switch the encoding