我有像
这样的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':字符串'//h1/../.[contains(@class,'open')]'不是有效的XPath表达式。
在Firefox控制台中使用相同的Xpath进行搜索,可以成功找到该元素。
WebDriver认为此xpath无效的任何想法?
注意:我的例子当然是简化的
答案 0 :(得分:2)
我想说可能低至the specification没有明确说明是否应该允许缩写步骤之后的谓词,即.
和..
,规范曾提到一个涉及缩写步骤之后的谓词的例子。
因此一些XPath实现不支持它。我注意到其中一个是.NET框架中的XPath实现。其他实现明确禁止它,甚至为用户提供有用的建议,以使用等效的未缩写表达式替换其XPath中的.
或..
,按顺序self::node()
或parent::node()
例如,xpathtester使用的实现。但正如您所注意到的,其他实现可能会支持它。
从解决方法来看,有许多替代XPath,它们与您原始尝试的XPath相当或足够接近。最简单的是将.
扩展为其未缩写的表达式,如上所述。就个人而言,如果可能的话,我宁愿不下树然后再回来返回父元素。相反,只需停止我们想要返回的父元素,并检查谓词中的子元素:
//*[contains(@class, 'open')][h1]
答案 1 :(得分:1)
如果要引用“div”相对于“h1”标记,则可以将xpath更改为以下内容:
//h1/ancestor::div[contains(@class, 'open')]
答案 2 :(得分:0)
您可以尝试//h1/../.[contains(@class, 'open')]
xpath
//div[@class='open']
xpath