我正在写一个 Selenium 测试用例。这是我用来匹配数据表中所有“修改”按钮的 xpath 表达式。
//img[@title='Modify']
我的问题是,如何按索引访问匹配的节点集?我试过了
//img[@title='Modify'][i]
和
//img[@title='Modify' and position() = i]
但两者都不起作用..我也尝试过使用 XPath 检查器(一个 firefox 扩展)。总共找到 13 个匹配项,然后我完全不知道如何选择其中一个。或者 XPath 是否支持指定选择不在同一个父节点下的节点?
这是一个常见问题解答:
//someName[3]
表示:文档中的所有 someName
元素,它们是其父级的第三个 someName
子级 - 可能有很多这样的元素。
您想要的正是第三个 someName
元素:
(//someName)[3]
解释:[]
的优先级(优先级)高于 //
。当您需要指定所选节点列表的第 N 个节点时,请记住始终将 //someName
类型的表达式放在括号中。
XPath 中没有 i
。
您要么使用文字数字://img[@title='Modify'][1]
或者您动态构建表达式字符串:'//img[@title='Modify']['+i+']'
(但请记住,动态 XPath 表达式在 within XSLT 中不起作用)。
或者 XPath 是否支持指定选择不在同一个父节点下的节点?
是:(//img[@title='Modify'])[13]
此 //img[@title='Modify'][i]
表示“任何具有“修改”标题和名为 <i>
的子元素的 <img>
。
tr
的第六个子元素且没有空内容的 td
://tr/td[6][string-length(text()) > 0]
xpath 中没有 i
并不完全正确。您仍然可以使用 count()
来查找索引。
考虑以下页面
标题 1 | 标题 2 | 标题 3 | 标题 4< /th> | 标题 5 | 标题 6 |
---|---|---|---|---|---|
数据行 1 col 1 | 数据行 1 col 2 | 数据行 1 col 3 | 数据行 1 col 4 | 数据行 1 col 5 | 数据行1 col 6 |
数据行 2 col 1 | 数据行 2 col 2 | 数据行 2 col 3 | 数据行 2 col 4 | 数据行 2 col 5 | 数据行 2 col 6 |
数据行 3 col 1 | 数据行 3 col 2 | 数据行 3 col 3 | 数据行 3 col 4 | 数据行 3 col 5< /td> | 数据行 3 col 6 |
数据行 4 col 1 | 数据行 4 col 2 | 数据第 4 行第 3 列 | 数据第 4 列第 4 列 | 数据第 4 列第 5 列 | 数据第 4 列第 6 列 |
数据行 5 col 1 | 数据行 5 col 2 | 数据行 5 col 3 | 数据行 5 col 4 | < td>数据行 5 col 5数据行 5 col 6< /td> | |
标题 7 | 标题 8 | 标题 9 th> | 标题 10 | 标题 11 | 标题 12 |
---|---|---|---|---|---|
数据行 1 列1 | 数据行 1 col 2 | 数据行 1 col 3 | 数据行 1 col 4 | 数据行 1 col 5< /td> | 数据行 1 col 6 |
数据行 2 col 1 | 数据行 2 col 2 | 数据第 2 行第 3 列 | 数据第 2 列第 4 列 | 数据第 2 列第 5 列 | 数据第 2 列第 6 列 |
数据行 3 col 1 | 数据行 3 col 2 | 数据行 3 col 3 | 数据行 3 col 4 | < td>数据行 3 col 5数据行 3 col 6 | |
数据行 4 col 1 | 数据行 4 col 2 | 数据行 4 col 3 | 数据行w 4 col 4 | 数据行 4 col 5 | 数据行 4 col 6 |
数据行 5 col 1 | 数据行 5 col 2 | 数据行 5 col 3 | 数据行 5 col 4 | 数据行 5 col 5 | < td>数据行 5 col 6|
该页面有 2 个表,每列有 6 列,每列都有唯一的列名,6 行有可变数据。最后一行在两个表中都有 Modify
按钮。
假设用户必须根据标题从第一个表中选择第四个 Modify
按钮
使用 xpath //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button
count()
运算符在此类情况下会派上用场。
逻辑:
使用 //th[.='Heading 4'] 查找 Modify 按钮的标题 使用 count(//tr/th[.='Heading 4']/preceding-sibling::th) 查找标题列的索引+1
注意:索引从 0 开始
使用 //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4' ]/preceding-sibling::th)+1] 使用 //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[ 从提取的节点列表中获取修改按钮count(//tr/th[.='标题 4']/preceding-sibling::th)+1]/button
td[count(../preceding-sibling::tr/th[.='Heading 4'])]/following-sibling::td
时不属于 td[1]
:)
//img[@title='Modify'][i]
简称
/descendant-or-self::node()/img[@title='Modify'][i]
因此返回同一父节点下的第 i 个节点。
你要
/descendant-or-self::img[@title='Modify'][i]
/descendant::img[@title='Modify'][$index]
即可。另请注意,[i]
谓词测试是否存在 i
子元素。
(//*[@attribute='value'])[index] 查找元素的目标,同时在其中找到多个匹配项
这是索引变量的解决方案
假设您找到了 5 个具有相同定位器的元素,并且您希望通过提供索引号对每个元素执行操作(此处,变量用于索引为“i”)
for(int i=1; i<=5; i++)
{
string xPathWithVariable = "(//div[@class='className'])" + "[" + i + "]";
driver.FindElement(By.XPath(xPathWithVariable)).Click();
}
它需要 XPath :
(//div[@class='className'])[1]
(//div[@class='className'])[2]
(//div[@class='className'])[3]
(//div[@class='className'])[4]
(//div[@class='className'])[5]
不定期副业成功案例分享
index values in XPath predicates (technically, 'proximity positions' of XPath node sets) start from 1
,而不是像 C 和 Java 这样的语言中常见的 0。”