selenium - 产生相同结果的 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 中,并没有提到初始上下文节点。
那么,是否意味着如果我们不提及初始上下文节点,那么它会(/)
默认设置为文档根节点吗?
请帮助提高我的理解。
解决方案
从“上下文”的角度来看,您的 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)
}
这里有几个值得注意的点:
- 尽管我们的文件有 root
A
,但浏览器会自动添加 html 标签以使 html 文件有效。所以它添加了html
节点和body
节点 - 考虑到上一点,我们从访问
html/body/A
具有root
上下文的 - 然后我们确保我们找不到
B
使用路径body/A/B
,因为上下文仍然是root
. - 然后我们可以看到,我们可以
B
在先前定位的上下文中找到A
。 - 最后一件事是我们
/html/body/A
在B
. 尽管我们使用B
as 搜索上下文,但我们仍然可以找到元素,因为我们从路径开始/
意味着root
并忽略任何搜索上下文。
推荐阅读
- android - 在android中的LinearLayout之间进行分隔的最佳方法是什么?
- c# - 在wpf C#中单击按钮时如何禁用其他功能
- c# - 使用 LINQ 展平树以获得最深的价值
- gradle - 使用多个模块将快照发布到 oss.jfrog.org 失败并显示 403
- c# - 如何打开 IObservable
> 进入 IObservable ? - reactjs - 使用 let 重新分配 React Components 属性值
- jupyter-notebook - Jupyter Object_Detection_Tutorial 的问题 - 导入 win32api 时 DLL 加载失败
- javascript - 自动关闭“fs.createWriteStream()”以避免潜在的内存泄漏
- graphql - 在 AWS AppSync 中为 SQL 查询字符串化 JSON 对象
- javascript - 通过 props 传递 react-redux 存储和调度功能?