How to get child child node details from xml using XMLDocument() in servicenow?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2019 03:16 AM
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

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2019 03:54 AM
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2019 05:36 AM
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()?.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2019 03:57 AM
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
}
Mark Correct if this solves your issue and also mark Helpful if you find my response worthy based on the impact.
Thanks
Ankur
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2019 05:34 AM
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