将 createNSResolver 与 XML 中指定的多个命名空间结合使用

2024-02-20

我有一个 xml 字符串,如下所示:

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

我正在尝试做一些事情:

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

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

resolver.lookupNamespaceURI("b")

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

resolver.lookupNamespaceURI("s")

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

Thanks!


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

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

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

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

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

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

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');.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 createNSResolver 与 XML 中指定的多个命名空间结合使用 的相关文章

随机推荐