【发布时间】: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