我正在尝试从下面的XML中选择特定节点"effectiveintervalstart"的值(由于很长,一直粘贴在底部)。

这是我的代码:

//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)


但是到目前为止,这将返回一个空数组。

这是我的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>


非常感谢您的帮助,非常感谢。

最佳答案

正如@ThijsKuipers所提到的,“ MSXML.DOMDocument”不了解您所引用的名称空间(“ a:”和“ b:”)。

您必须通过添加以下内容使DOM知道名称空间:

//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(" "));


然后,您可以按期望查询XML。

跨浏览器支持

附带说明:您根本不应该使用新的ActiveXObject(“ MSXML2.DOMDocument”)

Chrome,Firefox,Safari,Project Spartan和任何其他仅HTML5的浏览器都不了解“ ActiveXObject”。
您可能会问,然后我该如何解析XML?
前面提到的SoapJs使用document.evaluate。有关详细信息,请参见this answer

数据

如果您可以通过任何方式重写查询以使用OData endpoint,则它将/可以返回JSON,从本质上讲,它对JavaScript更友好。

07-26 09:33