Need help parsing a REST API XML response and loading an import set with the result

edwardhum
Kilo Contributor

Hi Folks,

I created an outbound rest message to get a list of computers and what to build an import set to load the computers into CMDB.  I can execute the REST call and get the response, the and i've been able to parse the date and get the details i need.  I'm just at loss on how to loop through and create entries in my import set.

sample XML response

<?xml version="1.0" encoding="UTF-8"?>
<computers>
    <size>622</size>
    <computer>
        <id>10</id>
        <name>computer1</name>
        <managed>true</managed>
        <username/>
        <model>MacBookAir7,2</model>
        <department>dept1</department>
        <building>building1</building>
        <mac_address>mac1</mac_address>
        <udid>udid1</udid>
        <serial_number>SERIAL1</serial_number>
        <report_date_utc>2019-06-11T15:29:17.642+0000</report_date_utc>
        <report_date_epoch>1560266957642</report_date_epoch>
    </computer>
    <computer>
        <id>12</id>
        <name>computer2</name>
        <managed>true</managed>
        <username/>
        <model>MacBookAir7,2</model>
        <department>dept1</department>
        <building>building1</building>
        <mac_address>mac2</mac_address>
        <udid>udid2</udid>
        <serial_number>SERIAL2</serial_number>
        <report_date_utc>2019-06-11T22:40:26.702+0000</report_date_utc>
        <report_date_epoch>1560292826702</report_date_epoch>
    </computer>
    <computer>
        <id>19</id>
        <name>computer3</name>
        <managed>true</managed>.............

 

My script so far.. (in a business rule for testing).  I'd like to move this to a scheduled job.

(function executeRule(current, previous /*null when async*/) {


 var r = new sn_ws.RESTMessageV2('DeviceIntegration', 'get');

//override authentication profile 
//authentication type ='basic'/ 'oauth2'
//r.setAuthenticationProfile(authentication type, profile name);

//set a MID server name if one wants to run the message on MID
//r.setMIDServer('MY_MID_SERVER');

//if the message is configured to communicate through ECC queue, either
//by setting a MID server or calling executeAsync, one needs to set skip_sensor
//to true. Otherwise, one may get an intermittent error that the response body is null
//r.setEccParameter('skip_sensor', true);

	var response = r.execute();
	var responseBody = response.getBody();
	var httpStatus = response.getStatusCode();

	//var jsonString = response.getBody();
	//var parser = new JSONParser();
	//var obj = parser.parse(jsonString);
	//current.description = responseBody;
	var xmlString = response.getBody();
	var xmldoc = new XMLDocument(xmlString,true);
	var r_id = xmldoc.getNodeText("//id");
	var r_name = xmldoc.getNodeText("//name");
	var r_managed = xmldoc.getNodeText("//managed");
	var r_username = xmldoc.getNodeText("//username");
	var r_model = xmldoc.getNodeText("//model");
	var r_department = xmldoc.getNodeText("//department");
	var r_building = xmldoc.getNodeText("//building");
	var r_mac_address = xmldoc.getNodeText("//mac_address");
	var r_udid = xmldoc.getNodeText("//udid");
	var r_serial_number = xmldoc.getNodeText("//serial_number");
	var r_report_date_utc = xmldoc.getNodeText("//report_date_utc");
	var r_report_date_epoch = xmldoc.getNodeText("//report_date_epoch");
	//current.description = r_serial_number;

})(current, previous);

Thanks in advance!

Edward

1 ACCEPTED SOLUTION

something like below

(function executeRule(current, previous /*null when async*/) {
	var r = new sn_ws.RESTMessageV2('DeviceIntegration', 'get');
	var response = r.execute();
	var responseBody = response.getBody();
	var httpStatus = response.getStatusCode();

	var crImpSet = new GlideRecord('sys_import_set');
	crImpSet.initialize();
	crImpSet.mode = 'synchronous';
	crImpSet.table_name = 'u_device_computers'; //Set the extended importset table
	crImpSet.state = 'loading';
	var ImpSetId = crImpSet.insert();
	var xmlString = response.getBody();
	var req=gs.xmlToJSON(xmlString);
	var jsonString = JSON.stringify(req);

	for(var i=0;i<req.computers.computer.length;i++){
		var imp = new GlideRecord('u_device_computers');
		imp.initialize();
		imp.u_id = req.computers.computer[i].id;
		imp.u_name = req.computers.computer[i].name;
		imp.sys_import_set = ImpSetId;
		imp.insert();
	}

})(current, previous);

View solution in original post

8 REPLIES 8

something like below

(function executeRule(current, previous /*null when async*/) {
	var r = new sn_ws.RESTMessageV2('DeviceIntegration', 'get');
	var response = r.execute();
	var responseBody = response.getBody();
	var httpStatus = response.getStatusCode();

	var crImpSet = new GlideRecord('sys_import_set');
	crImpSet.initialize();
	crImpSet.mode = 'synchronous';
	crImpSet.table_name = 'u_device_computers'; //Set the extended importset table
	crImpSet.state = 'loading';
	var ImpSetId = crImpSet.insert();
	var xmlString = response.getBody();
	var req=gs.xmlToJSON(xmlString);
	var jsonString = JSON.stringify(req);

	for(var i=0;i<req.computers.computer.length;i++){
		var imp = new GlideRecord('u_device_computers');
		imp.initialize();
		imp.u_id = req.computers.computer[i].id;
		imp.u_name = req.computers.computer[i].name;
		imp.sys_import_set = ImpSetId;
		imp.insert();
	}

})(current, previous);

Hi, I am not able to get the length, Does it works in scoped application as well?

 

Mike Patel
Tera Sage

I ran below and it gives me correct result so try below. make sure to replace payload 

var str= '<computers><size>622</size><computer><id>10</id><name>computer1</name></computer><computer><id>12</id><name>computer2</name></computer></computers>';

var req=gs.xmlToJSON(str);
var jsonString = JSON.stringify(req);

for(var i=0;i<req.computers.computer.length;i++){
	var id =req.computers.computer[i].id;
	var name = req.computers.computer[i].name;
	gs.print(id+','+name);
}

edwardhum
Kilo Contributor

that did the trick!  thanks!