Comment insérer une apostrophe dans une constante XPath?
Eric van der Vlist, Dyomedea (vdv@dyomedea.com).
vendredi 15 juillet 2005
Table des matières
Question
Réponse
D'où vient cette erreur?
Comment la résoudre?
Principe
Application à une transformation XSLT
A ne pas faire
Comment le contourner?
Références
Question
Dans une transformation XSLT, je dois faire un test utilisant une constante XPath contenant une apostrophe :
<xsl:when test="./@commune='Les roches l'évêque' ">
Lorsque j'applique ma transformation sur un fichier, j'ai l'erreur suivante :" This file is not valid: Invalid XPath expression" pointant sur la ligne ci-dessus.Comment puis-je faire pour que les apostrophes soient prises en compte dans mon expression XPath ?
Réponse
D'où vient cette erreur?
Dans l'expression XPath "./@commune='Les roches l'évêque' ", le caractère apostrophe est utilisé à la fois pour délimiter une constante de type chaîne de caractères et à l'intérieur de cette constante.
Cela poserait problème pour n'importe quel langage de programmation et c'est également le cas pour XPath.
Comment la résoudre?
Principe
Les différents langages de programmation proposent plusieurs principes pour résoudre ce type de problème. Certains utilisent des caractères d'échappement, d'autres permettent de remplacer les délimiteurs de constantes chaînes de caractères par des séquences ayant peu de chance de se trouver dans une chaîne de caractères, d'autres permettent de jouer entre deux caractères pour délimiter les chaînes de caractères.
XPath n'offre que cette dernière possibilité pour résoudre le problème et il faudra donc que nous récrivions l'expression XPath comme :
./@commune="Les roches l'évêque"
Puisque nous utilisons maintenant des guillemets pour encadrer la constante chaîne de caractères, nous pouvons utiliser une apostrophe à l'intérieur de cette chaîne.
A l'inverse, si nous avions dû insérer un guillemet à l'intérieur d'une chaîne, il aurait obligatoirement fallu utiliser des apostrophes pour délimiter la chaîne de caractères.
Application à une transformation XSLT
Après avoir déterminé quelle doit être notre expression XPath, nous devons maintenant trouver comment l'insérer dans notre transformation XSLT.
Le problème est que cette expression XPath doit être placée dans l'attribut "test" de l'élément XSLT "xsl:when". Les valeurs d'attributs XML sont elles-mêmes encadrées par des apostrophes ou des guillemets et nous avons à nouveau un problème analogue à celui que nous venons de résoudre :
<xsl:when test="./@commune="Les roches l'évêque" ">
est incorrect parce qu'il y a conflit entre les guillemets encadrant la valeur de l'attribut "test" et les guillemets utilisés dans l'expression XPath.
<xsl:when test='./@commune="Les roches l'évêque" '>
est incorrect parce qu'il y a conflit entre les apostrophes encadrant la valeur de l'attribut "test" et l'apostrophe utilisée dans l'expression XPath.
Heureusement pour nous, XML fournit une autre manière de résoudre ce problème et nous pouvons remplacer les guillemets et apostrophes par des appels à l'une des cinq entités internes pré-définies en XML, en l'occurrence """ et "'".
On pourra donc, au choix :
- utiliser des apostrophes pour délimiter l'attribut "test" et remplacer l'apostrophe dans l'expression XPath par "'" :
<xsl:when test='./@commune="Les roches l'évêque" '>
- utiliser des guillemets pour encadrer l'expression XPath et remplacer les guillemets dans l'expression XPath par """ :
- utiliser indifféremment soit des apostrophes soit des guillemets pour encadrer l'expression XPath et remplacer, sans se poser de question, toutes les apostrophes et guillemets dans l'expression XPath par "'" et """ :
ou
<xsl:when test='./@commune="Les roches l'évêque" '
>
On notera que tout parseur XML considérera ces variantes comme rigoureusement équivalentes et que dans tous les cas, l'expression XPath vue par le processeur XSLT est celle que nous souhaitons, c'est à dire ./@commune="Les roches l'évêque" .
A ne pas faire
On pourrait être tenté d'écrire :
<xsl:when test="./@commune='Les roches l'évêque' ">
et être surpris d'obtenir à la même erreur XPath que nous obtenions à l'origine.
C'est tout à fait normal puisque pour un parseur XML, cette valeur de l'attribut "test" est strictement équivalente à "./@commune='Les roches l'évêque' " et est donc incorrecte.Pour éviter ce type d'erreur, il faut, comme nous l'avons fait, déterminer dans un premier temps l'expression XPath "en clair", indépendamment de toute syntaxe XML puis déterminer dans un deuxième temps comment nous voulons exprimer cette expression dans un attribut XML en remplaçant au besoin certains caractères par des appels à des entités pré-définies.
Comment le contourner?
Tout ceci peut ressembler à un casse tête qui devient insoluble lorsque l'on doit à la fois insérer des guillemets et des apostrophes dans une chaîne de caractères et l'on peut préférer tout simplement contourner le problème.
Pour cela, le plus simple est de placer la constante dans une variable XSLT et de faire référence à cette variable :
<xsl:variable name="commune">Les roches l'évêque</xsl:variable>
<xsl:choose>
<xsl:when test="./@commune = $commune">
Nous pouvons maintenant insérer autant d'apostrophes et de guillemets que nous le souhaitons dans notre chaîne de caractères!
Références
Copyright 2005, Eric van der Vlist
|