XPath/Javascript - 创建新节点树时 INVALID_STATE_ERR

发布于 2024-12-13 17:28:54 字数 947 浏览 0 评论 0原文

我目前正在使用 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') 应该替换最后的原始 body 节点。

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

I'm currently playing arround with JS and the embedded XPath. I'm trying to create a little test script and found an interesting error which I'd like to understand. I'm calling the evaluate function like this:

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

In this case I get mixed results. The string, boolean and number types are no problem to handle but the UNORDERED_NODE_ITERATOR_TYPE is somehow tricky.

My function to handle the result looks like that:

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

But when I try to run this function I get an INVALID_STATE_ERR exception. But why? I do clone the objects and my parent node is a new created element node. (document.createElement('body') which should replace the original body node at the end.

Do I need to create the new-body element in another way? Is this exception threwn because the new body element is attached to the current document tree? How could I do it if I can't use createElement?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名的好友 2024-12-20 17:28:54

我尝试制作一个测试用例来重现该问题, 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、Chrome)。所以这是我可以建议的唯一解决方法。

I tried to make a test case to reproduce the issue, http://jsfiddle.net/pe95g/2/. It works fine with Mozilla and Opera but fails with WebKit browsers like Chrome and Safari. In my view it should not fail as the DOM document that is being queried is not changed, only nodes not attached to that document are created and changed while the XPath iteration happens. On the other hand the W3C DOM Level 3 XPath note is not very precise as to what is a "document modification" that "invalidates the iteration".

As a workaround I tried to use a snapshot instead of an iterator with the DOM Level 3 XPath API, http://jsfiddle.net/WT5Uk/1/, that approach works fine for me with all four major desktop browser supporting document.evaluate (i.e. Mozilla, Opera, Safari, Chrome). So that is the only workaround that I can suggest.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文