问题描述
我试图根据元素div的后代文本节点定位。
以下是HTML:
<html><head></head><body>
<div>
<div class="d x">Foo</div>
<span>Mumbai</span>
<h1>DEF</h1>
</div>
</body></html>
硒代码:
driver.findElement(By.xpath("//div[.='FooMumbaiDEF']"));
根据我的理解,并参考了stackoverflow帖子之后, Testing text() nodes vs string values in XPath 元素节点的字符串值是元素节点的所有文本节点后代按文档顺序的字符串值的串联。
但是我得到NoSuchElementException: Unable to locate element: //div[.='FooMumbaiDEF']
知道为什么找不到元素吗?
解决方法
//div[.='FooMumbaiDEF']
是无效的XPath,如果您想根据其文本处理Web元素,则可以在Xpath表达式中使用 contains()函数,该函数用于搜索Web包含特定文本的元素。
尝试在xpath下处理网页中的Foo文本:
driver.findElement(By.xpath("//div[contains(text(),'Foo')]"));
,
尝试使用xpath,因为您使用的不正确。
driver.findElement(By.xpath("//div[contains(text(),'FooMumbaiDEF')]"));
,
按照HTML:
<html>
<head>
</head>
<body>
<div>
<div class="d x">Foo</div>
<span>Mumbai</span>
<h1>DEF</h1>
</div>
</body>
</html>
没有类似的后代文本节点。但是存在带有 text 的后代<div>
,<span>
和<h1>
节点。
解决方案
要相对于后代<div>
,<div>
和<span>
节点中的文本标识父<h1>
元素,可以使用以下{{3} }基于xpath:
-
使用后代
<div>
:driver.findElement(By.xpath("//div[./div[text()='Foo']]"));
-
使用后代
<div>
:driver.findElement(By.xpath("//div[./span[text()='Mumbai']]"));
-
使用后代
<div>
:driver.findElement(By.xpath("//div[./h1[text()='DEF']]"));
理想情况下,您需要为visibilityOfElementLocated()
引入Locator Strategies,并且可以使用以下任意一种 locator策略
-
使用后代
<div>
:new WebDriverWait(driver,20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./div[text()='Foo']]")))
-
使用后代
<div>
:new WebDriverWait(driver,20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./span[text()='Mumbai']]")))
-
使用后代
<div>
:new WebDriverWait(driver,20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./h1[text()='DEF']]")))
首先运行$x("//div/descendant::text()")
,以检查div
元素的所有后代文本节点。它显示了七个后代文本节点。因此,它包含四个文本节点,其数据为\n
(即换行字符),以及以上三个文本节点,即Foo
,Mumbai
和DEF
。
因此,用于选择上述div
节点的Xpath表达式应为:
$x("//div[.='\nFoo\nMumbai\nDEF\n']")