Playing with XML Namespaces in Mule 4 Dataweave
Today, the world is full of REST APIs which use JSON as a major message type. But we have a lot of applications and APIs in the middleware world which rely on XML message structures. XML messages are a bit more complex than JSON messages, as in XML messages namespaces play a vital role. A miss in the namespace can lead to errors that are sometimes unseen to normal eyes. In this blog, we will discuss various ways by which we can handle the transformation of XML messages with or without namespaces in Mule 4 using Dataweave.
1. Transforming XML messages without namespaces
This conversion is pretty simple, all we need to consider is XPath and do the mapping accordingly. This is similar to the JSON data transformation Let's take an example of 2 XMLs, wherein both input and output XMLs don't have namespaces. The output we need to specify is application/xml.
INPUT:
<contact>
<firstName>Test</firstName>
<lastName>Data</lastName>
<address>
<street1>Street1</street1>
<street2>Street2</street2>
<city>City</city>
<state>State</state>
<country>Country</country>
</address>
</contact>
</InputRoot>
Suppose we want to extract the value of country from the above XML message. All we need to do is traverse to the node as we do in the case of JSON transformations i.e. (Assuming data is in the payload variable) payload.InputRoot.contact.address.country . Below is the dataweave file for the transformation transforming the data to a different XML format.
DATAWEAVE:
output application/xml
---
OutputRoot:{
Contact:{
Name: payload.InputRoot.contact.firstName ++ payload.InputRoot.contact.lastName,
Address :{
Street: payload.InputRoot.contact.address.street1 ++ payload.InputRoot.contact.address.street2 ,
City: payload.InputRoot.contact.address.city,
State:payload.InputRoot.contact.address.state
}
}
}
OUTPUT:
<Contact>
<Name>TestData</Name>
<Address>
<Street>Street1Street2</Street>
<City>City</City>
<State>State</State>
</Address>
</Contact>
</OutputRoot>
Above is the output for the dataweave file.
2. Transforming XML messages with namespaces.
<acc:name xmlns:acc="http://deciphermiddleware.in/ns/account"> or
<cont:name xmlns:cont="http://deciphermiddleware.in/ns/contact">.
Let's take the below example:
INPUT:
<cont:contact xmlns:cont="http://deciphermiddleware.in/ns/sample/contact">
<cont:firstName>Test</cont:firstName>
<cont:lastName>Data</cont:lastName>
<cont:address xmlns:add="http://deciphermiddleware.in/ns/sample/address">
<add:street1>Street1</add:street1>
<add:street2>Street2</add:street2>
<add:city>City</add:city>
<add:state>State</add:state>
<add:country>Country</add:country>
</cont:address>
</cont:contact>
</InputRoot>
Now, in the above case, we have multiple namespaces. To deal with such scenarios we need to declare namespaces in the Dataweave file.
%dw 2.0
output application/xml
ns ns0 http://deciphermiddleware.in/ns/sample/data
In dataweave, an element with namespace will be denoted by ns#Element (ns denotes namespace prefix as declared, Element is the name of node or element of XML and, # acts as separator)
Suppose we need to extract data of the country, now dataweave expression for the same will be "payload.ns0#InputRoot.cont#contact.cont#address.add#country"
Combining the above parameters, below is a sample dataweave file that will output the XML message generated from the above sample input XML, having different namespaces.
DATAWEAVE:
output application/xml
ns ns0 http://deciphermiddleware.in/ns/sample/data
ns cont http://deciphermiddleware.in/ns/sample/contact
ns add http://deciphermiddleware.in/ns/sample/address
ns ns1 http://deciphermiddleware.in/ns/sample/data1
ns cont1 http://deciphermiddleware.in/ns/sample/contact1
ns add1 http://deciphermiddleware.in/ns/sample/address1
---
ns1#OutputRoot:{
cont1#Contact:{
cont1#Name: payload.ns0#InputRoot.cont#contact.cont#firstName ++ payload.ns0#InputRoot.cont#contact.cont#lastName,
add1#Address :{
add1#Street: payload.ns0#InputRoot.cont#contact.cont#address.add#street1 ++ payload.ns0#InputRoot.cont#contact.cont#address.add#street2 ,
add1#City: payload.ns0#InputRoot.cont#contact.cont#address.add#city,
add1#State:payload.ns0#InputRoot.cont#contact.cont#address.add#state,
add1#Country:payload.ns0#InputRoot.cont#contact.cont#address.add#country
}
}
}
Below is the output for the above dataweave.
OUTPUT:
<cont1:Contact xmlns:cont1="http://deciphermiddleware.in/ns/sample/contact1">
<cont1:Name>TestData</cont1:Name>
<add1:Address xmlns:add1="http://deciphermiddleware.in/ns/sample/address1">
<add1:Street>Street1Street2</add1:Street>
<add1:City>City</add1:City>
<add1:State>State</add1:State>
<add1:Country>Country</add1:Country>
</add1:Address>
</cont1:Contact>
</ns1:OutputRoot>
References:
1. https://docs.mulesoft.com/dataweave/2.3/dataweave-cookbook-include-xml-namespaces
Please share your valuable feedback 😊😊😊
Comments
Post a Comment