Как выбрать указанный 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]