javascript 如何按路径检索特定 XML 节点的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4495569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 13:53:17  来源:igfitidea点击:

How do I retrieve the value of a specific XML node by path?

javascriptxmlxpath

提问by JYelton

I am looking for a Javascript solution to this problem:

我正在寻找针对此问题的 Javascript 解决方案:

I have an XML document which is loaded by way of a typical AJAX method:

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

var xml = http.responseXML;

var xml = http.responseXML;

Consider the following example xml snippet:

考虑以下示例 xml 片段:

<main>
    <primary>
         <enabled>true</enabled>
     </primary>
     <secondary>
         <enabled>true</enabled>
     </secondary>
 </main>

I would like to get the value of a node by specifying the path as follows:

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

var second_enabled = getNodeValueByPath('main/secondary/enabled', xml);

I cannot find any concise way of doing something like this. I seem to be forced to iterate through node collections after using getElementsByTagNameand the like.

我找不到任何简洁的方法来做这样的事情。在使用getElementsByTagName等之后,我似乎被迫遍历节点集合。

How would I construct the method getNodeValueByPathor is there some construct in Javascript that allows for this?

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

I am not well versed in Javascript.

我不精通Javascript。

EDIT:Here is an example that shows my attempt at using XPath and how it is failing:

编辑:这是一个示例,显示了我尝试使用 XPath 以及它是如何失败的:

XML:

XML:

<?xml version="1.0" ?>
<main xmlns="example.com">
  <primary>
    <enabled>true</enabled>
  </primary>
  <secondary>
    <enabled>false</enabled>
  </secondary>
</main>

JavaScript:(these are the relevant functions only)

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;
}

I am using the above JavaScript without any additional libraries. I am using Mozilla Firefox 3.6.13 which uses the document.evaluate method to select nodes (according to this information from w3schools). This application is for internal use and does not have to work on multiple browsers.

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

Given these examples, the alert dialog will appear, but contain no text. If I remove the string xmlns="example.com"from the XML document, the alert dialog appears with the text "false" as desired.

鉴于这些示例,警报对话框将出现,但不包含任何文本。如果我xmlns="example.com"从 XML 文档中删除该字符串,警报对话框将根据需要显示文本“false”。

Debugging using Firebugshows that resultNodeis an empty string as long as the namespace is declared.

使用Firebug 进行调试显示,resultNode只要声明了命名空间,它就是一个空字符串。

采纳答案by JYelton

This is FAQ: In XPath 1.0, a QName test without prefix selects elements under the null (or empty) namespace URI. So you need to register a prefix to the default namespace URI from your input source (example.com).

这是常见问题解答:在 XPath 1.0 中,不带前缀的 QName 测试选择空(或空)命名空间 URI 下的元素。因此,您需要从输入源 ( example.com)向默认命名空间 URI 注册前缀。

How do you do that with DOM 3 XPath API?

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

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

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

evaluate
Evaluates an XPath expression string and returns a result of the specified type if possible.
Parameters
[...]
resolverof typeXPathNSResolver
The resolver permits translation of all prefixes, including the xmlnamespace prefix, within the XPath expression into appropriate namespace URIs. If this is specified as null, any namespace prefix within the expression will result in DOMExceptionbeing thrown with the code NAMESPACE_ERR.

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

And from https://developer.mozilla.org/en/DOM/document.evaluate

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

var xpathResult = document.evaluate(
 xpathExpression, 
 contextNode, 
 namespaceResolver, 
 resultType, 
 result);
  • namespaceResolveris a function that will be passed any namespace prefixes and should return a string representing the namespace URI associated with that prefix. It will be used to resolve prefixes within the XPath itself, so that they can be matched with the document. nullis common for HTML documents or when no namespace prefixes are used.
var xpathResult = document.evaluate(
 xpathExpression, 
 contextNode, 
 namespaceResolver, 
 resultType, 
 result);
  • namespaceResolver是一个函数,它将传递任何命名空间前缀,并应返回一个字符串,表示与该前缀关联的命名空间 URI。它将用于解析 XPath 本身内的前缀,以便它们可以与文档匹配。null在 HTML 文档或不使用名称空间前缀时很常见。

Following this guide, you can use document.createNSResolveror a functionlike:

按照本指南,您可以使用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);
     }
  }
}     

回答by danjah

I've been playing around with the same thing, I tried a few XPath JS libraries, here's one: http://js-xpath.sourceforge.net/, but having said that, I couldn't get stuff working so I'll be watching this question avidly :)

我一直在玩同样的事情,我尝试了一些 XPath JS 库,这是一个:http: //js-xpath.sourceforge.net/,但话虽如此,我无法让东西工作,所以我会热切关注这个问题:)

Also, at SO: Cross-browser XPath implementation in JavaScript

此外,在 SO:JavaScript 中的跨浏览器 XPath 实现

回答by qwertymk

var xpathtosearchfor = '//div';
var result = new XPathEvaluator().evaluate(xpathtosearchfor,
    document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);

In firefox at least

至少在 Firefox 中

回答by Rajesh Kumar G

XmlDocument xDoc = new XmlDocument();
xDoc.Load("d:\one.xml");
XmlNode xNode = xDoc.SelectSingleNode(@"//main/secondary/enabled");
string result = ((XmlElement)xNode).FirstChild.Value;