如何通过路径检索特定XML节点的值?

JYe*_*ton 5 javascript xml xpath

我正在寻找这个问题的Javascript解决方案:

我有一个XML文档,它通过典型的AJAX方法加载:

var xml = http.responseXML;

请考虑以下示例xml片段:

<main>
    <primary>
         <enabled>true</enabled>
     </primary>
     <secondary>
         <enabled>true</enabled>
     </secondary>
 </main>
Run Code Online (Sandbox Code Playgroud)

我想通过指定路径获取节点的值,如下所示:

var second_enabled = getNodeValueByPath('main/secondary/enabled', xml);
Run Code Online (Sandbox Code Playgroud)

做这样的事情我找不到任何简洁的方法.我似乎被迫在使用之后迭代节点集合getElementsByTagName等.

我将如何构造该方法,getNodeValueByPath或者在Javascript中是否有一些允许这样做的构造?

我不熟悉Javascript.

编辑:这是一个示例,显示我尝试使用XPath及其失败的方式:

XML:

<?xml version="1.0" ?>
<main xmlns="example.com">
  <primary>
    <enabled>true</enabled>
  </primary>
  <secondary>
    <enabled>false</enabled>
  </secondary>
</main>
Run Code Online (Sandbox Code Playgroud)

JavaScript :(这些只是相关的功能)

function useHttpResponse()
{
    if (http.readyState == 4)
    {
        if(http.status == 200)
        {
            var xml = http.responseXML;
            var evalue = getXMLValueByPath('/main/secondary/enabled', xml);
            alert(evalue);
        }
    }
}

function getXMLValueByPath(nodepath, xml)
{
    var result = xml.evaluate(nodepath, xml, null, XPathResult.STRING_TYPE, null).stringValue;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

我使用上面的JavaScript而没有任何额外的库.我正在使用Mozilla Firefox 3.6.13,它使用document.evaluate方法来选择节点(根据w3schools的这些信息).此应用程序供内部使用,不必在多个浏览器上运行.

给出这些示例,将出现警告对话框,但不包含任何文本.如果我xmlns="example.com"从XML文档中删除该字符串,则会出现警告对话框,其中包含所需的文本"false".

使用Firebug进行调试resultNode只要声明了名称空间,就会显示为空字符串.

小智 5

这是FAQ:在XPath 1.0中,没有前缀的QName测试选择null(或空)命名空间URI下的元素.因此,您需要从输入源(example.com)向默认命名空间URI注册前缀.

你如何使用DOM 3 XPath API做到这一点?

来自http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate

evaluate
计算XPath表达式字符串,并在可能的情况下返回指定类型的结果.类型
参数
[...] 解析器允许将 XPath表达式中的所有前缀(包括名称空间前缀)转换为适当的名称空间URI.如果指定为,则表达式中的任何名称空间前缀都将导致 与代码一起抛出.
resolver XPathNSResolver
xmlnullDOMExceptionNAMESPACE_ERR

来自https://developer.mozilla.org/en/DOM/document.evaluate

var xpathResult = document.evaluate(
 xpathExpression, 
 contextNode, 
 namespaceResolver, 
 resultType, 
 result);
Run Code Online (Sandbox Code Playgroud)
  • namespaceResolver是一个将传递任何名称空间前缀的函数,并且应返回表示与该前缀关联的名称空间URI的字符串.它将用于解析XPath本身内的前缀,以便它们可以与文档匹配.null对于HTML文档或没有使用名称空间前缀时很常见.

按照本指南,您可以使用document.createNSResolver或执行以下功能:

function nsResolver(prefix) {   
  return prefix == 'ex' ? 'example.com' : null;   
}  

function useHttpResponse()
{
  if (http.readyState == 4)
  {
     if (http.status == 200)
     {
        var xml = http.responseXML;
        var evalue = xml.evaluate('string(/ex:main/ex:secondary/ex:enabled)',
                                  xml,
                                  nsResolver,
                                  XPathResult.STRING_TYPE,
                                  null);
        alert(evalue.stringValue);
     }
  }
}     
Run Code Online (Sandbox Code Playgroud)