2
votes

Comment gérer les guillemets simples et doubles dans xpath en Python

J'ai un XPath qui a un guillemet simple dans XPath qui provoque une SyntaxError: error .

J'ai essayé avec la séquence d'échappement:

xpath = "//label[contains(text(),'Ayuntamiento de la Vall d'Uixó  - Festivales Musix')]"


0 commentaires

4 Réponses :


0
votes

Essayez le xpath ci-dessous.

xpath = "//label[contains(text(), \"Ayuntamiento de la Vall d'Uixó  - Festivales Musix\")]"


1 commentaires

Que faites-vous lorsque la chaîne recherchée contient un guillemet double? Que faites-vous lorsque vous ne savez pas quel type de guillemets il contient, parce que la chaîne est parce que c'est une valeur d'exécution?



0
votes

Vous pouvez définir la chaîne de recherche en utilisant des guillemets triples - alors vous n'aurez pas à vous soucier des éventuels caractères spéciaux et guillemets dans votre chaîne.

Voici un exemple:

xpath = r"""raw triple quotes string allow the use of '\'"""

Si vous souhaitez également inclure des contre-obliques dans votre chaîne, vous pouvez utiliser des guillemets triples bruts:

xpath = """//label[contains(text(), "Ayuntamiento de la Vall d'Uixó  - Festivales Musix")]"""


4 commentaires

Vous n'avez pas besoin de guillemets triples pour obtenir un guillemet simple dans une chaîne entre guillemets doubles. Le problème n'est pas la validité syntaxique au niveau Python, c'est la validité syntaxique au niveau XPath, et les chaînes entre guillemets triples ne vont pas le couper là. Surtout lorsque la valeur recherchée est fournie par l'utilisateur et peut contenir à la fois des guillemets simples et doubles.


La chaîne XPath d'origine publiée par l'utilisateur se compose de guillemets doubles et simples - auquel cas le guillemet triple est une solution pour résoudre les problèmes concernant les guillemets simples et doubles. La validité syntaxique du XPath lui-même est une autre question bien sûr.


Non ce n'est pas. Cela ne résout le problème qu'au niveau Python, et ce n'est pas suffisant. Une chaîne XPath contenant à la fois des guillemets doubles et simples est toujours illégale.


Imaginez cette situation dans le code Python. xpath = "// label [contains (text (), '% s')]"% dynamic_value , ce qui est très probablement ce que l'OP a. Que faites-vous pour éviter les erreurs d'exécution, quel que soit le contenu de dynamic_value ?



2
votes

Il n'y a pas de guillemet qui s'échappe dans les littéraux de chaîne XPath. (Remarque: Cette réponse s'applique à XPath 1.0. Dans les versions supérieures de XPath, ce problème est résolu - voir le commentaire ci-dessous.)

Le seul moyen d'obtenir le résultat souhaité dans XPath pur est de concaténer des chaînes entre guillemets.

search_value = "Ayuntamiento de la Vall d'Uixó - Festivales Musix"  # could contain both " and '

xpath = "//label[contains(., %s)]" % xpath_string_escape(search_value)

def xpath_string_escape(input_str):
    """ creates a concatenation of alternately-quoted strings that is always a valid XPath expression """
    parts = input_str.split("'")
    return "concat('" + "', \"'\" , '".join(parts) + "', '')"

Vous pouvez créer ce type d'expressions mécaniquement en divisant la chaîne cible au niveau du guillemet simple et en joignant à nouveau les parties avec ', "'", ' code > comme nouveau séparateur. Exemple Python:

//label[contains(., concat('Ayuntamiento de la Vall d', "'", 'Uixó - Festivales Musix'))]

Certaines bibliothèques XPath prennent en charge des paramètres liés (un peu comme SQL) pour contourner ce problème, mais ce qui précède est la seule approche qui fonctionne partout.


4 commentaires

En fait, dans XPath 2.0 et les versions ultérieures, il existe un tel mécanisme d'échappement de guillemets. un " est échappé en le représentant avec deux guillemets adjacents: " " et l'apostrophe échappée est représentée par deux apostrophes: '' . Voir règles 74 à 76 dans: w3.org/TR/xpath20/#id-literals


Vous avez raison, j'ai présumé XPath 1.0 pour cette question. Je mettrai à jour mon libellé.


@Tomalak, votre extrait de code doit renvoyer ceci à la place: return "concat ('" +' \ ', "\'", \ ''. Join (parts) + "',' ')"


@ Néstor Vous avez raison, cela a été dérangé. Corrigé maintenant, merci!



0
votes

Pour créer un dans guillemets doubles qui incluent du texte avec guillemets simples en Python, vous pouvez utiliser les éléments suivants -the-webdriver / 48376890 # 48376890 "> Stratégie de localisation :

xpath = "//label[text()=\"Ayuntamiento de la Vall d'Uixó  - Festivales Musix\"]"


8 commentaires

Que faire si la chaîne de recherche contient un guillemet double?


Cela peut aussi être géré.


Ok ... comment? Et s'il contient les deux types de guillemets? La question n'est pas de savoir comment construire une chaîne Python, la question est de savoir comment construire une chaîne XPath.


@Tomalak Pouvez-vous soulever une nouvelle question avec votre exigence exacte. Les contributeurs de StackOverflow se feront un plaisir de vous aider.


Je n'ai aucune exigence. Je pose la question à vous , car votre réponse ne fonctionne pas dans le contexte de la question du PO. C'est techniquement correct, mais pas utile en pratique.


@Tomalak Le fait est que la question est balisée avec sélénium et sélénium-webdriver . En tant que contributeur de sélénium, nous travaillons toujours pour Selenium pour prendre en charge XPath 2.x et 3.x. Malheureusement, à partir de maintenant, Selenium prend en charge XPath 1.x. Il n'y a donc pratiquement que quelques options à offrir. D'où ma réponse.


@Tomalak En cas de guillemet double, vous devrez utiliser JavascriptExecutor


C'est pourquoi j'ai dit, c'est techniquement correct mais pas pratique. L'OP a très probablement rencontré ceci alors qu'il essayait ce genre de chose: xpath = "// label [contains (., '% S')]"% dynamic_value . Cela fonctionne la plupart du temps, jusqu'à ce que ce ne soit pas le cas. Et rien de ce que vous pouvez faire avec les chaînes Python n'y remédiera.