在Selenium Java中调用XPath count函数报错,如何获取聚合值?
解决Selenium中XPath聚合函数无法返回值的问题
问题
我尝试用Selenium的XPath,根据<tr>下<td>的内容获取该<tr>的索引,写了这段Java代码:
String xpath = "count(//tr[td[text()='Column Value A'] and td[text()='Column Value B']]/preceding-sibling::*)"; WebElement count = driver.findElement(By.xpath(xpath));
但运行时抛出异常:
org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression count(//tr[td[text()='Column Value A'] and td[text()='Column Value B']]/preceding-sibling::*) because of the following error: TypeError: Failed to execute 'evaluate' on 'Document': The result is not a node set, and therefore cannot be converted to the desired type.
为什么会报错?
Selenium的findElement()和findElements()方法只能返回DOM节点或者节点集合,而count()这类XPath聚合函数返回的是数值类型,不符合方法的返回要求,所以直接调用会抛出异常。
两种解决方法
方法1:用JavascriptExecutor执行XPath获取数值
通过JavaScript调用原生的document.evaluate方法,指定返回数值类型,就能直接拿到count()的计算结果:
String xpathExpr = "count(//tr[td[text()='Column Value A'] and td[text()='Column Value B']]/preceding-sibling::*)"; JavascriptExecutor js = (JavascriptExecutor) driver; Long precedingRowCount = (Long) js.executeScript( "return document.evaluate(arguments[0], document, null, XPathResult.NUMBER_TYPE, null).numberValue;", xpathExpr ); // 若需要从1开始的索引,给结果加1即可 int targetRowIndex = precedingRowCount.intValue() + 1; System.out.println("目标行索引:" + targetRowIndex);
方法2:先定位目标行,再统计前置兄弟元素数量
先找到符合条件的<tr>元素,再用findElements()获取它所有的前置兄弟<tr>,集合的大小就是前置元素的数量:
// 先定位目标<tr> WebElement targetRow = driver.findElement(By.xpath("//tr[td[text()='Column Value A'] and td[text()='Column Value B']]")); // 获取目标行的所有前置兄弟<tr> List<WebElement> precedingRows = driver.findElements(By.xpath("//tr[td[text()='Column Value A'] and td[text()='Column Value B']]/preceding-sibling::tr")); // 前置元素数量是从0开始的索引,加1得到从1开始的索引 int targetRowIndex = precedingRows.size() + 1; System.out.println("目标行索引:" + targetRowIndex);
内容的提问来源于stack exchange,提问作者Dili
相关产品推荐
相关产品推荐

