web-dev-qa-db-fra.com

Comment sélectionner un nœud spécifié dans les ensembles de nœuds Xpath par index avec Selenium?

J'écris un test de sélénium. Et voici l'expression xpath que j'utilise pour faire correspondre tous les boutons 'Modifier' d'une table de données.

//img[@title='Modify']

Ma question est la suivante: comment puis-je visiter les ensembles de nœuds correspondants par index? J'ai essayé avec

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

et

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

Mais ni l'un ni l'autre ne fonctionne. J'ai aussi essayé avec le vérificateur XPath (une extension firefox). Il y a un total de 13 correspondances trouvées, alors je ne sais absolument pas comment je vais sélectionner l'une d'entre elles .. Ou XPath prend-il en charge la sélection spécifiée de nœuds qui ne sont pas sous le même nœud parent?

79
Kymair Wu

Ceci est une FAQ:

//someName[3]

signifie: tous les someName éléments du document, qui sont le troisième someName enfant de leur parent - ces éléments peuvent être nombreux.

Ce que vous voulez, c'est exactement le 3ème élément someName:

(//someName)[3]

Explication: le [] a une priorité plus élevée que //. Rappelez-vous toujours de mettre des expressions du type //someName entre parenthèses lorsque vous devez spécifier le nième nœud de la liste de nœuds sélectionnée.

174
Dimitre Novatchev

Il n'y a pas de i dans XPath.

Soit vous utilisez des nombres littéraux: //img[@title='Modify'][1]

Ou vous construisez la chaîne d'expression dynamiquement: '//img[@title='Modify']['+i+']' (Mais gardez à l'esprit que les expressions XPath dynamiques ne fonctionnent pas à partir de inside XSLT).

Ou XPath prend-il en charge la sélection spécifiée de nœuds qui ne sont pas sous le même nœud parent?

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


Ce //img[@title='Modify'][i] Signifie "tout <img> Ayant pour titre" Modify "et un élément enfant nommé <i>."

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

est l'abréviation de

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

retourne donc le ième nœud sous le même nœud parent.

Tu veux

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

Il n'y a pas i dans xpath n'est pas tout à fait vrai. Vous pouvez toujours utiliser la count() pour rechercher l'index.

Considérez la page suivante

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

La page comporte 2 tables et 6 colonnes avec chacune un nom de colonne unique et 6 lignes avec des données variables. La dernière ligne contient le bouton Modify dans les deux tables.

En supposant que l'utilisateur doit sélectionner le 4ème bouton Modify de la première table en fonction de l'en-tête

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

L'opérateur count() est très utile dans de telles situations.

Logique:

  1. Recherchez l’en-tête du bouton Modify à l’aide de //th[.='Heading 4']
  2. Recherchez l'index de la colonne d'en-tête à l'aide de count(//tr/th[.='Heading 4']/preceding-sibling::th)+1

Note: L'index commence à 0

  1. Récupère les lignes de l'en-tête correspondant en utilisant //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]

  2. Obtenez le bouton Modify de la liste de noeuds extraite en utilisant //th[.='Heading 4']/ancestor::thead/following-sibling::tbody/tr/td[count(//tr/th[.='Heading 4']/preceding-sibling::th)+1]/button

1
Eric Stanley

(// * [@ attribut = 'valeur']) [index] pour trouver la cible de l'élément pendant que vous en trouvez plusieurs correspondances

1
mahesh

Voici la solution pour la variable d'index

Disons que vous avez trouvé 5 éléments avec le même localisateur et que vous souhaitez effectuer une action sur chaque élément en fournissant un numéro d'index (ici, la variable est utilisée pour l'index en tant que "i")

for(int i=1; i<=5; i++)
{
    string xPathWithVariable = "(//div[@class='className'])" + "[" + i + "]";
    driver.FindElement(By.XPath(xPathWithVariable)).Click();
}

Il faut XPath:

(//div[@class='className'])[1]
(//div[@class='className'])[2]
(//div[@class='className'])[3]
(//div[@class='className'])[4]
(//div[@class='className'])[5]
0
Srinivas Kassa