Ich schreibe einen Selenium-Testfall. Und hier ist der xpath-Ausdruck, den ich verwende, um alle 'Modify'-Schaltflächen in einer Datentabelle abzugleichen.
//img[@title='Modify']
Meine Frage ist, wie kann ich die übereinstimmenden Knotensätze nach Index aufrufen? Ich habe es mit versucht
//img[@title='Modify'][i]
und
//img[@title='Modify' and position() = i]
Aber beides funktioniert nicht. Ich habe es auch mit XPath Checker (One Firefox Extension) versucht. Es wurden insgesamt 13 Übereinstimmungen gefunden. Ich habe keine Ahnung, wie ich eine davon auswählen soll. Oder unterstützt XPath die angegebene Auswahl von Knoten, die sich nicht unter demselben übergeordneten Knoten befinden?
Dies ist eine FAQ:
//someName[3]
bedeutet: Alle someName
Elemente im Dokument, die das dritte someName
untergeordnete Element des übergeordneten Elements sind - möglicherweise gibt es viele solcher Elemente.
Was Sie wollen, ist genau das 3. someName
-Element:
(//someName)[3]
Erklärung: das []
hat eine höhere Priorität (Priorität) als //
. Denken Sie daran, immer Ausdrücke vom Typ //someName
in Klammern, wenn Sie den N-ten Knoten der ausgewählten Knotenliste angeben müssen.
In XPath gibt es kein i
.
Entweder verwenden Sie Literalzahlen: //img[@title='Modify'][1]
Oder Sie erstellen die Ausdruckszeichenfolge dynamisch: '//img[@title='Modify']['+i+']'
(Beachten Sie jedoch, dass dynamische XPath-Ausdrücke in innerhalb XSLT nicht funktionieren.).
Oder unterstützt XPath die angegebene Auswahl von Knoten, die sich nicht unter demselben übergeordneten Knoten befinden?
Ja: (//img[@title='Modify'])[13]
Dies //img[@title='Modify'][i]
bedeutet "any <img>
mit dem Titel 'Modify' und einem untergeordneten Element namens <i>
. "
//img[@title='Modify'][i]
kurzform für
/descendant-or-self::node()/img[@title='Modify'][i]
daher wird der i-te Knoten unter demselben übergeordneten Knoten zurückgegeben.
Sie wollen
/descendant-or-self::img[@title='Modify'][i]
Es gibt kein i
in xpath ist nicht ganz wahr. Sie können weiterhin die Funktion count()
verwenden, um den Index zu finden.
Betrachten Sie die folgende Seite
<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>
Die Seite enthält 2 Tabellen und 6 Spalten mit jeweils eindeutigen Spaltennamen sowie 6 Zeilen mit variablen Daten. Die letzte Zeile enthält die Schaltfläche Modify
in beiden Tabellen.
Angenommen, der Benutzer muss die 4. Schaltfläche Modify
aus der ersten Tabelle basierend auf der Überschrift auswählen
Benutze den xpath //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button
Der Operator count()
ist in solchen Situationen hilfreich.
Logik:
Modify
mit //th[.='Heading 4']
count(//tr/th[.='Heading 4']/preceding-sibling::th)+1
Hinweis: Index beginnt bei
0
Holen Sie sich die Zeilen für den entsprechenden Header mit //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]
Holen Sie sich die Schaltfläche Modify
aus der Liste der extrahierten Knoten mit //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button
(// * [@ attribute = 'value']) [index], um das Ziel eines Elements zu finden, während mehrere Übereinstimmungen darin gefunden werden
Hier ist die Lösung für die Indexvariable
Angenommen, Sie haben 5 Elemente mit demselben Locator gefunden und möchten für jedes Element eine Aktion ausführen, indem Sie die Indexnummer angeben (hier wird die Variable für den Index als "i" verwendet).
for(int i=1; i<=5; i++)
{
string xPathWithVariable = "(//div[@class='className'])" + "[" + i + "]";
driver.FindElement(By.XPath(xPathWithVariable)).Click();
}
Es dauert XPath:
(//div[@class='className'])[1]
(//div[@class='className'])[2]
(//div[@class='className'])[3]
(//div[@class='className'])[4]
(//div[@class='className'])[5]