Help with inbound SOAP message and going through (interate through) each "key"

Steven Young
Tera Guru

Hello awesome community.

wondering if you can help with i hope something simple, but i just cannot for the life of me, get it working.

with JSON, you can easy go through each key in the object.
var obj = {

"key": "value",

"key": "value"

}

and you can do 
for (var key in obj){

do something

}

but i've got an incoming SOAP message in XML.  I've looked at the docs site and it's not very helpful when trying to go through each "key"  in xml.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sam="http://www.service-now.com/Recieve">
   <soapenv:Header/>
   <soapenv:Body>
      <sam:lookup>
         <!--Optional:-->
         <serial_number>lajsdfl;asdlfjsadf</serial_number>
         <!--Optional:-->
         <asset_tag>asdfasdf</asset_tag>
         <!--Optional:-->
         <display_name>asdfasdfsad</display_name>
         <!--Optional:-->
         <assigned_to>asdfasdf</assigned_to>
      </sam:lookup>
   </soapenv:Body>
</soapenv:Envelope>


this is similar to the data that we will be receiving, but a lot more field's that need to be updated.
i have tried and tried to iterate through all fields in the sam:lookup  but i cannot get it working.
and i do not want to have to do a new line with "request.assigned_to"    request.display_name   etc.

if you can help, that would be greatly appreciated.

3 REPLIES 3

Vishal Jaswal
Giga Sage

Hello @Steven Young 

Sharing a similar thread: https://www.servicenow.com/community/developer-forum/api-call-need-to-get-the-cookie-from-the-authen... 

I have tried below background script (Reference: https://www.servicenow.com/docs/bundle/yokohama-api-reference/page/app-store/dev_portal/API_referenc...

var xmlString = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sam="http://www.service-now.com/Recieve"><soapenv:Header/><soapenv:Body><sam:lookup><!--Optional:--><serial_number>lajsdfl;asdlfjsadf</serial_number><!--Optional:--><asset_tag>asdfasdf</asset_tag><!--Optional:--><display_name>asdfasdfsad</display_name><!--Optional:--><assigned_to>asdfasdf</assigned_to></sam:lookup></soapenv:Body></soapenv:Envelope>';
// Parse XML
var xmldoc = new XMLDocument2();
xmldoc.parseXML(xmlString);
// Extract values using XPath
var serialNumber = xmldoc.getNodeText("//serial_number");
var assetTag = xmldoc.getNodeText("//asset_tag");
var displayName = xmldoc.getNodeText("//display_name");
var assignedTo = xmldoc.getNodeText("//assigned_to");
// Print extracted values
gs.print("Serial Number: " + serialNumber);
gs.print("Asset Tag: " + assetTag);
gs.print("Display Name: " + displayName);
gs.print("Assigned To: " + assignedTo);

 

VishalJaswal_0-1742833597225.png

 




Hope that helps!

Thank you for the help.  However, No, this does not help.  i dont want to have to use a line to get each field.   i already know i can do the xmldoc.getNodeText.

but also,  i can do   "request.serial_number"   as well....
i'm looking to interate through each field without having to use a line for each.

Ankur Bawiskar
Tera Patron
Tera Patron

@Steven Young 

Unfortunately that's not how XML is structured.

Another way, convert XML to JSON and then do JSON parsing

var xmlString = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sam="http://www.service-now.com/Recieve">' +
                '<soapenv:Header/>' +
                '<soapenv:Body>' +
                '<sam:lookup>' +
                '<serial_number>lajsdfl;asdlfjsadf</serial_number>' +
                '<asset_tag>asdfasdf</asset_tag>' +
                '<display_name>asdfasdfsad</display_name>' +
                '<assigned_to>asdfasdf</assigned_to>' +
                '</sam:lookup>' +
                '</soapenv:Body>' +
                '</soapenv:Envelope>';

gs.info(xmlString);

var jsonObject = gs.xmlToJSON(xmlString);

function extractValues(obj, keys) {
    var result = {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === 'object') {
                var nestedResult = extractValues(obj[key], keys);
                for (var nestedKey in nestedResult) {
                    if (nestedResult.hasOwnProperty(nestedKey)) {
                        result[nestedKey] = nestedResult[nestedKey];
                    }
                }
            } else {
                if (keys.includes(key)) {
                    result[key] = obj[key];
                }
            }
        }
    }
    return result;
}

var keysToExtract = ["serial_number", "display_name", "asset_tag", "assigned_to"];
var extractedValues = extractValues(jsonObject, keysToExtract);

for (var key in extractedValues) {
    if (extractedValues.hasOwnProperty(key)) {
        gs.info(key + ': ' + extractedValues[key]);
    }
}

Output:

json parsin.gif

If my response helped please mark it correct and close the thread so that it benefits future readers.

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