IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XSL/XSLT/XPATH XML Discussion :

[XSLT] Caractères spéciaux dans une feuille de transformation


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut [XSLT] Caractères spéciaux dans une feuille de transformation
    Bonjour,

    Je suis confronté au problème suivant :
    Dans une feuille de transformation générant du xhtml, se trouve notamment une partie javascript dans laquelle l'utilisation de symbole tel &, < ou > est indispensable. Je les échappe de tel façon qu'ils soient acceptés par le parser xslt (j'utilise le parser standard de php 5) - &amp; pour &, etc -, mais pour une raison qui m'échappe, le contenu de la balise script est rendu en CDATA - voilà le code xhtml généré après transformation (les underscore de la balise CDATA ont été ajouté pour l'affichage de ce message, ils ne sont pas dans le code original) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    		<script type="text/javascript"><!_[CDATA[
    			load = function( date ){
    				var qURL = 'page?date='+escape(this.fieldName)+'&param=1'; 
    			}
    		]_]></script>
    J'ai essayé de spécifier dans ma feuille de style xslt qu'il s'agissait bien de texte brut (<xsl:text>) - la source xslt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		<script type="text/javascript">
    			<xsl:text>
    			load = function( date ){
    				var qURL = 'page?date='+escape(this.fieldName)+'&amp;param=1'; 
    			}
    			</xsl:text>
    		</script>
    Je ne sais pas bien quoi faire ; toute aide serait la bienvenue...
    Merci, et bonne journée.

  2. #2
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Salut,

    C'est un bug de libxslt qui ajoute automatiquement une section cdata au text généré en dessous d'une balise SCRIPT. Essaie cette solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <script type="text/javascript">
       <xsl:text disable-output-escaping="yes"><![CDATA[
          load = function( date ){
             var qURL = 'page?date='+escape(this.fieldName)+'&param=1'; 
          }
    	]]></xsl:text>
    </script>
     
    et:
    $xsl_dom->loadXML($xsl, LIBXML_NOCDATA);
    ou
    $xsl_dom->load($xsl_file_location, LIBXML_NOCDATA);
    ou cette autre solution (je la préfère):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
       <xsl:text disable-output-escaping="yes">
           &lt;script type="text/javascript">
           //&lt;![CDATA[
          load = function( date ){
             var qURL = 'page?date='+escape(this.fieldName)+'&param=1'; 
          }
            // ]]>
            &lt;/script>
       </xsl:text>
    ERE
    Quand une tête pense seule, elle devient folle.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Merci Emmanuel,

    je vais essayer cette dernière solution ; si j'ai bien compris, il s'agit donc juste de faire passer une balise script pour du texte. A minima, cela pourrait donner ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     <xsl:text disable-output-escaping="yes">
           &lt;script type="text/javascript">
          load = function( date ){
             var qURL = 'page?date='+escape(this.fieldName)+'&amp;param=1'; 
          }
            &lt;/script>
       </xsl:text>

  4. #4
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Salut,

    Oui c'est tout à fait cela. Mais ne t'ennuie pas, mets tout dans une CDATA comme ça pas besoin de mettre les entités et tu conserves un code javascript normal...

    ERE
    Quand une tête pense seule, elle devient folle.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    J'ai testé, et ça marche ! c'est plutot une bonne nouvelle, dans la mesure où jusqu'à présent j'avais essayé de contourner le problème en évitant les caractères incriminant dans mes sources javascript, ce qui en soit n'était pas une solution durable. Merci, donc.

    Citation Envoyé par emmanuel.remy Voir le message
    Salut,

    Oui c'est tout à fait cela. Mais ne t'ennuie pas, mets tout dans une CDATA comme ça pas besoin de mettre les entités et tu conserves un code javascript normal...

    ERE
    Oui, c'est une bonne idée, mais la génération de mon code javascript est conditionné en xslt : il faudrait donc, si je ne m'abuse, ouvrir et fermer les balises CDATA à chaque fois que je "remonte" sur la couche xslt...

  6. #6
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Effectivement s'il est généré en XSLT, c'est un peu différent.

    Bon dev,

    ERE
    Quand une tête pense seule, elle devient folle.

  7. #7
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,
    Citation Envoyé par lescarphe Voir le message
    Oui, c'est une bonne idée, mais la génération de mon code javascript est conditionné en xslt : il faudrait donc, si je ne m'abuse, ouvrir et fermer les balises CDATA à chaque fois que je "remonte" sur la couche xslt...
    On peut demander au processeur XSLT de placer systématiquement des balises CDATA sur des éléments spécifiés ; cela se fait avec l'attribut cdata-section-elements de la balise xsl:output.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  8. #8
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    @GrandFather: et dans ce cas, faut il activer disable-output-escaping="yes" sur les sorties de ces éléments ?

    ERE
    Quand une tête pense seule, elle devient folle.

  9. #9
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Non, en principe ce n'est pas nécessaire.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Je suis pas sur qu'il soit nécessaire d'ouvrir un nouveau post, puisque le problème est très similaire :

    comment insérer le fameux hack ie5 permettant de charger des feuilles de style alternatives pour ie dans une feuille de transformation xslt ; je pensais avoir compris le comportement des CDATA après vos réponses, mais je n'arrive pas à résoudre ce nouveau problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    		<!--[if gte IE 5]>
    		<![if lt IE 7]>
    			<style type="text/css" media="screen">
    			@import "/css/common_ie.css";
    			</style>
    		<![endif]>
    		<![endif]-->
    en toute logique, est ce que quelque chose dans ce style ne devrait pas fonctionner ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    		<xsl:text disable-output-escaping="yes">
    		&lt;![CDATA[
    		<!--[if gte IE 5]>
    		<![if lt IE 7]>
    			<style type="text/css" media="screen">
    			@import "/css/common_ie.css";
    			</style>
    		<![endif]>
    		<![endif]-->
    		]]&gt;
    		</xsl:text>
    Pour info, le code généré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    		<!--[CDATA[
     
    		]]-->

  11. #11
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par lescarphe Voir le message
    en toute logique, est ce que quelque chose dans ce style ne devrait pas fonctionner ?
    Eh non, ça ne peut pas fonctionner.

    Il ne faut pas oublier qu'un fichier XSLT est avant tout du XML ; en l'occurrence, dans du code XSLT, les commentaires HTML hors bloc CDATA sont interprétés et restitués par le parseur comme tels, au processeur XSLT qui n'en fait rien.

    Il faut donc quelque chose dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
    <xsl:text disable-output-escaping="yes"><![CDATA[
    		<!--[if gte IE 5]>
    		<![if lt IE 7]>
    			<style type="text/css" media="screen">
    			@import "/css/common_ie.css";
    			</style>
    		<![endif]>
    		<![endif]-->
    ]]></xsl:text>
    <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
    Facile, non ?
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par GrandFather Voir le message
    Il ne faut pas oublier qu'un fichier XSLT est avant tout du XML ; en l'occurrence, dans du code XSLT, les commentaires HTML hors bloc CDATA sont interprétés et restitués par le parseur comme tels, au processeur XSLT qui n'en fait rien.
    Merci ; je vais essayer, même si j'avoue que quelque chose m'échappe

    par exemple, à qui est destiné le CDATA englobant (non interprété par le xslt, si je ne m'abuse, puisque désactivé pour l'interprétation) ?

    autre chose : pourquoi un disable-escaping alors qu'il n'y a rien à échapper ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
    à ce sujet, pourquoi un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
    ne marcherait pas ? intuitivement, tout ce qui est situé entre deux balises text ne devrait pas être interprété par le proc xslt, non ?
    Si ce n'est pas le cas, quelle est l'utilité d'une balise text ?

    Bref, il me manque quelque base pour bien assimiler tout ça .

  13. #13
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    Salut,

    Je crois qu'il y a une petite incompréhension par rapport à ce que tu voulais générer et ce qui a été pris en compte.

    Je pense que ce code convient car tu n'as pas besoin de CDATA dans ta stylesheet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <xsl:text disable-output-escaping="yes">
    <![CDATA[
    	<!--[if gte IE 5]>
    	<![if lt IE 7]>
    		<style type="text/css" media="screen">
    		@import "/css/common_ie.css";
    		</style>
    	<![endif]>
    	<![endif]-->
    ]]>
    </xsl:text>
    ERE
    Quand une tête pense seule, elle devient folle.

  14. #14
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par emmanuel.remy Voir le message
    Je crois qu'il y a une petite incompréhension par rapport à ce que tu voulais générer et ce qui a été pris en compte.
    Euh, exact, je me suis un peu emmêlé les pinceaux, je ne sais pas où j'ai pu lire qu'un CDATA était nécessaire en sortie...

    En ce qui concerne l'utilité exacte de xsl:text : cette balise sert essentiellement à définir exactement un texte littéral que le processeur XSLT doit envoyer en sortie, sans prendre en compte les caractères blancs (espaces, retours-chariots, tabulations, etc.) qui l'entourent.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="...">
    <balise>
      Bonjour !
    </balise>
    </xsl:template>
    renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <balise>
      Bonjour !
    </balise>
    Tandis que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:template match="...">
    <balise>
      <xsl:text>Bonjour !</xsl:text>
    </balise>
    </xsl:template>
    renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <balise>Bonjour !</balise>
    On l'utilise essentiellement pour des sorties de type texte, comme du CSV par exemple, pour avoir un texte correctement formaté sans que l'indentation du code XSLT interfère. Ici, on l'utilise uniquement pour son attribut disable-output-escaping qui évitera que les <, > et & du hack IE soient remplacés par leurs entités respectives lors de la sérialisation du résultat.

    Une dernière précision : un <![CDATA[...]]> qui figure dans du code XSLT est analysé par le parseur XML et son contenu est remonté au processeur XSLT comme étant du texte simple, mais à aucun moment le processeur XSLT n'a « connaissance » de la présence de ce bloc CDATA. Tout ce que voit le processeur XSLT, que ce soit du document XML à traiter ou du code XSLT lui-même, ce sont des noeuds de type texte, des éléments, des attributs, des commentaires et des PI (processing instruction). Les CDATA et les entités, c'est la tambouille du seul parseur XML.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par GrandFather Voir le message
    On l'utilise essentiellement pour des sorties de type texte, comme du CSV par exemple, pour avoir un texte correctement formaté sans que l'indentation du code XSLT interfère. Ici, on l'utilise uniquement pour son attribut disable-output-escaping qui évitera que les <, > et & du hack IE soient remplacés par leurs entités respectives lors de la sérialisation du résultat.
    Citation Envoyé par GrandFather Voir le message
    Une dernière précision : un <![CDATA[...]]> qui figure dans du code XSLT est analysé par le parseur XML et son contenu est remonté au processeur XSLT comme étant du texte simple, mais à aucun moment le processeur XSLT n'a « connaissance » de la présence de ce bloc CDATA. Tout ce que voit le processeur XSLT, que ce soit du document XML à traiter ou du code XSLT lui-même, ce sont des noeuds de type texte, des éléments, des attributs, des commentaires et des PI (processing instruction). Les CDATA et les entités, c'est la tambouille du seul parseur XML.
    Merci, c'est beaucoup plus clair maintenant !

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par emmanuel.remy Voir le message
    Je pense que ce code convient car tu n'as pas besoin de CDATA dans ta stylesheet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <xsl:text disable-output-escaping="yes">
    <![CDATA[
    	<!--[if gte IE 5]>
    	<![if lt IE 7]>
    		<style type="text/css" media="screen">
    		@import "/css/common_ie.css";
    		</style>
    	<![endif]>
    	<![endif]-->
    ]]>
    </xsl:text>
    ERE
    En fait, lors de mes tests, cette solution échappait les caractères spéciaux ; pourtant, si j'ai bien compris, le contenu du CDATA est transmis tel quel au processeur XSLT, et donc l'instruction disable-escaping devrait rendre à l'identique cette portion de texte... mais voilà ce que j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	&lt;!--[if gte IE 5]&gt;
    	&lt;![if lt IE 7]&gt;
    		&lt;style type="text/css" media="screen"&gt;
    		@import "/css/common_ie.css";
    		&lt;/style&gt;
     
    	&lt;![endif]&gt;
    	&lt;![endif]--&gt;

    La solution, pas très élégante, est d'échapper "à la main" tous les caractères spéciaux dans le XML original. Mais j'avoue que je ne comprends pas pourquoi : la logique est plutôt de ton coté...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		<xsl:text disable-output-escaping="yes">
    				&lt;!--[if gte IE 5]&gt;
    				&lt;![if lt IE 7]&gt;
    					&lt;style type="text/css" media="screen"&gt;
    					&lt;/style&gt;
    				&lt;![endif]&gt;
    				&lt;![endif]--&gt;
    		</xsl:text>

  17. #17
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Emmanuel t'a déjà donné la solution : il s'agit d'un bug de PHP qui ne prend pas en compte par défaut une spécificité de libxml/libxslt. Il faut que tu charges la feuille de style en spécifiant un paramètre supplémentaire :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $xsl->load($xslfile, LIBXML_NOCDATA);
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SQL] Problème d'affichage de caractère spéciaux dans une variable chaîne
    Par Kryptonaute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/08/2006, 08h40
  2. Affichage caractéres spéciaux dans une alert.
    Par nebule dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 05/05/2006, 13h51
  3. [RegEx] caractère spéciaux dans une chaine
    Par BigBarbare dans le forum Langage
    Réponses: 3
    Dernier message: 12/04/2006, 11h53
  4. Caractères spéciaux dans une boite de dialogue
    Par Rafiki dans le forum Général JavaScript
    Réponses: 22
    Dernier message: 09/03/2006, 14h05
  5. [xslt]insérer javascript dans une feuille
    Par nemya dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 15/11/2005, 13h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo