Seleniumを使用して、インデックスによってXpathノードセット内の指定されたノードを選択する方法


91

Seleniumテストケースを書いています。そして、これが、データテーブル内のすべての「変更」ボタンに一致させるために使用するxpath式です。

//img[@title='Modify']

私の質問は、一致したノードセットにインデックスでアクセスするにはどうすればよいですか?私は試しました

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

そして

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

しかし、どちらも機能しません。XPathチェッカー(Firefox拡張機能1つ)も試しました。完全に13の一致が見つかった場合、どうすればそれらの1つを選択するのかまったくわかりません。 または、XPathは、同じ親ノードの下にない指定されたノードの選択をサポートしていますか?

回答:


191

これはFAQです:

//someName[3]

意味someName文書のすべての要素、つまりsomeNameその親の3番目の 子-そのような要素が多数存在する可能性があります。

あなたが欲しいのはまさに3番目のsomeName要素です:

(//someName)[3]

説明[]は、よりも優先順位(優先度)が高くなってい//ます。//someName選択したノードリストのN番目のノードを指定する必要がある場合は、タイプの式を角括弧で囲んでください。


1
本当にありがとう!申し訳ありませんが、優先順位を完全に忘れてしまいました。試してみましたが、うまくいきました。
Kymair Wu

1
@ Kymair-Wu:この回答がお役に立ててうれしいです。ここSOで感謝の気持ちを表す方法は、回答を受け入れることです(ヒント:回答の横にあるチェックマークをクリックしてください)。:)
Dimitre Novatchev 2010

@DimitreNovatchevあなたは同じ質問のポイントを何度も得ています:p、FAQに感謝します。
Eytoss 2012年

2
@Eytoss、どういたしまして。そして、はい、私は比較的単純な答えを最も+ 1Sを取得しています-ではない私は私の最大の成果であると考えていることの答えを- :)おそらく誰もがかつてのを理解しているため、ほとんど誰もが、後者を理解していない
Dimitre Novatchev

2
@TEHEMPRAH、実際に私は答えで「親の3番目の 'someName'子」とは言わなかったのを見ました。これに気づいていただきありがとうございます。今すぐ修正。
Dimitre Novatchev、2015

14

iXPathにはありません。

リテラル数を使用するか: //img[@title='Modify'][1]

または、式文字列を動的に作成します'//img[@title='Modify']['+i+']'(ただし、動的XPath式はXSLT からは機能しないことに注意してください)。

または、XPathは同じ親ノードの下にないノードの指定された選択をサポートしますか?

はい: (//img[@title='Modify'])[13]


これ//img[@title='Modify'][i]は、「<img>タイトルが「変更」で、名前がの子要素を持つ任意のもの」を意味し<i>ます。


何らかの理由で、属性式の前にインデックスを含める必要がありました。例えば、見つけることtdの第六子だったのをtr、空のコンテンツを持っていない://tr/td[6][string-length(text()) > 0]
サミル・アギアル

1
@kopranb説明については、この回答を参照してくださいstackoverflow.com/a/1006439/18771
Tomalak

'// img [@ title =' Modify '] [' + i + ']'(+1)について説明していただきありがとうございます
DebanjanB

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

の略

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

したがって、同じ親ノードの下にあるi番目のノードを返します。

あなたが欲しい

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

1
ジャストは/descendant::img[@title='Modify'][$index]罰金を動作します。また、[i]述語はi子要素の存在をテストすることに注意してください。

2

何もありませんiのxpathに完全に真実ではありません。引き続きcount()インデックスを見つけることができます。

次のページを検討してください

<html>

	<head>
		<title>HTML Sample table</title>
	</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>

	<body>
	<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>

	</body>
</html>

このページには2つのテーブルがあり、それぞれに一意の列名を持つ6つの列と可変データを持つ6つの行があります。最後の行には、Modify両方のテーブルのボタンがあります。

ユーザーがModify見出しに基づいて最初のテーブルから4番目のボタンを選択する必要があると仮定します。

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


1

(// * [@ attribute = 'value'])[index]要素のターゲットを検索し、その中に複数の一致を見つける


1
もう少し説明してもらえますか?
abhiarora 2017

0

これがインデックス変数の解決策です

たとえば、ロケーターが同じ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]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.