【问题标题】:Parsing XML with default namespace using xPath in javascript在javascript中使用xPath解析具有默认命名空间的XML
【发布时间】:2011-10-09 08:15:45
【问题描述】:

我需要创建一个 XML xPath 解析器。所有解析都必须发生在客户端(使用 javascript)。我创建了一个执行此操作的 javascript,在默认命名空间发挥作用之前,一切看起来都很好。我根本无法查询具有默认命名空间的 XML。

我在小提琴上创建了一个示例代码。在 xmlString 中是从服务器接收的 XML 字符串。在 xPathString 中是对接收到的 XML 进行查询。

这里有一些场景:

  1. http://jsfiddle.net/BF34q/1/ - 没有命名空间 - 一切正常
  2. http://jsfiddle.net/BF34q/2/ - 添加了 ns 命名空间。元素有 ns: 前缀。 xPath 使用此前缀 - 好的
  3. http://jsfiddle.net/BF34q/3/ - 使用默认命名空间 - 不确定如何配置 xPathString。

注意其他人会使用这个解析器,所以我真的很想避免这样的解决方案

var xPathString = "//*[local-name()='book']";

并使他们能够使用简单的 xPath 表达式对其进行解析。我想知道是否可以在 javascript 中分配默认命名空间前缀?

注意:fiddle 上提供的示例在 IE 中不起作用。

【问题讨论】:

    标签: javascript xml xpath namespaces


    【解决方案1】:

    我认为有三种方法可以做到这一点:

    1. 使用//*[local-name()='book'] 语法访问节点
    2. Convert XML to string,使用 RegExp 删除默认命名空间,convert it back to XML
    3. 对于事先知道命名空间的 XML 文件,您可以创建 own namespace resolver,这将允许您使用自己的前缀作为默认命名空间。

    可以这样实现:

    function nsResolver(prefix) {
        switch (prefix) {
            case 'xhtml':
                return 'http://www.w3.org/1999/xhtml';
            case 'mathml':
                return 'http://www.w3.org/1998/Math/MathML';
            default:
                return 'http://example.com/domain';
        }
    }
    xml.evaluate('//myPrefix:book', xml, nsResolver, XPathResult.ANY_TYPE, null);
    

    【讨论】:

      【解决方案2】:

      我的印象是您对 XPath 处理的理解与实现不匹配 - 除非,也就是说,您正在处理的实现与我熟悉的非常不同。

      通常,XPath 处理器必须注册命名空间并将前缀映射到它们,才能成功计算表达式。所以前缀可以是任何东西——唯一重要的是它们映射到什么。请参阅this answer by a known expert 以获取更多信息。

      【讨论】:

      • 您可以省略命名空间的前缀,然后将该命名空间视为默认命名空间。以下是一些示例和说明:w3schools.com/xml/xml_namespaces.aspdeveloperfusion.com/article/3720/understanding-xml-namespaces/5
      • @dugokontov,我认为您混淆了 no namespacedefault namespace。在 XML 文档中,您使用 xmlns="something" 设置默认命名空间,因此没有前缀。默认情况下,默认命名空间空命名空间(无命名空间)。默认命名空间取决于上下文; XPath 在这里也不例外。通过不使用他的 XPath 表达式指定任何前缀并且不注册任何命名空间,OP 的表达式很可能匹配没有命名空间中的节点。
      • 你和我在评论中所做的一样感到悲伤:在 XML 文档中,你使用 xmlns="something" 设置默认命名空间,所以没有前缀 = = 您可以省略命名空间的前缀,然后该命名空间被视为默认命名空间。此外,您在最后一句话中的场景在我提供的第一个示例中进行了描述:jsfiddle.net/BF34q/1。所以,我有点困惑你想对我说什么?
      • @dugokontov,我明白你为什么感到困惑 :-) 我一定误读了你的陈述,对此深表歉意。我想对您说的是,您需要将命名空间http://example.com/domain 注册到您的XPath 处理器。只需将其映射到某个前缀 x,然后将该前缀用于您的查询。它将使用诸如 LibXML2 之类的库来工作。不过,不确定浏览器中嵌入的处理器应该是什么咒语。也许尝试使用Saxon library
      • 不要误会我的意思,但我感觉你根本没有阅读我的问题。我知道我必须为默认命名空间分配一些前缀,我的问题是 我想知道是否可以在 javascript 中分配默认命名空间前缀?。请在回答之前阅读...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2021-10-21
      • 2010-10-09
      • 2011-01-30
      • 2013-01-01
      相关资源
      最近更新 更多