cev*_*ing 2 javascript arrays xpath
当我使用 时querySelectorAll,我可以td在我的示例文档中找到 138 个节点。
Array.from(document.querySelectorAll('td')).length
138
Run Code Online (Sandbox Code Playgroud)
当我对 XPath 做同样的事情时,我没有得到任何结果:
Array.from(document.evaluate(".//td", document.body, null, XPathResult.ANY_TYPE, null)).length
0
Run Code Online (Sandbox Code Playgroud)
虽然至少有一场比赛:
document.evaluate(".//td", document.body, null, XPathResult.ANY_TYPE, null).iterateNext().nodeName
"TD"
Run Code Online (Sandbox Code Playgroud)
问题似乎是Array.from无法迭代 a XPathResult。即使这样也返回 0:
Array.from(document.evaluate('.', document.body, null, XPathResult.ANY_TYPE, null)).length
0
Run Code Online (Sandbox Code Playgroud)
如何制作XPathResult适合的Array.from?
不幸的是你不能。Array.from可以将两种类型的对象转换为数组:
.length属性的“类数组” 。XPathResult不做任何这些。您可以通过手动迭代结果并将结果存储在一个数组中来做到这一点,例如:
const nodes = [];
let node = xPathResult.iterateNext();
while (node) {
nodes.push(node);
node = xPathResult.iterateNext();
}
Run Code Online (Sandbox Code Playgroud)
...但如果你无论如何都要循环遍历节点,你可能可以在循环中执行任何你想做的数组操作。
根据@JamesTheAwesomeDude的答案,如果将迭代器填充到 XPathResult 上,则可以使用Array.from(或扩展运算符)。这个迭代器稍微好一点,因为它可以对所有类型的 XPathResult 进行操作:
if (!XPathResult.prototype[Symbol.iterator]) XPathResult.prototype[Symbol.iterator] = function* () {
switch (this.resultType) {
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
let result;
while ( (result = this.iterateNext()) != null ) yield result;
break;
case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
for (let i=0; i < this.snapshotLength; i++) yield this.snapshotItem(i);
break;
default:
yield this.singleNodeValue;
break;
}
};
Run Code Online (Sandbox Code Playgroud)