使用JavaScript中的xPath解析默认命名空间下的XML

3
我需要创建一个XML xPath解析器。所有解析都必须在客户端上处理(使用JavaScript)。我创建了一段JavaScript代码来实现这一点,当默认命名空间起作用时,所有看起来都很正常。但是,我无法查询具有默认命名空间的XML。
我在fiddle上创建了一个示例代码。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中是否可以分配默认命名空间前缀?

注意:在IE中,提供的fiddle示例将无法工作。

2个回答

9
我认为有三种方法可以做到这一点:
  1. 使用 //*[local-name()='book'] 语法来访问节点。
  2. 将 XML 转换为字符串,使用 RegExp 删除默认命名空间,再将其转换回 XML
  3. 对于您事先知道命名空间的 XML 文件,您可以创建自己的命名空间解析器,它将允许您使用默认命名空间的自定义前缀。

此操作可按以下方式完成:

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

0

我有一种印象,你对XPath处理的理解与实现不符 - 除非你所处理的实现与我熟悉的实现非常不同。

通常,XPath处理器必须注册命名空间并将前缀映射到它们,以便成功评估表达式。因此,前缀可以是任何东西 - 唯一重要的是它们映射到的内容。请参阅这位知名专家的答案以获取更多信息。


您可以省略命名空间的前缀,那么该命名空间将被视为默认命名空间。以下是一些示例和说明:http://www.w3schools.com/xml/xml_namespaces.asp,http://www.developerfusion.com/article/3720/understanding-xml-namespaces/5/ - dugokontov
@dugokontov,我认为你混淆了无命名空间默认命名空间。在XML文档中,您可以使用xmlns="something"来设置默认命名空间,因此没有前缀。默认情况下,默认命名空间是空命名空间(无命名空间)。默认命名空间取决于上下文;XPath在这里也不例外。通过在XPath表达式中不指定任何前缀并且不注册任何命名空间,OP的表达式很可能匹配没有命名空间的节点。 - Lumi
你刚才在我的评论中说了和我一样的话:“在XML文档中,您可以使用xmlns =“ something”设置默认命名空间,因此没有前缀”。也就是说,“您可以省略命名空间前缀,然后该命名空间被视为默认命名空间”。另外,在您最后一句中描述的情况在我提供的第一个示例中已经说明:http://jsfiddle.net/BF34q/1/。所以,我有点困惑,您想对我说什么? - dugokontov
@dugokontov,我能理解你为什么感到困惑 :-) 我可能误读了你的陈述,对此很抱歉。我想对你说的是,你需要在XPath处理器中注册命名空间http://example.com/domain。只需将其映射到某个前缀x,然后在查询中使用该前缀即可。它可以在使用LibXML2等库时工作。不过 embedded in the browser 的处理器的咒语不确定应该是什么。也许可以尝试使用Saxon库 - Lumi
不要误会我,但我有一种感觉,你根本没有读懂我的问题。我知道我必须为默认命名空间分配一些前缀,我的问题是“是否可能在Javascript中分配默认命名空间前缀?”请在回答之前仔细阅读... - dugokontov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接