XPath查找子元素的父元素

5

我有这样一个结构:

<div class="Container">
  <div class="HighlightContainer">
    <div class="NodeTextHighlightContainer">
      <span class="TreeItemSelected">Products</span>
    </div>
    <button class="ContainerSelectedMenu" type="button"></button>
  </div>
</div>

由于DOM的行为以及尝试保持动态性,我只能针对包含“Products”文本的span元素进行定位,例如:
Driver.FindElement(By.XPath("//div[contains(@class, 'Container')]/descendant::span[text() = 'Products']"));

然而,我需要针对具有 class="ContainerSelectedMenu" 的按钮进行定位,并基于该 span 元素,最好的方法是什么?类似于获取子容器的父 div,然后查找按钮元素。

我完全没有经验,但是 .. 不是用于选择父级吗? - Hawk
2个回答

11

我已经找到了不同的方式,通过向上和向下遍历来完成这个任务,这种方法也可以很好地工作,但现在我的首选是这种方法:

xpath = "//div[contains(@class, 'Container') and descendant::span[text() = 'Products']]//button";

基本上,您将后代与text()='Products'作为所需的一部分放置在父标签div中。然后,您可以使用//button或者//button[@class='ContainerSelectedMenu']轻松查找按钮。

实际上,在这里不需要descendant轴,因此可以通过以下方式简化:

xpath = "//div[contains(@class, 'Container') and .//span[text() = 'Products']]//button";

在英语中...

  • 找到一个 div
  • 1. 它有一个包含 "Container" 的 @class 属性,并且
  • 2. 它拥有一个名为 `Products` 的 span 元素。
  • 找到该 div 的后代并且是一个 button 元素。

2
我认为你需要在 //span 前面加上 . (即 .//span),这样它就从当前上下文开始了。 - Daniel Haley
@DanielHaley 听起来对我没错,我会编辑的,谢谢! - mrfreester
很棒的解释,这帮了很多忙。 - saltillokid11

3

一种方法是针对 span 元素,然后向上找到祖先元素 div,再返回到具有匹配的 class 属性的元素...

//span[normalize-space()='Products']/ancestor::div[contains(@class,'Container')]//*[contains(@class,'ContainerSelectedMenu')]

另一种方法是先定位到 div,再定位到 span,然后向上回溯两级,最后再返回到具有匹配 class 的元素...
//div[contains(@class,'Container')]//span[normalize-space()='Products']/../../*[contains(@class,'ContainerSelectedMenu')]

另一种方法(类似于 @mrfreester 的方法)是匹配 div,测试 span,并直接转到具有匹配 class 的元素...
//div[contains(@class, 'Container') and .//span[normalize-space()='Products']]//*[contains(@class,'ContainerSelectedMenu')]

所有这些都与button匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接