首页 > 解决方案 > 产生相同结果的 3 个不同 Xpath 之间的差异

问题描述

我正在尝试定位元素<a>

HTML:

<html><head></head><body>
<a href="https://www.google.com">Click Here!</a>
</body></html>

下面是使用 Xpath 产生相同结果的 Selenium 代码:

driver.findElement(By.xpath("self::node()/child::node()/child::body/child::a")).click();    //Statement1
driver.findElement(By.xpath("/child::node()/child::body/child::a")).click();    //Statement2
driver.findElement(By.xpath("child::node()/child::body/child::a")).click(); //Statement3

我的理解:

在 Statement1 中,它将初始上下文节点称为self::node. 在这里,我们将整个HTMLDocument作为self::node(). 因此,我们的初始上下文节点设置为整个HTMLDocument(也称为文档根节点(/))。因此,我们的初始上下文节点设置为文档根节点(/)
在 Statement2 中,它绝对将初始上下文节点称为文档根节点(/)
但是在 Statement3 中,并没有提到初始上下文节点。

那么,是否意味着如果我们不提及初始上下文节点,那么它会(/)默认设置为文档根节点吗?

请帮助提高我的理解。

标签: seleniumxpath

解决方案


从“上下文”的角度来看,您的 1 和 3 语句是相同的(self并且child都是 xpath 轴)。两者都将文档的根作为上下文(在 Selenium 中称为SearchContext)。

在这种情况下,上下文是根,因为您在驱动程序中查找元素。如果您将有一个WebElement并尝试在该元素内查找元素,那么您的上下文将不适root用于 1 和 3 语句。

下面是一些更详细的解释..

假设我们有test.html以下内容:

<A val="success A">
  <B val="success B"/>
</A>

像这样的测试:

@Test
public void test(){
    driver.get("file:///path_to_page/test.hml");
    WebElement a = driver.findElement(By.xpath("html/body/A")); // (1, 2)
    System.out.println(a.getAttribute("val"));
    try{
        System.out.println(driver.findElement(By.xpath("body/A/B")).getAttribute("val")); // (3)
    }catch (NoSuchElementException e){
        System.out.println("body/A/B cannot be found as the context is root");
    }
    WebElement b = a.findElement(By.xpath("B")); // (4)
    System.out.println(b.getAttribute("val"));
    System.out.println(b.findElement(By.xpath("/html/body/A")).getAttribute("val")); // (5)
}

这里有几个值得注意的点

  1. 尽管我们的文件有 root A,但浏览器会自动添加 html 标签以使 html 文件有效。所以它添加了html节点和body节点
  2. 考虑到上一点,我们从访问html/body/A具有root上下文的
  3. 然后我们确保我们找不到B使用路径body/A/B,因为上下文仍然是root.
  4. 然后我们可以看到,我们可以B在先前定位的上下文中找到A
  5. 最后一件事是我们/html/body/AB. 尽管我们使用Bas 搜索上下文,但我们仍然可以找到元素,因为我们从路径开始/意味着root并忽略任何搜索上下文。

推荐阅读