对 XML 中指定的多个命名空间使用 createNSResolver [英] Using createNSResolver with multiple namespaces specified in the XML

查看:27
本文介绍了对 XML 中指定的多个命名空间使用 createNSResolver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的 xml 字符串:

I have an xml string such as this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <ExecuteResponse xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
      <ExecuteResult i:type="a:RetrieveEntityResponse" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:ResponseName>RetrieveEntity</a:ResponseName>
        <a:Results xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
          <a:KeyValuePairOfstringanyType>
            <b:key>Some Value</b:key>
          </a:KeyValuePairOfstringanyType>
        </a:Results>
      </ExecuteResult>
    </ExecuteResponse>
  </s:Body>
</s:Envelope>

我正在尝试做一些事情:

I'm trying to do something along the lines of:

var resolver = xmlDoc.createNSResolver(xmlDoc.documentElement);
return new XPathEvaluator().evaluate("//b:key", xmlDoc.documentElement, resolver, XPathResult.ANY_TYPE, null);

关键节点没有找到,原因是我调用的时候

The key node is not being found, and the reason is when I call

resolver.lookupNamespaceURI("b")

直接返回null.但是,当我这样做时它确实会返回一些东西

directly, it returns null. However, it does return something when I do

resolver.lookupNamespaceURI("s")

所以我最好的猜测是 createNSResolver 方法只在传入的 xml 文档的根节点中查找命名空间.有什么方法可以让它找到在 xml 中定义的所有命名空间,或者其他一些如何构建文档中存在的所有命名空间的列表?

so my best guess is the createNSResolver method only looks for namespaces in the root node of the xml document that is passed in. Is there any way to make it find all of the namespaces that are defined in the xml, or some other way to build a list of all of the namespaces that exist in the document?

谢谢!

推荐答案

在一般情况下,基于 XML 文档中的所有命名空间声明设置一致的命名空间解析是不可能的,例如

Well setting up consistent namespace resolving based on all namespace declarations in the XML document is not possible in the general case as you could have e.g.

<root xmlns="http://example.com/n1">
  <foo xmlns="http://example.com/n2">
   <p1:bar xmlns:p1="http://example.com/n1">
    <p2:baz xmlns:p2="http://example.com/n1">...</p2:baz>
   </p1:bar>
  </foo>
</root>

使用不同前缀的相同命名空间,当然您可以使用示例,例如

where the same namespace is used with different prefixes and of course you could have samples as e.g.

<p:foo xmlns:p="http://example.com/n1">
  <p:bar xmlns:p="http://example.com/n2">...</p:bar>
</p:foo>

其中相同的前缀绑定到不同元素上的不同命名空间 URI.

where the same prefix is bound to different namespace URIs on different elements.

所以基本上你需要知道你正在寻找的元素节点的命名空间 URI,然后你可以使用你的代码可以选择的任何前缀设置命名空间解析器,例如

So basically you need to know the namespace URI of the element node you are looking for, then you can set up a namespace resolver with any prefix your code can choose e.g.

return xmlDoc.evaluate("//pf:key", xmlDoc, function(prefix) { if (prefix === 'pf' return 'http://schemas.datacontract.org/2004/07/System.Collections.Generic'; else return null; }, XPathResult.ANY_TYPE, null);

另一方面,对于那个简单的路径,我根本不会使用 XPath 和 evaluate 而是使用 return xmlDoc.getElementsByTagNameNS('http://schemas.datacontract.org/2004/07/System.Collections.Generic', 'b');.

On the other hand with that simple path I would not use XPath and evaluate at all but rather go for return xmlDoc.getElementsByTagNameNS('http://schemas.datacontract.org/2004/07/System.Collections.Generic', 'b');.

至于在 DOM 树中查找名称空间声明以根据前缀自己构建名称空间解析器,XPath 可以通过查看名称空间轴来提供一些帮助,例如//namespace::* 但在浏览器中 Mozilla/Firefox 从不认为有必要支持命名空间轴.然后是一些 DOM Level 3 方法 http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefixhttp://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI 所以您可以编写自己的代码来遍历 DOM 树并收集命名空间声明,但这在一般情况下无助于解决我上面发布的两个示例中概述的问题.

As for finding namespace declarations in a DOM tree to build up a namespace resolver yourself based on prefixes, XPath can give some assistance itself by looking at the namespace axis e.g. //namespace::* but inside the browser Mozilla/Firefox never considered it necessary to support the namespace axis. Then there are some DOM Level 3 methods http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix and http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI so you could write your own code walking the DOM tree and collecting namespace declarations but that does not help in the general case to solve the problems outlined in the two example samples I posted above.

这篇关于对 XML 中指定的多个命名空间使用 createNSResolver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆