Как выбрать указанный node внутри Xpath node устанавливает по индексу с Selenium?

Я пишу тест Selenium. И вот выражение xpath, которое я использую, чтобы сопоставить все кнопки "Изменить" в таблице данных.

//img[@title='Modify']

Мой вопрос: как я могу подобрать сопоставленные node наборы по индексу? Я пробовал с помощью

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

и

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

Но не работает. Я также пробовал с XPath checker (One firefox extension). Всего найдено 13 совпадений, тогда я понятия не имею, как выбрать один из них. Или XPath поддерживает указанный выбор узлов, которые не находятся под одним и тем же родителем node?

Ответ 1

Это FAQ:

//someName[3]

означает: все someName элементы в документе, которые являются третьим дочерним элементом someName их родителя - может быть много таких элементов.

То, что вы хотите, - это как раз третий элемент someName:

(//someName)[3]

Объяснение: [] имеет более высокий приоритет (приоритет), чем //. Помните, всегда нужно помещать выражения типа //someName в скобки, когда вам нужно указать Nth node их выбранного node -list.

Ответ 2

В XPath нет i.

Либо вы используете литеральные числа: //img[@title='Modify'][1]

Или вы строит строку выражения динамически: '//img[@title='Modify']['+i+']' (но имейте в виду, что динамические выражения XPath не работают из XSLT).

Или XPath поддерживает указанный выбор узлов которые не находятся под одним и тем же родителем node?

Да: (//img[@title='Modify'])[13]


Этот //img[@title='Modify'][i] означает "any <img> с названием" Modify "и дочерним элементом с именем <i>."

Ответ 3

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

не подходит для

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

следовательно, возвращает i'th node под одним и тем же родителем node.

Вы хотите

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

Ответ 4

(//* [@атрибут = 'значение']) [индекс] найти цель элемента, пока вы найдете несколько совпадений в нем

Ответ 5

Нет i в xpath не совсем верно. Вы все еще можете использовать 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>

Ответ 6

Вот решение для индексной переменной

Допустим, вы нашли 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]