我有html喜欢
<html>
<body>
<div class='open'>
<h1>Title</h1>
<div>Opened</div>
</div>
</body>
</html>
在我的Selenium WebDriver 3测试中,我试图使用以下xpath选择div.open元素:
//h1/../.[contains(@class, 'open')]
在c#中的以下命令中:
driver.FindElement(By.XPath("//h1/../.[contains(@class, 'open')]"));
结果如何
OpenQA.Selenium.InvalidSelectorException:无效的选择器:无法找到具有xpath表达式的元素//h1/../.[contains(@class,'open')],因为以下错误::无法在'Document'上执行'evaluate': string '//h1/../.[contains(@class, ' open ')]' is not a valid XPath expression.
在Firefox控制台中使用相同的Xpath进行搜索,可以成功找到该元素 .
任何想法为什么WebDriver认为这个xpath无效?
注意:我的例子当然是简化的
3 回答
我想说可能是the specification可能没有明确说明是否应该允许缩写步骤之后的谓词,即
.
和..
,规范都没有提到缩写步骤后涉及谓词的例子 .所以一些XPath实现只是不支持它 . 我注意到其中一个是.NET框架中的XPath实现 . 其他实现明确禁止它,甚至为用户提供有用的建议,以便在其XPath中使用等效的未缩写表达式替换
.
或..
,依次为self::node()
或parent::node()
,例如xpathtester使用的实现 . 但正如您所注意到的,其他实现可能会支持它 .解决方法是,XPath有许多替代方法,它们与您原始尝试的XPath相当或足够接近 . 最简单的是将
.
扩展为其未缩写的表达式,如上所述 . 就个人而言,如果可能的话,我宁愿不下树然后再回来返回父元素 . 相反,只需停止我们想要返回的父元素,并检查谓词中的子元素:如果要引用“div”相对于“h1”标记,则可以将xpath更改为以下内容:
而不是
//h1/../.[contains(@class, 'open')]
xpath
你可以尝试//div[@class='open']
xpath