使用xpath用javascript从XML中获取内容时遇到问题

Trouble using xpath to get stuff out of XML with javascript

本文关键字:遇到 问题 获取 xpath javascript XML 使用      更新时间:2023-09-26

我想我正确地设置了名称空间解析程序

var nodes=xml.evaluate(path, //xpathExpression
                               xml,  //contextNode
                               NSResolver, //namespaceResolver
                               XPathResult.ANY_TYPE, //resultType
                               null //result
                              );

我认为我设置的路径是正确的,(我在这里尝试了很多变化,几乎所有可能工作的)

path="/";

但是nodes.iterateNext()似乎在告诉我我做错了什么:

firebug output : nodes : [object XPathResult] length : undefined 

不过,x和xml对象很好,因为我可以在firebug中看到它们和xml。如果你使用我的代码,我只是在chrome中测试,所以如果你使用IE,你可能会有一大堆其他的蠕虫。:)

这是xml(净化版本)

<dataset xmlns="http://stub.test.data1" xmlns:xs="http://another.stub.test.moredata">
<!--
<dataset
    xmlns="http://stub.test.data1"
    xmlns:xs="http://another.stub.test.moredata"
    xs:schemaLocation="http://yet.more.stub.test.data/xmldata.xsd"
>
-->
    <metadata>
        <item name="a" type="xs:string" length="92"/>
        <item name="b" type="xs:string" length="50"/>
        <item name="c" type="xs:short" precision="1"/>
        <item name="d" type="xs:string" length="66"/>
        <item name="e" type="xs:string" length="26"/>
        <item name="f" type="xs:string" length="6"/>
        <item name="g" type="xs:string" length="264"/>
        <item name="h" type="xs:double" precision="2"/>
        <item name="i" type="xs:string" length="22"/>
        <item name="j" type="xs:date"/>
        <item name="k" type="xs:date"/>
        <item name="l" type="xs:string" length="16"/>
        <item name="m" type="xs:short" precision="1"/>
        <item name="n" type="xs:short" precision="1"/>
        <item name="o" type="xs:string" length="50"/>
    </metadata>
    <data>
        <row>
            <value>someData1</value>
            <value>someData2</value>
            <value>someData3</value>
            <value>someData4</value>
            <value>someData5</value>
            <value>someData6</value>
            <value>someData7</value>
            <value>someData8</value>
            <value>someData9</value>
            <value>someData10</value>
            <value>someData11</value>
            <value>someData12</value>
            <value>someData13</value>
            <value>someData14</value>
            <value>someData15</value>
        </row>
    </data>
</dataset>

下面是javascript:

function loadXMLDoc(dname)
{
    if (window.XMLHttpRequest)
      {
        xhttp=new XMLHttpRequest();
      }
    else
      {
        xhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    //initializes the request
    xhttp.open("GET",dname,false);//method, url, optional async defaults to true
    try {xhttp.responseType="msxml-document"} catch(err) {
        console.log('hey, an error occured');
    } // Helping IE
    xhttp.send("");//send the request. Does not return till the response is returned (due to false above)
    return xhttp;
}
function NSResolver(nsPrefix) {
    console.log("nsPrefix : " + nsPrefix);
    if(nsPrefix == "xs") {
        return "http://www.w3.org/2001/XMLSchema-instance";
    }
}
function displayNodes() {
    // code for IE
    if (window.ActiveXObject || xhttp.responseType=="msxml-document")
    {
        console.log('code for IE');
        console.log('path=' + path);
        xml.setProperty("SelectionLanguage","XPath");
        nodes=xml.selectNodes(path);
        for (i=0;i<nodes.length;i++)
          {
          document.write(nodes[i].childNodes[0].nodeValue);
          document.write("<br>");
          }
    }
    // code for Chrome, Firefox, Opera, etc.
    else if (document.implementation && document.implementation.createDocument)
    {
        console.log('code for chr / ff / op');
        console.log('path=' + path);

        //docs : http://help.dottoro.com/ljruhkuj.php
        var nodes=xml.evaluate(path, //xpathExpression
                               xml,  //contextNode
                               NSResolver, //namespaceResolver
                               XPathResult.ANY_TYPE, //resultType
                               null //result
                              );
        console.log("nodes : " + nodes + " length : " + nodes.length);
        var result=nodes.iterateNext();
        while (result)
          {
              document.write(result.childNodes[0].nodeValue);
              document.write("<br>");
              result=nodes.iterateNext();
          }
    }
    document.write('shit should have displayed by now');
}

path="/"; 
function reload() {
    x=loadXMLDoc("testxml.xml"); //x is now a XMLHttpRequest object
    xml=x.responseXML; //xml is now a response to the request, or null if it failed
    displayNodes();
    console.log("x (XMLHTTPRequest Object) : " + x);
    console.log("xml (XMLHTTPRequest.responseXML) : " + xml);
}
reload();

查看Mozilla关于在Javascript中使用XPath的文档,XPathResult对象似乎没有您所要求的length这样的属性。

因此,当firebug说length : undefined时,并不一定意味着您在XPath路径或evaluate()的使用中做错了什么。我能看到你唯一做错的事就是索要nodes.length

如果你的结果是一个快照,你可以要求nodes.snapshotLength,但它不是:

当resultType参数中的结果类型指定为ANY_type时。。。如果返回的结果类型是节点集,则它将仅为UNORDERED_node_ITERATOR_type。

现在,当您进行迭代时,您应该得到一个结果节点:文档根节点,即<dataset>元素的(不可见的)父节点。接下来,您要求它打印result.childNodes[0].nodeValueresult.childNodes[0]应该是<dataset>元素。根据这些文档,元素的.nodeValue为null。因此,您的document.write()可能没有显示任何内容。

请尝试打印result.nodeName(此处为文档)。这应该为根节点提供#document,或者您选择的元素的名称。

如果你只是想让的东西工作,并验证它是否工作,我会将你的路径更改为"/*"。您将得到一个更具体的结果,即<dataset>元素。