XMLHelper with Namespaces

raprohaska
Kilo Guru

ServiceNow Level: Beginner

Trying to parse a SOAP response and I have found all suggestions point to XMLDocument and XMLHelper but I see very little about what functions are exposed through these objects. I think my troubles are due to the namespace in the xml. Here is an example of the xml:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

  <s:Header />

  <s:Body>
          <CreateIncidentResponse xmlns="http://tempuri.org/">

                  <CreateIncidentResult xmlns:a="http://schemas.datacontract.org/2004/07/Entities.CMS.ExternalServices"
                                                                              xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
         
                            <a:Messages />

                            <a:Success>true</a:Success>

                            <a:TicketID>I140000048</a:TicketID>

                    </CreateIncidentResult>

            </CreateIncidentResponse>

  </s:Body>

</s:Envelope>

var response = s.post();

var helper = new XMLHelper(response);

var obj = helper.toObject();

JSUtil.logObject(obj, 'obj Response: ');

Log Object: obj Response: Object @xmlns:s: string =

http://schemas.xmlsoap.org/soap/envelope/ s:Body: Object UpdateIncidentResponse:

Object @xmlns: string = http://tempuri.org/ UpdateIncidentResult: Object

@xmlns:a: string =

http://schemas.datacontract.org/2004/07/Entities.CMS.ExternalServices

a:Success: string = true a:TicketID: string = I140000048 a:Messages: null = null

@xmlns:i: string = http://www.w3.org/2001/XMLSchema-instance

I can see the values (success = true and TicketID = I140000048) in the object but I don't understand how to access those values from code. Since I can't step through the code it is difficult to understand the structure of the object that is created.

Sorry if I'm reposting a question but I haven't found a great example yet.

- AA

10 REPLIES 10

Thank your for your effort and response.   I don't know how your solution applies, but if you could provide more of an example, I think I might be able to understand better.



Here is an example of my response:


<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:loginResponse xmlns:ns="http://services"><ns:return>159c78a6-caad-4478-a8f8-a73216a44b42</ns:return></ns:loginResponse></soapenv:Body></soapenv:Envelope>




Using your syntax, would I use something like this:


var loginresponse = obj["s:Body]["ns:loginResponse"]["ns:return"];


instead of


var loginresponse = xmldoc.getNodeText("//ns:return");


Hi Michael,



Try changing your code to this:



var loginresponse = obj["soapenv:Body"]["ns:loginResponse"]["ns:return"];




The pattern here is to use the full element name including the namespace as you descend into the object structure.


In my case, I have a list of elements on the xml and all elements have same tag name.   How to iterate through the XML to get all elements in an array? I see that getNodeText only returns me the first node that is found but can't return me the list of all nodes with the same 'name'.



Any idea how to do this ? by the way, they are all at same level so I cant use childiterator.


Hi Jesus,



If you're still using XMLHelper, the resulting object should turn these repeating elements into standard JavaScript Arrays.



Let's use an example SOAP response like this:



<?xml version="1.0" encoding="UTF-8"?>


<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">


<soapenv:Header/>


<soapenv:Body>


  <wis:getSomethingResponse>


      <GetSomeDataResponse>


          <thing1>value1</thing1>


          <thing2>value2</thing2>


          <arrayOfStuff>


              <name>arrayName1</name>


              <value>123456</value>


          </arrayOfStuff>


          <arrayOfStuff>


              <name>arrayName2</name>


              <value>654321</value>


          </arrayOfStuff>


          <arrayOfStuff>


              <name>arrayName3</name>


              <value>none</value>


          </arrayOfStuff>


      </GetSomeDataResponse>


  </wis:getSomethingResponse>


</soapenv:Body>


</soapenv:Envelope>



I'll usually start by turning this into an object with XMLHelper and logging the result to see what I'm working with. Run this from a background script:



var xml = '<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header/><soapenv:Body><wis:getSomethingResponse><GetSomeDataResponse><thing1>value1</thing1><thing2>value2</thing2><arrayOfStuff><name>arrayName1</name><value>123456</value></arrayOfStuff><arrayOfStuff><name>arrayName2</name><value>654321</value></arrayOfStuff><arrayOfStuff><name>arrayName3</name><value>none</value></arrayOfStuff></GetSomeDataResponse></wis:getSomethingResponse></soapenv:Body></soapenv:Envelope>';



var helper = new global.XMLHelper(xml);


var obj = helper.toObject();



gs.debug(JSUtil.describeObject(obj));



This gives us the following output:



*** Script: [DEBUG] Log Object


  Object


      @xmlns:soapenc: string = http://schemas.xmlsoap.org/soap/encoding/


      @xmlns:soapenv: string = http://schemas.xmlsoap.org/soap/envelope/


      @xmlns:xsd: string = http://www.w3.org/2001/XMLSchema


      @xmlns:xsi: string = http://www.w3.org/2001/XMLSchema-instance


      soapenv:Header: null = null


      soapenv:Body: Object


          wis:getSomethingResponse: Object


              GetSomeDataResponse: Object


                  thing1: string = value1


                  thing2: string = value2


                  arrayOfStuff: Array of 3 elements


                      [0]: Object


                          name: string = arrayName1


                          value: string = 123456


                      [1]: Object


                          name: string = arrayName2


                          value: string = 654321


                      [2]: Object


                          name: string = arrayName3


                          value: string = none



Armed with this knowledge, we can extract what we want:



var body = obj['soapenv:Body'];


var getSomeData = body['wis:getSomethingResponse']['GetSomeDataResponse'];


var stuffArray = getSomeData['arrayOfStuff'];



var i, item;


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


  item = stuffArray[i];


  gs.debug('name: {0}, value: {1}', item.name, item.value);


}



Running this gives us:



*** Script: [DEBUG] name: arrayName1, value: 123456


*** Script: [DEBUG] name: arrayName2, value: 654321


*** Script: [DEBUG] name: arrayName3, value: none



Hopefully this helps!


Hi Josh,



can youbrieflu explain how o textract data using for loop.