我正在尝试从HTML表格中显示的一系列频道中选择一个频道。我正在使用以下Selenium方法来选择链接
WebElement channel = driver.findElement(By.xpath("//span[contains(text(),Sales)]"));
channel.click();
然而,它正在选择列表中的第一个频道(帐户管理)。我希望它会选择正确的通道或抛出错误,而不是选择错误的通道。以下是我想要的频道的完整xpath:
/html/body/div[2]/div[2]/form/div/table/tbody[2]/tr/td/ul/li[2]/a/span
频道列表在HTML代码中定义如下:
<form action="nextpage.do" method="post" name="selectChannelForm">
<div class="de">
<h2>Select channel</h2>
<table id="selectChannelForm">
<tbody id=""></tbody>
<tbody id="">
<tr rowtype="container">
<td class="desecond" colspan="3">
<ul>
<li>
<a id="selected_a" href="nextpage.do?selectedChannel=123">
<span>Account Management</span></a>
</li>
<li>
<a id="selected_a" href="nextpage.do?selectedChannel=456">
<span>Sales</span></a>
</li>
<li>
<a id="selected_a" href="nextpage.do?selectedChannel=789">
<span>Complaints</span></a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
<input type="hidden" value="selectChannelForm" name="formid">
</div>
答案 0 :(得分:2)
您忘记了“销售”周围的引号,只需更改一下代码就可以了:
WebElement channel = driver.findElement(By.xpath("//span[contains(text(),'Sales')]"));
channel.click();
你是对的很奇怪,你没有得到错误信息,而是第一个元素是一个跨度。 这可能是xpath中的一个错误。 contains函数意识到你的第二个参数不是字符串,但它不是返回 false ,而是返回 true 。
它实际上击中了所有三个跨度项目。因为您使用了findElement
函数,所以只能获得第一个结果。
试试这个,你会看到怪癖:
System.out.println(driver.findElements(By.xpath("//span[contains(text(),Sales)]")).size());
结果将是:
3
看一下w3c definition,你会发现以下一行:
如果$ arg2的值是零长度字符串,那么该函数 返回true。
然后在xpath-site of microsoft上你会发现另一个有趣的暗示:
如果参数不是string类型,则首先将其转换为a 字符串,然后评估。
将所有这些信息放在一起,我想,xpath将非字符串/非变量第二个参数解释为空字符串,因此在搜索//span
以来所有span元素都返回true。
来自@MichaelKay的评论我们得知,我的“猜测”非常接近:
在XPath和XQuery中,像“hello”这样的裸名称表示child :: hello,和 如果你没有使用模式感知,那么系统只会看 对于叫做你好的孩子,如果没有,它会返回一个 空节点集。
结论:OP看到的行为与设计一致,即使它看起来非常不直观。
答案 1 :(得分:1)
您正在使用的xpath缺少""
文本周围的引号Sales
。 text()
函数接受一个字符串参数,并且可以使用引号形成字符串。以下列方式更新xpath -
driver.findElement(By.xpath("//span[contains(text(),'Sales')]")).click();
或者,如果您想将其分配给WebElement,请填写引号 -
WebElement channel = driver.findElement(By.xpath("//span[contains(text(),'Sales')]"));
channel.click();
如果您想要编写嵌套双引号或嵌套单引号,则使用转义字符\
来编写它。这是如何 -
WebElement channel = driver.findElement(By.xpath("//span[contains(text(),\"Sales\")]"));
channel.click();
希望这有帮助。
答案 2 :(得分:1)
需要将xpath修改为“// span [contains(text(),'Sales')]”。
正如我们在下面的方法定义中看到的那样,contains方法只返回true如果第二个参数也是文本。
来源:https://en.wikipedia.org/wiki/XPath
包含(s1,s2) 如果s1包含s2,则返回true。 文本() 找到text类型的节点