1

I'm trying to select the value of a specific node "effectiveintervalstart" from the XML below (pasted all the way on the bottom since it's long).

Here's my code:

//the XML is returned into req.responseXML.xml
var result = req.responseXML.xml.toString();
            var doc = new ActiveXObject("MSXML2.DOMDocument");
            doc.async = false;
            doc.loadXML(result);

            var arrayAnswers = [];
            var arr = doc.selectNodes("//b:effectiveintervalstart");
            for (var i = 0, len = arr.length; i < len; i++) {

                arrayAnswers[i] = arr.nextNode.text;
            }

            alert(arrayAnswers);
            alert(arrayAnswers.length)

However so far this is returning an empty array instead.

This is my XML.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <RetrieveMultipleResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <RetrieveMultipleResult xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">
        <a:Entities>
          <a:Entity>
        <a:Attributes xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
          <a:KeyValuePairOfstringanyType>
            <b:key>calendarid</b:key>
            <b:value i:type="c:guid" xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/">933d2b7d-0e7c-e211-a14f-78e7d1620f84</b:value>
          </a:KeyValuePairOfstringanyType>
          <a:KeyValuePairOfstringanyType>
            <b:key>calendarrules</b:key>
            <b:value i:type="a:EntityCollection">
              <a:Entities>
                <a:Entity>
                  <a:Attributes>
                    <a:KeyValuePairOfstringanyType>
                      <b:key>calendarruleid</b:key>
                      <b:value i:type="c:guid" xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/">b77b4621-3774-e411-80db-005056971aab</b:value>
                    </a:KeyValuePairOfstringanyType>                        

                    /* this node */
                    <a:KeyValuePairOfstringstring>
                      <b:key>effectiveintervalstart</b:key>
                      <b:value>11/26/2014</b:value>
                    </a:KeyValuePairOfstringstring>
                    /*  */

                    <a:KeyValuePairOfstringstring>
                      <b:key>rank</b:key>
                      <b:value>0</b:value>
                    </a:KeyValuePairOfstringstring>

Thank you very much for your help, much appreciated. .

jcjr
  • 1,503
  • 24
  • 40
ichachan
  • 637
  • 1
  • 10
  • 34
  • I'm guessing your error lie around var arr = doc.selectNodes("//b:effectiveintervalstart"); Try "/Envelope/Body/RetrieveMultipleResponse/RetrieveMultipleResult/Attributes/KeyValuePairOfStringanyType/Value/Entities/Entity/Attributes/KeyValuePairOfstringstring/" – WickedFan Dec 04 '14 at 15:59
  • Where do you see the node `b:effectiveintervalstart`, it doesn't exist... the node `//a:KeyValuePairOfstringstring[b:key = 'effectiveintervalstartdate']/b:value` does exist. You might want to take a look at the Sdk.Soap.js library for inspiration https://code.msdn.microsoft.com/SdkSoapjs-9b51b99a. – Thijs Kuipers Dec 04 '14 at 16:59

1 Answers1

0

As @ThijsKuipers mentions, the ´MSXML.DOMDocument´ doesn't know about the namespaces (´a:´ and ´b:´) you are referencing.

You must make your DOM aware of the namespaces by adding:

//From: https://code.msdn.microsoft.com/SdkSoapjs-9b51b99a/sourcecode?fileId=113716&pathId=1614657476

var ns = { 
  "s": "http://schemas.xmlsoap.org/soap/envelope/", 
  "a": "http://schemas.microsoft.com/xrm/2011/Contracts", 
  "i": "http://www.w3.org/2001/XMLSchema-instance", 
  "b": "http://schemas.datacontract.org/2004/07/System.Collections.Generic", 
  "c": "http://www.w3.org/2001/XMLSchema", 
  "d": "http://schemas.microsoft.com/xrm/2011/Contracts/Services", 
  "e": "http://schemas.microsoft.com/2003/10/Serialization/", 
  "f": "http://schemas.microsoft.com/2003/10/Serialization/Arrays", 
  "g": "http://schemas.microsoft.com/crm/2011/Contracts", 
  "h": "http://schemas.microsoft.com/xrm/2011/Metadata", 
  "j": "http://schemas.microsoft.com/xrm/2011/Metadata/Query", 
  "k": "http://schemas.microsoft.com/xrm/2013/Metadata", 
  "l": "http://schemas.microsoft.com/xrm/2012/Contracts" 
 }; 

var namespaces = []; 
for (var i in ns)
{ 
    namespaces.push("xmlns:" + i + "='" + ns[i] + "'"); 
} 

doc.setProperty("SelectionNamespaces", namespaces.join(" "));

Then you can query your XML as you expect.

Cross-browser support

On a side note: You shouldn't be using new ActiveXObject("MSXML2.DOMDocument") at all

Chrome, Firefox, Safari, Project Spartan and any other HTML5-only browser don't understand "ActiveXObject". How do I then parse XML, you might ask? The before mentioned SoapJs uses document.evaluate. See this answer for details.

OData

If you by any means can rewrite you query to use the OData endpoint then it will/could return JSON back which, by nature, is much more JavaScript-friendly.

Community
  • 1
  • 1
Casper Jensen
  • 551
  • 1
  • 5
  • 15