web-dev-qa-db-fra.com

Utilisation de XPATH pour rechercher du texte contenant nbsp;

J'utilise XPather Browser pour vérifier mes expressions XPATH sur une page HTML.

Mon objectif final est d’utiliser ces expressions dans Selenium pour tester mes interfaces utilisateur.

J'ai un fichier HTML avec un contenu similaire à ceci:

 <tr> 
 <td> abc </ td> 
 <td> nbsp; </ td> 
 </ tr> 

Je veux sélectionner un nœud avec un texte contenant la chaîne "&nbsp;".

Avec une chaîne normale comme "abc", il n'y a pas de problème. J'utilise un XPATH semblable à //td[text()="abc"].

Lorsque j'essaie avec un XPATH tel que //td[text()="&nbsp;"], il ne renvoie rien. Existe-t-il une règle spéciale concernant les textes avec "&"?

112
Bergeroy

Il semble que OpenQA , les gars derrière Selenium, aient déjà résolu ce problème. Ils ont défini certaines variables pour correspondre explicitement aux espaces. Dans mon cas, je dois utiliser un XPATH semblable à //td[text()="${nbsp}"].

J'ai reproduit ici le texte d'OpenQA concernant ce problème (trouvé ici ):

HTML normalise automatiquement les espaces au sein des éléments, ignore les espaces de début et de fin et convertit les espaces, les onglets et les nouvelles lignes supplémentaires en un seul espace. Lorsque Selenium lit du texte hors de la page, il tente de dupliquer ce problème. Vous pouvez donc ignorer tous les onglets et les nouvelles lignes de votre code HTML, ainsi que des assertions basées sur l'apparence du texte dans le navigateur. Nous faisons cela en remplaçant tous les espaces non visibles (y compris l’espace insécable "&nbsp;") Par un seul espace. Toutes les nouvelles lignes visibles (<br>, <p> Et <pre> Nouvelles lignes formatées) doivent être conservées.

Nous utilisons la même logique de normalisation que le texte des tables de scénarios de test HTML Selenese. Cela présente de nombreux avantages. Premièrement, vous n'avez pas besoin de regarder la source HTML de la page pour comprendre ce que vos assertions devraient être; Les symboles "&nbsp;" Sont invisibles pour l'utilisateur final. Vous ne devriez donc pas avoir à vous en soucier lors de l'écriture de tests Selenese. (Vous n'avez pas besoin de mettre des marqueurs "&nbsp;" Dans votre scénario de test pour assertText sur un champ contenant "&nbsp;".) Vous pouvez également insérer des lignes et des espaces supplémentaires dans votre sélénien <td> Tags; comme nous utilisons la même logique de normalisation dans le scénario de test que dans le texte, nous pouvons nous assurer que les assertions et le texte extrait correspondent exactement.

Cela crée un problème dans les rares occasions où vous souhaitez vraiment/devez insérer des espaces supplémentaires dans votre scénario de test. Par exemple, vous devrez peut-être taper du texte dans un champ comme celui-ci: "foo". Mais si vous écrivez simplement <td>foo </td> Dans votre scénario de test Selenese, nous remplacerons vos espaces supplémentaires par un seul espace.

Ce problème a une solution de contournement simple. Nous avons défini une variable en sélénien, ${space}, Dont la valeur est un seul espace. Vous pouvez utiliser ${space} Pour insérer un espace qui ne sera pas automatiquement coupé, comme ceci: <td>foo${space}${space}${space}</td>. Nous avons également inclus une variable ${nbsp}, Que vous pouvez utiliser pour insérer un espace insécable.

Notez que les XPaths ne normalisent pas les espaces . Si vous avez besoin d'écrire un XPath comme //div[text()="hello world"] mais que le code HTML du lien est vraiment "hello&nbsp;world", Vous devrez insérer un vrai "&nbsp;" Dans votre Selenese cas de test pour le faire correspondre, comme ceci: //div[text()="hello${nbsp}world"].

87
Bergeroy

J'ai trouvé que je pouvais faire la correspondance lorsque je saisissais un espace insécable codé en dur (U + 00A0) en tapant Alt + 0160 sous Windows entre les deux guillemets ...

//table[@id='TableID']//td[text()=' ']

travaillé pour moi avec le caractère spécial.

D'après ce que j'ai compris, la norme XPath 1.0 ne gère pas les caractères Unicode échappés. Il semble y avoir des fonctions pour cela dans XPath 2.0 mais il semble que Firefox ne le supporte pas (ou j'ai mal compris quelque chose). Vous devez donc faire avec la page de codes locale. Moche, je sais.

En fait, il semble que la norme s’appuie sur le langage de programmation utilisant XPath pour fournir la séquence d’échappement Unicode correcte ... Donc, d’une manière ou d’une autre, j’ai fait ce qu’il fallait.

24
PhiLho

Essayez d’utiliser l’entité décimale &#160; au lieu de l'entité nommée. Si cela ne fonctionne pas, vous devriez pouvoir utiliser simplement le caractère Unicode pour un espace insécable au lieu du &nbsp; entité.

(Remarque: je n'ai pas essayé cela dans XPather, mais je l'ai essayé dans Oxygen.)

4
James Sulak

N'oubliez pas qu'un processeur XML conforme aux normes aura remplacé toutes les références d'entités autres que les cinq références standard de XML (&amp;, &gt;, &lt;, &apos;, &quot;) avec le caractère correspondant dans le codage cible au moment de l'évaluation des expressions XPath. Compte tenu de ce comportement, les suggestions de PhiLho et de jsulak sont la voie à suivre si vous souhaitez utiliser des outils XML. Quand vous entrez &#160; dans l'expression XPath, il doit être converti en séquence d'octets correspondante avant que l'expression XPath ne soit appliquée.

2
ChuckB

Je ne peux pas obtenir de correspondance en utilisant Xpather, mais ce qui suit a fonctionné pour moi avec des fichiers XML et XSL ordinaires dans le Bloc-notes XML de Microsoft:

<xsl:value-of select="count(//td[text()='&nbsp;'])" />

La valeur renvoyée est 1, ce qui correspond à la valeur correcte dans mon cas de test.

Cependant, je devais déclarer nbsp en tant qu'entité dans mon XML et mon XSL en utilisant les éléments suivants:

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>

Je ne sais pas si cela vous aidera, mais j'ai pu réellement trouver nbsp en utilisant une expression XPath.

Edit: Mon exemple de code contient les caractères 'nbsp;' mais la surbrillance de la syntaxe JavaScript le convertit en caractère d'espace. Ne soyez pas trompé!

1
Zack The Human

Rechercher &nbsp; ou seulement nbsp - l’avez-vous essayé?

1
roni