【问题标题】:XPath/Javascript - INVALID_STATE_ERR when creating new nodes treeXPath/Javascript - 创建新节点树时出现 INVALID_STATE_ERR
【发布时间】:2011-11-06 19:16:09
【问题描述】:

我目前正在玩 JS 和嵌入式 XPath。我正在尝试创建一个小测试脚本,并发现了一个我想了解的有趣错误。我这样调用评估函数:

var result = document.evaluate(
    xpath,
    document,
    null,
    XPathResult.ANY_TYPE);

在这种情况下,我得到的结果好坏参半。字符串、布尔值和数字类型处理起来没有问题,但 UNORDERED_NODE_ITERATOR_TYPE 有点棘手。

我处理结果的函数如下所示:

    function nodes(iterator, parentNode) {
        var cur = iterator.iterateNext(); // do not touch! altering this object causes a INVALID_STATE_ERR Exception
        var myObj = cur == null || cur == undefined ? undefined : cur.cloneNode(true);
        var count = 0;

        while(myObj) {
            parentNode.appendChild(myObj);
            var =  iterator.iterateNext().cloneNode(true);
        }
    }

但是当我尝试运行这个函数时,我得到一个 INVALID_STATE_ERR 异常。但为什么?我确实克隆了对象,我的父节点是一个新创建的元素节点。 (document.createElement('body') 应该替换最后的原始正文节点。

我是否需要以其他方式创建 new-body 元素?是否因为新的 body 元素附加到当前文档树而引发了此异常?如果我不能使用 createElement 怎么办?

【问题讨论】:

  • 考虑发布足够多的示例代码让我们重现问题,也许使用像jsfiddle.net 这样的网站。恐怕像var = iterator.iterateNext().cloneNode(true); 这样的行在语法上甚至都不正确。对于 XPath DOM API,考虑首先迭代结果以收集找到的节点,例如在一个数组中,然后操作 DOM 树。另一方面,HTML 文档只有一个 body 元素,那么为什么需要使用迭代器呢?选择单个节点不就足够了吗?
  • 我试图将你的 sn-ps 变成一个测试用例来重现这个问题,这里是:jsfiddle.net/pe95g/2。我认为该示例应该可以正常工作,并且在 Mozilla 和 Opera 中确实可以,但在 Chrome 和 Safari 中,我得到一个“INVALID_STATE_ERR: DOM Exception 11”。据我了解,这是 WebKit 的 DOM 实现中的一个错误,尽管 DOM Level 3 XPath 注释没有特别详细地说明什么是“使迭代无效”的“文档修改”。如果我将代码更改为使用快照 (jsfiddle.net/WT5Uk/1),它适用于 Mozilla、Opera、Safari、Chrome。
  • 你是对的。我也用快照尝试了这个,但在那里我发现了另一个奇怪的失败。当我使用评估函数时,我使用定义的函数“evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result);”在 Firefox 中,但相同的调用风格会导致 chrome (15.0.874.106) 中的错误。我必须这样称呼:“document.evaluate(xpath,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)”奇怪!但是你是对的,上面的代码在 Firefox 7 中运行。(如果你添加你的评论作为答案,我会接受它,因为它对我有很大帮助)

标签: javascript html dom xpath


【解决方案1】:

我尝试制作一个测试用例来重现该问题,http://jsfiddle.net/pe95g/2/。它适用于 Mozilla 和 Opera,但不适用于 Chrome 和 Safari 等 WebKit 浏览器。在我看来,它不应该失败,因为正在查询的 DOM 文档没有更改,只有未附加到该文档的节点会在 XPath 迭代发生时创建和更改。另一方面,W3C DOM Level 3 XPath 注释对于什么是“使迭代无效”的“文档修改”并不是很精确。

作为一种解决方法,我尝试使用快照而不是迭代器和 DOM Level 3 XPath API http://jsfiddle.net/WT5Uk/1/,这种方法对我来说适用于所有支持 document.evaluate 的所有四种主要桌面浏览器(即 Mozilla、Opera、 Safari,铬)。所以这是我可以建议的唯一解决方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多