[英]Selenium Find By Xpath returning the wrong element
我正在嘗試從HTML表格中顯示的一系列通道中選擇一個通道。 我正在使用以下硒方法選擇鏈接
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>
您忘記了“銷售”兩邊的引號,只需稍微更改一下代碼即可使用:
WebElement channel = driver.findElement(By.xpath("//span[contains(text(),'Sales')]"));
channel.click();
您是對的,這很奇怪,您沒有收到錯誤消息,而是第一個元素是span。 這可能實際上是xpath中的錯誤。 contains函數實現了您的第二個參數不是字符串,而是返回true而不是返回false 。
它實際上擊中了所有三個跨度項。 結果只有第一個,因為您使用了findElement
函數。
試試這個,你會看到這個怪癖:
System.out.println(driver.findElements(By.xpath("//span[contains(text(),Sales)]")).size());
結果將是:
3
看一下w3c定義,您會發現以下行:
如果$ arg2的值是零長度的字符串,則該函數返回true。
然后,在Microsoft的xpath站點上,您將找到另一個有趣的提示:
如果參數不是字符串類型,則首先將其轉換為字符串,然后求值。
我猜想,將所有這些信息放在一起,xpath會將您的非字符串/不變的第二個參數解釋為空字符串,因此自從您搜索//span
以來,所有span元素都返回true。
從@MichaelKay在我們學到的評論中,我的“猜測”非常接近:
在XPath和XQuery中,像“ hello”這樣的裸名意味着child :: hello,如果您不使用模式識別,那么系統將只查找稱為hello的子級,如果沒有,則它將返回一個空的節點集。
結論:OP所看到的行為是設計好的,即使它看起來很不直觀。
您使用的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();
希望這可以幫助。
xpath需要修改為“ // span [contains(text(),'Sales')]”“。
正如我們在下面的方法定義中看到的那樣,contains方法僅在第二個參數也是文本時才返回true。
資料來源: https : //en.wikipedia.org/wiki/XPath
如果s1包含s2,則contains(s1,s2)返回true。 text()查找text類型的節點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.