Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Selenium通过Xpath返回错误的元素进行查找_Java_Html_Selenium_Xpath_Xquery - Fatal编程技术网

Java Selenium通过Xpath返回错误的元素进行查找

Java Selenium通过Xpath返回错误的元素进行查找,java,html,selenium,xpath,xquery,Java,Html,Selenium,Xpath,Xquery,我试图从HTML表格中显示的一系列频道中选择一个频道。我使用以下Selenium方法来选择链接 WebElement channel=driver.findElement(By.xpath(//span[contains(text(),Sales)]); channel.click(); 但是,它选择了列表中的第一个频道(帐户管理)。我希望它要么选择正确的通道,要么抛出错误,而不是选择错误的通道。以下是我想要的通道的完整xpath: /html/body/div[2]/div[2]/form/

我试图从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>

选择频道

您使用的xpath缺少
销售
文本周围的引号
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缺少
文本周围的引号
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();
希望这有帮助。

首先-你的错误! 您忘记了“Sales”周围的引号,只需稍微更改一下代码,它就会工作:

WebElement channel = driver.findElement(By.xpath("//span[contains(text(),'Sales')]"));
channel.click();
第二个xpath错误? 您是对的,这很奇怪,您没有收到错误消息,而是收到了第一个元素,即跨度。 这可能是xpath中的一个错误。contains函数意识到第二个参数不是字符串,但它不是返回false,而是返回true

它实际上击中了所有三个跨度项目。由于使用了
findElement
函数,因此只能得到第一个结果

试试这个,你会发现其中的怪癖:

System.out.println(driver.findElements(By.xpath("//span[contains(text(),Sales)]")).size());
结果将是:

三,

第三,可能是“按设计” 查看以下行:

如果$arg2的值是长度为零的字符串,则函数 返回true

然后在屏幕上,您将发现另一个有趣的谜题提示:

如果参数不是string类型,则首先将其转换为 字符串,然后进行求值

我想,把所有这些信息放在一起,xpath会将非字符串/非变量的第二个参数解释为空字符串,因此会为所有span元素返回true,因为您正在搜索
//span

更新 我们从@MichaelKay的评论中了解到,我的“猜测”非常接近:


在XPath和XQuery中,像“hello”这样的简单名称意味着child::hello和 如果您没有使用模式感知,那么系统只需查看 对于称为hello的孩子,如果没有,它将返回一个 空节点集

结论:OP看到的行为是设计好的,尽管看起来很不直观。

首先-你的错误! 您忘记了“Sales”周围的引号,只需稍微更改一下代码,它就会工作:

WebElement channel = driver.findElement(By.xpath("//span[contains(text(),'Sales')]"));
channel.click();
第二个xpath错误? 您是对的,这很奇怪,您没有收到错误消息,而是收到了第一个元素,即跨度。 这可能是xpath中的一个错误。contains函数意识到第二个参数不是字符串,但它不是返回false,而是返回true

它实际上击中了所有三个跨度项目。由于使用了
findElement
函数,因此只能得到第一个结果

试试这个,你会发现其中的怪癖:

System.out.println(driver.findElements(By.xpath("//span[contains(text(),Sales)]")).size());
结果将是:

三,

第三,可能是“按设计” 查看以下行:

如果$arg2的值是长度为零的字符串,则函数 返回true

然后在屏幕上,您将发现另一个有趣的谜题提示:

如果参数不是string类型,则首先将其转换为 字符串,然后进行求值

我想,把所有这些信息放在一起,xpath会将非字符串/非变量的第二个参数解释为空字符串,因此会为所有span元素返回true,因为您正在搜索
//span

更新 我们从@MichaelKay的评论中了解到,我的“猜测”非常接近:


在XPath和XQuery中,像“hello”这样的简单名称意味着child::hello和 如果您没有使用模式感知,那么系统只需查看 对于称为hello的孩子,如果没有,它将返回一个 空节点集


结论:OP看到的行为是设计好的,尽管看起来很不直观。

xpath需要修改为“//span[contains(text(),'Sales')]”

正如我们在下面的方法定义中所看到的,只有当第二个参数也是文本时,contains方法才会返回true

资料来源:

包含(s1、s2) 如果s1包含s2,则返回true。 正文()
查找text类型的节点

xpath需要修改为“//span[contains(text(),'Sales')]”

正如我们在方法d中看到的