Handling XML response with or without namespace in Postman

 While testing an XML response in postman, we need to convert XML data to JSON in order to traverse child nodes of an XML document. XML documents can be with/without namespaces. If XML documents have namespaces, then those are declared as attributes to the XML tag. There may or may not be prefixes associated with XML tags containing namespaces. There are different methods or ways to convert XML to JSON, a few of which are described in this blog.

  1. XML to JSON without namespaces -- using xml2Json
  2. XML to JSON with namespaces -- using xml2js

Postman version: 8.0.7
Libraries: xml2Json, xml2js

XML to JSON without namespaces

Let's assume we are getting the below XML response from Webservice.
<ROOT>
<Account>
<name>Name1</name>
<id>123123</id>
<address>
<street>Street1</street>
<city>City1</city>
<state>State1</state>
<Country>Country1</Country>
</address>
</Account>
<Account>
<name>Name2</name>
<id>124234</id>
<address>
<street>Street2</street>
<city>City</city>
<state>State1</state>
<Country>Country1</Country>
</address>
</Account>
</ROOT>
To convert this XML payload without namespaces, we can use the below code snippet in Postman.

Code:
const responseJson = xml2Json(pm.response.text());//fetch xml data in text/string
console.log(JSON.stringify(responseJson));//logging to postman console

The JSON converted data will be logged in the Postman console as below:

Pretty print:

If we want to log the value of city under the address element of second Account.

const responseJson = xml2Json(pm.response.text());//fetch xml data in text
const city=responseJson.ROOT.Account[1].address.city;//fetch the desired city value
console.log(city);//logging to postman console

Postman console will log the value as "City2".

In the above example, XML tag does not contain any namespaces. What if XML elements have namespaces and have different namespaces at each level of hierarchy. The next section gives various tips and tricks that can be used to tackle such scenarios. 

XML to JSON with namespaces

Let's take another example of XML response which contains namespaces and prefixes.

<tns:ROOT tns:xmlns="http://samplenamespace.com/v1/target">
<tns:Account acc:xmlns="http://samplenamespace.com/v1/target/account">
<acc:name>Name1</acc:name>
<acc:id>123123</acc:id>
<acc:address add:xmlns="http://samplenamespace.com/v1/target/account/address">
<add:street>Street1</add:street>
<add:city>City1</add:city>
<add:state>State1</add:state>
<add:Country>Country1</add:Country>
</acc:address>
</tns:Account>
<tns:Account acc:xmlns="http://samplenamespace.com/v1/target/account">
<acc:name>Name2</acc:name>
<acc:id>124234</acc:id>
<acc:address add:xmlns="http://samplenamespace.com/v1/target/account/address">
<add:street>Street2</add:street>
<add:city>City2</add:city>
<add:state>State2</add:state>
<add:Country>Country2</add:Country>
</acc:address>
</tns:Account>
</tns:ROOT>

If we use the same snippet as used in previous example i.e.

const responseJson = xml2Json(pm.response.text());//fetch xml data in text/string
console.log(JSON.stringify(responseJson));//logging to postman console

Then output from console will look like.
 Pretty print

In this case, logging the value of city under the address element of the second Account becomes difficult as now the prefix is added and the key has ":" character which results in an invalid Js/JSON reference as below.

#1 One way to reach the particular value is:

const responseJson = xml2Json(pm.response.text());//fetch xml data in text/string
const city=responseJson["tns:ROOT"]["tns:Account"][1]["acc:address"]["add:city"];
console.log(city);

In the above case, we have to explicitly define the key to extract data for each element/node, which will not be easy in most cases. As there can be a possibility, prefix changes wherein instead of tns, ns1 comes, etc. Then above logic will correspond to an invalid object.

Another approach is to convert the XML with namespaces to a form where there are no namespaces. The output of XML response as if there are no namespaces involved. For example:



#2 For this, we will be using the "xml2js" library in Postman.

Sample code snippet:

const respBodyXML = pm.response.text();
const parseString = require('xml2js').parseString;
const stripPrefix = require('xml2js').processors.stripPrefix;
parseString(respBodyXML, {
tagNameProcessors: [stripPrefix], //removing prefix
ignoreAttrs: true, //ignoring all attributes including xmlns
explicitArray: false,
explicitRoot: true//including root tag inside the JSON
}, function (err, result) {
console.log(JSON.stringify(result));
});

Console Output:

{"ROOT":{"Account":[{"name":"Name1","id":"123123","address":{"street":"Street1","city":"City1","state":"State1","Country":"Country1"}},{"name":"Name2","id":"124234","address":{"street":"Street2","city":"City2","state":"State2","Country":"Country2"}}]}}

These are some of the ways by which we can handle XML requests inside Postman.

Please share your valuable feedback in the comments below! 😊



Comments

Popular posts from this blog

DateTime formatting using xp20:format-dateTime ()

Create Delimited String from XML Nodes and Vice Versa in SOA 12c