找到带有文本的元素,然后 Select 元素在它上面很多层

Find Element with Text, then Select Element Many Levels Above it

我正在制作一个 chrome 扩展程序,用于删除网站的一部分。为此,我需要找到一个包含一些文本的 <span>,然后是 select 包含 <div> 的标签。通常此标签会比 DOM 中的跨度高很多级别,并且它与 select by.

没有一致的属性

HTML

<body>
  <div> <!-- I want to select this DIV -->
    <div>
        <div>
            <div>
                <span>some text</span>
             </div>
         </div>
    </div>
  </div>
</body>

我已经使用 //span[text() = 'some text' 找到了正确的 <span> 但现在我需要回到示例中的第一个 <div> HTML

已尝试 //*[ancestor::span[text() = 'some text']]//span[ancestor::*[text() = 'some text']]。是的,这些只会上升到第一个 parent,但这对我来说甚至不起作用,即使当我在 XPath Tester.

上测试时它们作为有效的 XPath 表达式出现

编写可以执行此操作的 XPath 表达式的最简单方法是什么?

您可以尝试使用 ../ 语法向上一级(即:到直接父级)并像这样链接它们:

const getnodes=function( expr, parent ){
        let results=[];
        let contextNode=parent || document;
        let query=document.evaluate( expr, contextNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
        for ( let i=0, length=query.snapshotLength; i < length; ++i ) {
            results.push( query.snapshotItem( i ) );
        }
        return results;
    };
  
  let col=getnodes( '//span[ text()="some text" ]/../../../../../div', document.body );
  col.forEach( n=>console.info( n.textContent ) )
<!--This is the div I want to select -->
  <div>top
    <div>a
        <div>b
            <div>c
                <span>some text</span>
             </div>
         </div>
    </div>
  </div>

我发现一个更好的解决方案是在 XPath 查询中使用 ancestor,因为我经常想向上遍历许多级别。

例子

//span[text() = 'some text']/ancestor::*[4]

从所选范围中选择第四个元素,无论这些元素可能是什么类型。

//span[text() = 'some text']/ancestor::a[2]

将找到所选跨度向上的第二个锚标记,前提是它是跨度的直接上级。