How to get child child node details from xml using XMLDocument() in servicenow?

Kotaiah
Kilo Guru

Hi,

I have one integration called scripted soap web services - which going to insert or update configuration item records in cmdb table.

Values on the configuration item record will be updated based on xml payload. All values are updating properly expect IP_Address values.

XML Payload:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<CMDB>
<CIS>
<CI>
<CI_ID>AST000003591160</CI_ID>
<CLASS>BMC_COMPUTERSYSTEM</CLASS>
<CI_NAME>ANDSESP03</CI_NAME>

<IP_Addresses>
<IP_Address>10.232.3.200</IP_Address>
<IP_Address>10.232.3.75</IP_Address>
<IP_Address>10.38.224.17</IP_Address>
<IP_Address>10.38.224.15</IP_Address>
<IP_Address>10.232.3.72</IP_Address>
</IP_Addresses>


<DOMAIN />
<PATCH_NUMBER />
<PORT_PER_SLOT />
<NUMBER_OF_SLOTS />
<USERS_AFFECTED />
<SUBNET_MASK />
</CI>

<CI><CI_ID>AST000003396384</CI_ID>

<CLASS>BMC_COMPUTERSYSTEM</CLASS>

<CI_NAME>SNOWTEST2.JOHNH</CI_NAME>

<IP_Addresses>
<IP_Address>10.232.3.201</IP_Address>
<IP_Address>10.232.3.76</IP_Address>
<IP_Address>10.38.224.18</IP_Address>
<IP_Address>10.38.224.19</IP_Address>
<IP_Address>10.232.3.74</IP_Address>
</IP_Addresses>


<DOMAIN />
<PATCH_NUMBER />
<PORT_PER_SLOT />
<NUMBER_OF_SLOTS />
<USERS_AFFECTED />
<SUBNET_MASK />
</CI>

</CIS>
</CMDB>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Scripted soap webservice:

var xmldoc = new XMLDocument(soapRequestXML);
var nodelist = xmldoc.getNodes("//CIS/*");
for( i = 0; i < nodelist.getLength(); i++)
{
var parent = nodelist.item(i);
var ciId = xmldoc.getChildTextByTagName(parent, 'CI_ID');
var class1 = xmldoc.getChildTextByTagName(parent, 'CLASS');
var name = xmldoc.getChildTextByTagName(parent, 'CI_NAME');

}

Here my question is how to get 'IP_Address' all child node data of parent node 'P_Addresses' for each ci record like  below:

first ci record contains : 

<IP_Address>10.232.3.200</IP_Address>
<IP_Address>10.232.3.75</IP_Address>
<IP_Address>10.38.224.17</IP_Address>
<IP_Address>10.38.224.15</IP_Address>
<IP_Address>10.232.3.72</IP_Address>

Second ci record contains : 

<IP_Address>10.232.3.201</IP_Address>
<IP_Address>10.232.3.76</IP_Address>
<IP_Address>10.38.224.18</IP_Address>
<IP_Address>10.38.224.19</IP_Address>
<IP_Address>10.232.3.74</IP_Address>

 

var nodeIPList= parent.getElementsByTagName('IP_Addresses');

var u_ip_address = xmldoc.getChildTextByTagName(nodeIPList.item(0), 'IP_Address');

the above code returning the the first childtext details only but we needed all child node text details of "IP_Address"

 Thanks harshavardhan  and anukar for your prompt response now we are able to fetch the ip address details of each configuration item.

But the thing we are calling some other function called mapFields(ciObject,parent,ven); from the first for loop so this function is updating\inserting configuration record in my instance.

 

var k=0;

var xmldoc = new XMLDocument(soapRequestXML);
var nodelist = xmldoc.getNodes("//CIS/*");
for( i = 0; i < nodelist.getLength(); i++)
{

k=i+1;
var parent = nodelist.item(i);
var ciId = xmldoc.getChildTextByTagName(parent, 'CI_ID');
var class1 = xmldoc.getChildTextByTagName(parent, 'CLASS');
var name = xmldoc.getChildTextByTagName(parent, 'CI_NAME');

 

var ipAddressCountNodes = xmldoc.getNodes("//CMDB/CIS/CI[" + k + "]/IP_Addresses/*");
var ipAddressCountLength = ipAddressCountNodes.getLength();
gs.log("@444444 ipAddressCountLength:"+ ipAddressCountLength);
var arr = '';

for(j=1;j<=ipAddressCountLength;j++){
var ipAddress = xmldoc.getNodeText("//CMDB/CIS/CI[" + k + "]/IP_Addresses/IP_Address[" + j + "]");
//ipAddArr1.push(ipAddress);
arr += ipAddress+',';
}

var ciObject = new GlideRecord('u_cgi_redesign');
ciObject.initialize();
mapFields(ciObject,parent,name,arr );
ciObject.insert();

}

 

function mapFields(ciObject, parent,ven,arr) {

var nodeIPList= parent.getElementsByTagName('IP_Addresses');
if (nodeIPList) {

ciObject.u_ip_address = res;
}

}

 

When i added below sort ip address code in the mapFields() function its displaying the first configuration item sorted ip address details only and its not displaying the second ci sorted ip address details.?.

var ipAddArr1 = arr.split(',');
gs.log("@444444 ipAddArr1.length"+ipAddArr1.length);
var tmp,instr1,instr2 = [];
for(i=0;i<ipAddArr1.length;i++)
{
for(j=1;j<ipAddArr1.length-i;j++)
{
instr1 = ipAddArr1[j-1].split(".");
instr2 = ipAddArr1[j].split(".");
if(parseInt(instr1[0]) > parseInt(instr2[0])){
tmp=ipAddArr1[j-1];
ipAddArr1[j-1]=ipAddArr1[j];
ipAddArr1[j]=tmp;
}else if(parseInt(instr1[0]) == parseInt(instr2[0])
&& parseInt(instr1[1]) > parseInt(instr2[1]) ){
tmp=ipAddArr1[j-1];
ipAddArr1[j-1]=ipAddArr1[j];
ipAddArr1[j]=tmp;
}else if(parseInt(instr1[0]) == parseInt(instr2[0])
&& parseInt(instr1[1]) == parseInt(instr2[1])
&& parseInt(instr1[2]) > parseInt(instr2[2])){
tmp=ipAddArr1[j-1];
ipAddArr1[j-1]=ipAddArr1[j];
ipAddArr1[j]=tmp;
}else if(parseInt(instr1[0]) == parseInt(instr2[0])
&& parseInt(instr1[1]) == parseInt(instr2[1])
&& parseInt(instr1[2]) == parseInt(instr2[2])
&& parseInt(instr1[3]) > parseInt(instr2[3])){
tmp=ipAddArr1[j-1];
ipAddArr1[j-1]=ipAddArr1[j];
ipAddArr1[j]=tmp;
}else if(parseInt(instr1[0]) == parseInt(instr2[0])
&& parseInt(instr1[1]) == parseInt(instr2[1])
&& parseInt(instr1[2]) == parseInt(instr2[2])
&& parseInt(instr1[3]) == parseInt(instr2[3]) && parseInt(instr2[4]) > parseInt(instr1[4])){
tmp=ipAddArr1[j-1];
ipAddArr1[j-1]=ipAddArr1[j];
ipAddArr1[j]=tmp;
}
}

}
var res = ipAddArr1[0];

Can you please help me.

Regards,

Kotaiah Sadari

4 REPLIES 4

Harsh Vardhan
Giga Patron

Tried with below scripts on my Personal instance. 

i am adding logic here,  give a try at your end. 

 

var larr=[]
var xmlString ="<CMDB><CIS><CI><CI_ID>AST000003591160</CI_ID><CLASS>BMC_COMPUTERSYSTEM</CLASS><CI_NAME>ANDSESP03</CI_NAME><IP_Addresses><IP_Address>10.232.3.200</IP_Address><IP_Address>10.232.3.75</IP_Address><IP_Address>10.38.224.17</IP_Address><IP_Address>10.38.224.15</IP_Address><IP_Address>10.232.3.72</IP_Address></IP_Addresses><DOMAIN /><PATCH_NUMBER /><PORT_PER_SLOT /><NUMBER_OF_SLOTS /><USERS_AFFECTED /><SUBNET_MASK /></CI><CI><CI_ID>AST000003396384</CI_ID><CLASS>BMC_COMPUTERSYSTEM</CLASS><CI_NAME>SNOWTEST2.JOHNH</CI_NAME><IP_Addresses><IP_Address>10.232.3.201</IP_Address><IP_Address>10.232.3.76</IP_Address><IP_Address>10.38.224.18</IP_Address><IP_Address>10.38.224.19</IP_Address><IP_Address>10.232.3.74</IP_Address></IP_Addresses><DOMAIN /><PATCH_NUMBER /><PORT_PER_SLOT /><NUMBER_OF_SLOTS /><USERS_AFFECTED /><SUBNET_MASK /></CI></CIS></CMDB>";


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




for(var i=0;i<req.CMDB.CIS.CI.length;i++){


for(j=0;j<req.CMDB.CIS.CI[i].IP_Addresses.IP_Address.length;j++){

var arr=req.CMDB.CIS.CI[i].IP_Addresses.IP_Address;

}
larr.push(arr)


}
gs.print(larr);

Hi Harshvardhan,

Thanks for your prompt response, that script is working properly but thing we are calling some other function called mapFields(ciObject,parent,ven); from the first for loop so this function is updating\inserting configuration record in my instance.

 

var xmldoc = new XMLDocument(soapRequestXML);
var nodelist = xmldoc.getNodes("//CIS/*");
for( i = 0; i < nodelist.getLength(); i++)
{
var parent = nodelist.item(i);
var ciId = xmldoc.getChildTextByTagName(parent, 'CI_ID');
var class1 = xmldoc.getChildTextByTagName(parent, 'CLASS');
var name = xmldoc.getChildTextByTagName(parent, 'CI_NAME');

var ciObject = new GlideRecord('u_cgi_redesign');
ciObject.initialize();
mapFields(ciObject,parent,name );
ciObject.insert();

}

 

function mapFields(ciObject, parent,ven) {

var nodeIPList= parent.getElementsByTagName('IP_Addresses');
if (nodeIPList) {

ciObject.u_ip_address = xmldoc.getChildTextByTagName(nodeIPList.item(0), 'IP_Address');
//ciObject.u_ip_address = ipAddArr1[0];
}

}

Here my question is how to pass each set of  ip address details for each iteration to mapFields()?.

Ankur Bawiskar
Tera Patron
Tera Patron

Hi Sadari,

So here is the script which works in background to get all the 10 ip address; you can push them in different array or single array; I have pushed 5 IP address in array since there are 2 chunks of 5 IP addresses

var xmldoc = new XMLDocument(soapRequestXML);
var nodelist = xmldoc.getNodes("//CIS/*");
var length = nodelist.getLength();

var ipAddressNodes = xmldoc.getNodes("//CMDB/CIS/CI")

for( i = 1; i <=ipAddressNodes.getLength(); i++){
var arr = [];
var ipAddressCountNodes = xmldoc.getNodes("//CMDB/CIS/CI[" + i + "]/IP_Addresses/*");
var ipAddressCountLength = ipAddressCountNodes.getLength();


for(j=1;j<=ipAddressCountLength;j++){
var ipAddress = xmldoc.getNodeText("//CMDB/CIS[1]/CI[" + i + "]/IP_Addresses/IP_Address[" + j + "]");
arr.push(ipAddress.toString());
}
gs.print('Array value is: ' + arr);

screenshot below

find_real_file.png

}

Mark Correct if this solves your issue and also mark Helpful if you find my response worthy based on the impact.
Thanks
Ankur

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader

Hi Ankur,

 

Thanks for your prompt response, that script is working properly but thing we are calling some other function called mapFields(ciObject,parent,ven); from the first for loop so this function is updating\inserting configuration record in my instance.

 

var xmldoc = new XMLDocument(soapRequestXML);
var nodelist = xmldoc.getNodes("//CIS/*");
for( i = 0; i < nodelist.getLength(); i++)
{
var parent = nodelist.item(i);
var ciId = xmldoc.getChildTextByTagName(parent, 'CI_ID');
var class1 = xmldoc.getChildTextByTagName(parent, 'CLASS');
var name = xmldoc.getChildTextByTagName(parent, 'CI_NAME');

var ciObject = new GlideRecord('u_cgi_redesign');
ciObject.initialize();
mapFields(ciObject,parent,name );
ciObject.insert();

}

 

function mapFields(ciObject, parent,ven) {

var nodeIPList= parent.getElementsByTagName('IP_Addresses');
if (nodeIPList) {

ciObject.u_ip_address = xmldoc.getChildTextByTagName(nodeIPList.item(0), 'IP_Address');
//ciObject.u_ip_address = ipAddArr1[0];
}

}

Here my question is how to pass each set of  ip address details for each iteration to mapFields()?.

 

Regards,

Kotaiah Sadari