【问题标题】:DOM XPath query doesn't work when a xmlns is given给出 xmlns 时,DOM XPath 查询不起作用
【发布时间】:2013-10-17 22:45:01
【问题描述】:

在 Firefox JavaScript 控制台中:

parser = new DOMParser();

foo = parser.parseFromString('<foo></foo>', "text/xml");
res = foo.evaluate("/foo", foo, null, 0, null);
res.iterateNext();
> [object Element]

foo = parser.parseFromString('<foo xmlns="http://foo.bar.baz/quux"></foo>', "text/xml");
res = foo.evaluate("/foo", foo, null, 0, null);
res.iterateNext();
> null

res = foo.evaluate("*[1]", foo, null, 0, null);
res.iterateNext();
> [object Element]

如果 XML 文档不包含 xmlns,它会被正确解析和查询。如果是这样,我们将无法再通过标签和属性名称进行查询。但是,使用通配符和索引进行查询确实有效。在 Chrome 中也观察到了同样的情况。创建和使用默认命名空间解析器以及自定义命名空间解析器并没有帮助。有什么建议吗?

【问题讨论】:

    标签: javascript xml dom xpath xml-namespaces


    【解决方案1】:

    在处理命名空间时,您必须做两件事。

    1. 在 XPath 表达式中使用命名空间。由于您的文档中没有前缀,我只选择了ns - 最好使用在现实世界代码中更具描述性的内容。
    2. 添加命名空间解析器,它实际上是作为第三个参数传递给evaluate(...) 的函数。

    将所有内容放在一起,您的代码将如下所示:

    parser = new DOMParser();
    foo = parser.parseFromString('<foo xmlns="http://foo.bar.baz/quux"></foo>', "text/xml");
    res = foo.evaluate("/ns:foo", foo, function(prefix) {
        if (prefix === 'ns') {
            return 'http://foo.bar.baz/quux';
        } else {
            return null
        }
    }, 0, null);
    res.iterateNext();
    

    按预期返回:

    <foo xmlns="http://foo.bar.baz/quux"></foo>
    

    您的第三个查询有结果,因为您使用了忽略命名空间的通配符匹配器 *。不注册命名空间但使用通配符匹配器的替代 XPath 表达式是

    //*[local-name() = 'foo']
    

    【讨论】:

    • 太棒了!非常感谢。早些时候,我用 javax.xml.xpath.XPathExpression 在 Java 中尝试过类似的代码,并且不需要额外的命名空间处理,我想知道为什么。似乎 Java XPath 实现在 XML 命名空间的上下文中不那么严格。
    猜你喜欢
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多