如何使用Selenium通过索引选择Xpath节点集中的指定节点?

问题描述 投票:74回答:5

我正在写一个Selenium测试用例。这是我用来匹配数据表中所有“修改”按钮的xpath表达式。

//img[@title='Modify']

我的问题是,如何通过索引访问匹配的节点集?我试过了

//img[@title='Modify'][i]

//img[@title='Modify' and position() = i]

但是都不起作用..我也试过XPath checker(一个firefox扩展)。发现总共有13个匹配,然后我完全不知道如何选择其中一个..或者XPath是否支持指定选择不在同一父节点下的节点?

xpath selenium
5个回答
166
投票

这是一个FAQ:

//someName[3]

意思是:文件中的所有someName元素,即父母的第三个someName子元素 - 可能有许多这样的元素。

你想要的正是第3个someName元素:

(//someName)[3]

说明:[]的优先级(优先级)高于//。当您需要指定所选节点列表的第N个节点时,请记住始终将//someName类型的表达式放在括号中。


14
投票

XPath中没有i

要么使用文字数字://img[@title='Modify'][1]

或者您动态构建表达式字符串:'//img[@title='Modify']['+i+']'(但请记住,动态XPath表达式在XSLT中不起作用)。

或者XPath是否支持指定的不在同一父节点下的节点选择?

是的:(//img[@title='Modify'])[13]


这个//img[@title='Modify'][i]的意思是“任何带有'修改'标题的<img>和一个名为<i>的子元素。”


2
投票
//img[@title='Modify'][i]

是的缩写

/descendant-or-self::node()/img[@title='Modify'][i]

因此返回同一父节点下的第i个节点。

你要

/descendant-or-self::img[@title='Modify'][i]

1
投票

(// * [@ attribute ='value'])[index]查找元素的目标,同时找到多个匹配的元素


1
投票

xpath中没有i并不完全正确。您仍然可以使用count()查找索引。

请考虑以下页面

<html>
	<head>
	<style>
	table, td, th {
		border: 1px solid black;
		font-size: 15px;
		font-family: Trebuchet MS, sans-serif;
	}
	table {
		border-collapse: collapse;
		width: 100%;
	}

	th, td {
		text-align: left;
		padding: 8px;
	}

	tr:nth-child(even){background-color: #f2f2f2}

	th {
		background-color: #4CAF50;
		color: white;
	}
	</style>
	<table>
		<thead>
			<tr>
				<th>Heading 1</th>
				<th>Heading 2</th>
				<th>Heading 3</th>
				<th>Heading 4</th>
				<th>Heading 5</th>
				<th>Heading 6</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>Data row 1 col 1</td>
				<td>Data row 1 col 2</td>
				<td>Data row 1 col 3</td>
				<td>Data row 1 col 4</td>
				<td>Data row 1 col 5</td>
				<td>Data row 1 col 6</td>
			</tr>
			<tr>
				<td>Data row 2 col 1</td>
				<td>Data row 2 col 2</td>
				<td>Data row 2 col 3</td>
				<td>Data row 2 col 4</td>
				<td>Data row 2 col 5</td>
				<td>Data row 2 col 6</td>
			</tr>
			<tr>
				<td>Data row 3 col 1</td>
				<td>Data row 3 col 2</td>
				<td>Data row 3 col 3</td>
				<td>Data row 3 col 4</td>
				<td>Data row 3 col 5</td>
				<td>Data row 3 col 6</td>
			</tr>
			<tr>
				<td>Data row 4 col 1</td>
				<td>Data row 4 col 2</td>
				<td>Data row 4 col 3</td>
				<td>Data row 4 col 4</td>
				<td>Data row 4 col 5</td>
				<td>Data row 4 col 6</td>
			</tr>
			<tr>
				<td>Data row 5 col 1</td>
				<td>Data row 5 col 2</td>
				<td>Data row 5 col 3</td>
				<td>Data row 5 col 4</td>
				<td>Data row 5 col 5</td>
				<td>Data row 5 col 6</td>
			</tr>
			<tr>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
			</tr>
		</tbody>
	</table>

	</br>

	<table>
		<thead>
			<tr>
				<th>Heading 7</th>
				<th>Heading 8</th>
				<th>Heading 9</th>
				<th>Heading 10</th>
				<th>Heading 11</th>
				<th>Heading 12</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>Data row 1 col 1</td>
				<td>Data row 1 col 2</td>
				<td>Data row 1 col 3</td>
				<td>Data row 1 col 4</td>
				<td>Data row 1 col 5</td>
				<td>Data row 1 col 6</td>
			</tr>
			<tr>
				<td>Data row 2 col 1</td>
				<td>Data row 2 col 2</td>
				<td>Data row 2 col 3</td>
				<td>Data row 2 col 4</td>
				<td>Data row 2 col 5</td>
				<td>Data row 2 col 6</td>
			</tr>
			<tr>
				<td>Data row 3 col 1</td>
				<td>Data row 3 col 2</td>
				<td>Data row 3 col 3</td>
				<td>Data row 3 col 4</td>
				<td>Data row 3 col 5</td>
				<td>Data row 3 col 6</td>
			</tr>
			<tr>
				<td>Data row 4 col 1</td>
				<td>Data row 4 col 2</td>
				<td>Data row 4 col 3</td>
				<td>Data row 4 col 4</td>
				<td>Data row 4 col 5</td>
				<td>Data row 4 col 6</td>
			</tr>
			<tr>
				<td>Data row 5 col 1</td>
				<td>Data row 5 col 2</td>
				<td>Data row 5 col 3</td>
				<td>Data row 5 col 4</td>
				<td>Data row 5 col 5</td>
				<td>Data row 5 col 6</td>
			</tr>
			<tr>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
				<td><button>Modify</button></td>
			</tr>
		</tbody>
	</table>

	</head>
</html>

该页面有2个表,有6列,每列有唯一的列名,6行有可变数据。最后一行在两个表中都有Modify按钮。

假设用户必须根据标题从第一个表中选择第4个Modify按钮

使用xpath //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button

count()操作员在这样的情况下派上用场。

逻辑:

  1. 使用Modify找到//th[.='Heading 4']按钮的标题
  2. 使用count(//tr/th[.='Heading 4']/preceding-sibling::th)+1查找标题列的索引

注意:索引从0开始

  1. 使用//th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]获取相应标头的行
  2. 使用Modify从提取的节点列表中获取//th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button按钮
© www.soinside.com 2019 - 2024. All rights reserved.