Parsing through multiple child nodes in XML response

Ben Cervantes
Kilo Expert

Hello All, 

Currently we are trying to set up an integration point between BigFix and ServiceNow. We are able to query BigFix's REST API and receive an XML response back. The issue that I am running into is parsing through response. The response is several thousand lines and I need to extract the answer node content for each individual line. Below is an example of what I am receiving back from the API. 

<?xml version="1.0" encoding="UTF-8"?>
<BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BESAPI.xsd">
	<Query>
		<Result>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer>
		</Result>
		<Evaluation>
			<Time>68717.944ms</Time>
			<Plurality>Plural</Plurality>
		</Evaluation>
	</Query>
</BESAPI>

 

With the script shown below I am able to parse the response but not each individual answer node. The counter variable that I have created to keep track of the answers starts at the 3300ish position skipping several items and then after each iteration it skips every other item and returns back blank results. Any help in the right direction is appreciated. Below is the current script that I am running. 

// Execute REST call
try {
    var response = restMessage.execute();
    var responseBody = response.getBody();
    gs.log('This is the BigFix API response code: ' + response.getStatusCode());
    //gs.log('BigFix API response: ' + response.getBody());
    var xmlDoc = new XMLDocument2();
    xmlDoc.parseXML(responseBody);

    // Grab Result Node
    var result = xmlDoc.getNode('//Result');

    // Iterate through the child answer nodes
    var answer = result.getChildNodeIterator();

    var counter = 0;
    while (answer.hasNext()) {
        counter++;
        var node = answer.next();
        
            gs.print('Node name: ' + node.getNodeName());
            gs.print('Node Text Content: ' + node.getTextContent());
            gs.print('Node Value: ' + node);
            gs.print('Node Counter: ' + counter);
        
    }
} catch(error) {
    gs.error(error);
}
1 ACCEPTED SOLUTION

Ben Cervantes
Kilo Expert

I was able to figure out how to parse each individual child node that has the same <answer> tag. Below is the script that I used. 

try {

    var response = restMessage.execute();
    var responseBody = response.getBody();

    var xmlDoc = new XMLDocument(responseBody);
    var answerList = xmlDoc.getNodes('//Result/*').getLength();

    for (var i = 1; i < answerList + 1; i++) {
        var value = xmlDoc.getNodeText('//Answer['+i+']');
        var answer = String(value);

        //gs.print('Individual value for string tag is: ' + answer);
    }
} catch(error) {
    gs.error(error);
}

View solution in original post

4 REPLIES 4

Manish Vinayak1
Tera Guru

Hi Ben,

Have you considered using gs.xmlToJSON() function? It converts the XML string to JSON Object, which is then easy to utilize.

Here is the documentation link :https://developer.servicenow.com/app.do#!/api_doc?v=madrid&id=r_SGSYS-xmlToJSON_S

 

Here is the sample code executed using your sample XML string:

var xmlString = '<?xml version="1.0" encoding="UTF-8"?> <BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BESAPI.xsd"> 	<Query> 		<Result> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 			<Answer type="string">Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User</Answer> 		</Result> 		<Evaluation> 			<Time>68717.944ms</Time> 			<Plurality>Plural</Plurality> 		</Evaluation> 	</Query> </BESAPI>';

var jsonObject = gs.xmlToJSON(xmlString);
gs.print(JSON.stringify(jsonObject));

var answerArr = jsonObject["BESAPI"]["Query"]["Result"]["Answer"];

for(var i = 0; i < answerArr.length; i ++) {

gs.print(answerArr[i].content);
}

 

Here is the result:

*** Script: {"BESAPI":{"Query":{"Evaluation":{"Plurality":"Plural","Time":"68717.944ms"},"Result":{"Answer":[{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"},{"type":"string","content":"Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User"}]}},"xsi:noNamespaceSchemaLocation":"BESAPI.xsd","xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"}}

*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User
*** Script: Computer Name$OS Fingerprint$Manufacturer$Model$Computer Type$Physical or Virtual$Last logged in User

 

Hope this helps!

Cheers,

Manish

Hello Manish, 

Thank you for replying, I have tried gs.xmlToJSON(). However, the issue is that the XML response is several thousand lines and the background script will not process the conversion. 

 

Hi Ben,

Oh okay. Well, the logic should remain same, whether you try from background script or any server side script.

Maybe I am unable to understand the problem here. Do you mean that this logic, i.e., gs.xmlToJSON() doesn't work when there are thousands of lines in the XML?

Thanks,

Manish

Ben Cervantes
Kilo Expert

I was able to figure out how to parse each individual child node that has the same <answer> tag. Below is the script that I used. 

try {

    var response = restMessage.execute();
    var responseBody = response.getBody();

    var xmlDoc = new XMLDocument(responseBody);
    var answerList = xmlDoc.getNodes('//Result/*').getLength();

    for (var i = 1; i < answerList + 1; i++) {
        var value = xmlDoc.getNodeText('//Answer['+i+']');
        var answer = String(value);

        //gs.print('Individual value for string tag is: ' + answer);
    }
} catch(error) {
    gs.error(error);
}