Chrome JavaScript:如何访问xpath搜索的第n个结果?

35g0bw71  于 2023-05-11  发布在  Go
关注(0)|答案(2)|浏览(151)

问题描述

我尝试使用xpath从下面的HTML中定位“Messi”节点。为了最小化编码工作,我希望使用数组索引的解决方案,而不是通过迭代器循环。
我的假设是最标准和最简单的API是XPathExpression.evaluate()。如果有更好的API,请分享。
顺便说一下,我需要根据返回的结果对DOM Node进行更改。因此,XPathResult.resultType将被设置为ORDERED_NODE_ITERATOR_TYPE,因此不能使用XPathResult.snapshotItem()

HTML示例

<html>
<body>

<div>
    <div>NumberOne</div>
    <div>NumberTwo_Mbappe</div>
    <div>NumberOne</div>
    <div>NumberTwo_Ronaldo</div>
    <div>NumberTwo_Messi</div>
</div>

</body>
</html>

获取XPath结果的代码

运行下面的代码将从上面的html返回一个迭代器。

let xpathIterator = new XPathEvaluator()
                        .createExpression("//*[starts-with(text(), 'NumberTwo')]")
                        .evaluate(
                            document, 
                            XPathResult.ORDERED_NODE_ITERATOR_TYPE
                        );

提取第n项的现有迭代器方案

现有的XPathResult接口只有一个iterateNext()方法,因此需要六行代码来提取第n项:

let n = 3;
while (n > 0) { 
    xpathIterator.iterateNext(); 
    n--; 
}
xpathIterator.iterateNext();

提取第n项的理想数组方案

由于XPath和Chrome每天有数百万人使用,理想情况下,应该有一种方法可以直接使用数组索引获取第n个条目(如下面的代码所示)。如果这样的API还不存在,我会感到惊讶。

let v = xpathResult[2];

理想的解决方案不一定需要使用XPathExpression.evaluate()。我对任何使用Chrome支持的标准JavaScript函数的解决方案持开放态度。
(希望我们不需要使用函数。如果必须使用函数,则最好不要超过2到3行ESLint代码。)
谢谢!

相关文章

由于XPathResult.resultType不是一个可迭代对象,因此以下文章不适用:

oogrdqng

oogrdqng1#

把这个注入到控制台:

document.querySelector(".wikitable >  tbody").children[6];
epggiuax

epggiuax2#

如何使用CssSelector获取三个“NumberTwo”节点?在获得三个节点之后,如何直接访问第三个节点(“Messi”节点)?顺便说一下,这五个文本节点不一定位于<ul><li>中,它们同样有可能被<ol><li><table><tr>包裹。
给定您在编辑中显示的HTML,如下所示:

const allNodes = Array.from(document.querySelectorAll(`ul li, ol li, table tr`))
const allNumberTwoNodes = allNodes.filter(e =>
                              e.textContent.includes(`NumberTwo`)
                          );
console.log(allNumberTwoNodes);
<html>
  <body>
    <ul>
      <li>NumberOne</li>
      <li>NumberTwo_Mbappe</li>
      <li>NumberOne</li>
      <li>NumberTwo_Ronaldo</li>
      <li>NumberTwo_Messi</li>
    </ul>

    <ol>
      <li>NumberOne</li>
      <li>NumberTwo_Mbappe</li>
      <li>NumberOne</li>
      <li>NumberTwo_Ronaldo</li>
      <li>NumberTwo_Messi</li>
    </ol>
    
    <table>
      <tr><td>NumberOne</td></tr>
      <tr><td>NumberTwo_Mbappe</td></tr>
      <tr><td>NumberOne</td></tr>
      <tr><td>NumberTwo_Ronaldo</td></tr>
      <tr><td>NumberTwo_Messi</td></tr>
    </table>
  </body>
</html>

在这里,我们依赖于textContent,它为我们提供了忽略标记的节点的文本内容(毫不奇怪),这就是为什么即使这些表行具有表数据单元格,<tr>的textContent也为我们提供了一个字符串,就好像<td>标记不存在一样。
此外,“NumberTwo”节点不一定是第2、第4和第5节点;它们同样可能位于1-2-5或1-4-5或3-4-5位置。
查询选择器,就像XPath一样,不关心HTML的顺序,它会找到“匹配的东西”,而不是“第x个位置的东西”(除非你像XPath一样将子位置烘焙到选择器中)。

相关问题