How to retrieve the names of xml tags

Hi All,
After a GET Request is sent, the response is in XML format. Which I am able to convert it into JSON format using :

let jResponse =xml2Json(responseBody);

However I want to only capture all the tagnames present in the xml to ensure that all intended xml tags are correctly shown. That is traverse through all the xml tags and capture the tagname in an array/csv file.

I am not sure how to proceed… your assistance would be of great help.

Sample XML Response:
<p:HighLevelSummaryDetails>
<p:MRN>1234566</p:MRN>
<p:LRN>ABD-38U-9JR</p:LRN>
<p:PartID>2690U01</p:DUCRandPartID>
<p:VersionID>1</p:VersionID>
<p:GoodsLocationCode>RMGRMGRMGGVM</p:GoodsLocationCode>
<p:CreatedDateTime>
<p:DateTimeString formatCode=“304”>20231030160405Z</p:DateTimeString>
</p:CreatedDateTime>
<p:AcceptanceDateTime>
<p:DateTimeString formatCode=“304”>20231030160404Z</p:DateTimeString>
</p:AcceptanceDateTime>
<p:P2PDateTime>
<p:DateTimeString formatCode=“304”>20231030160407Z</p:DateTimeString>
</p:P2PDateTime>
<p:FinalisedDateTime>
<p:DateTimeString formatCode=“304”>20231030163908Z</p:DateTimeString>
</p:FinalisedDateTime>
</p:HighLevelSummaryDetails>
<p:GeneratedDetails>
<p:ROE>89</p:ROE>
<p:Reference>3456789012-2690U02</p:Reference>
<p:StatusOfEntry-ICS>22</p:StatusOfEntry-ICS>

Let’s use a cut down version of your sample response and use the pre-formatted text option in the editor so its shows correctly.

<p:HighLevelSummaryDetails>
    <p:MRN>1234566</p:MRN>
    <p:LRN>ABD-38U-9JR</p:LRN>
    <p:VersionID>1</p:VersionID>
    <p:CreatedDateTime>
        <p:DateTimeString formatCode="304">20231030160405Z</p:DateTimeString>
    </p:CreatedDateTime>
</p:HighLevelSummaryDetails>

You can see from the example that you have elements within elements.

Therefore, do you want a list of all of the elements or just the sub elements within the HighLevelSummaryDetails?

When you convert the above to a JavaScript Object using xml2Json, it will return the following structure.

image

The elements are turned into key\value pairs.

As its not a flat list of elements, you will need some sort of function to recurse through the object to return all of the keys.

javascript - How to recursively map/restructure an object? - Stack Overflow

I’ve just picked one of the solutions from there as an example.

function getAllKeys(obj){
  var keys = (typeof obj === "object") && (obj !== null) && Object.keys(obj);
  return !!keys ? keys.reduce((r,k) => r.concat(getAllKeys(obj[k])),keys)
                : [];
};

This will return a flat array of the keys.

image

The following is a decent article that you might want to look through.

Handling XML response with or without namespace in Postman (deciphermiddleware.in)

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));
});

It returns a cleaner object that might be easier to work with.

{"HighLevelSummaryDetails":{"MRN":"1234566","LRN":"ABD-38U-9JR","VersionID":"1","CreatedDateTime":{"DateTimeString":"20231030160405Z"}}}
1 Like

Thanks Mike for sharing the options for converting to JSON.

How do we convert multiple tags on the xml response to JSON file?

<Reasons>
							<Reason code="CLEAR"
							        description="STATUS"/>
							<Reason code="00000"
							        description="RULE MATCH COUNT"/>
							<Reason code="00000"
							        description="ENQUIRY MATCH COUNT"/>
							<Reason code="00000"
							        description="TOTAL RULE SCORE"/>
</Reasons>

Here my xml element Reason have two other sub tags as “Code” and “Description”. When I use your suggestion above, I am getting the below response.

"Reasons": {
								"Reason": [
									true,
									true,
									true,
									true
								]
}

They don’t seem to return the correct elements for me.

@Kaliswaran_N

I did put your example response through an online XML validator and it didn’t find any errors, but I’ve never seen XML like that before.

You have a reason element with code and description attributes.
Which look like they ought to be elements of their own with proper text nodes.

If you use the xml2js method, just comment out the ignore attributes line.

let respBodyXML = pm.response.text();
let parseString = require('xml2js').parseString;
let 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(result);
});

This produces exactly the same format as the xml2Json method.

const response = pm.response.text();
let responseJson = xml2Json(response);
console.log(responseJson);

image

If you modify the xml2js method slightly to merge the attributes, then it will remove the attribute keys. (The dollar signs).

Have a look here for the xml2js options.

xml2js - npm (npmjs.com)

Based on your example response, the following appears to be the best fit.

let respBodyXML = pm.response.text();
let parseString = require('xml2js').parseString;

parseString(respBodyXML, {
    mergeAttrs: true,
    explicitArray: false
}, function (err, result) {
    console.log(result);
});

Which returns the following.

image

1 Like

Thank you so much Mike for your help,I tried the suggestion and it worked.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.