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] xsl:sort + apply-templates


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut [XSLT] xsl:sort + apply-templates
    Salut tout le monde
    J'ai une question sur le xsl:sort utilisé avec apply-templates
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:apply-templates select="noeud">
      <xsl:sort select"..."/>
    </xsl:apply-templates>
    <xsl:template match="noeud">
     ...instructions...
    </xsltemplate>
    dans mes resultat de transformation l'appel de templates ne s'applique pas sur le resulatat de sort
    j'aimerai savoir comment faire appliquer l'appel de templates sur le resultat de tri plutot que sur le xml d'origine ?

    merci pour votre aide

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Par défaut
    Pourtant ça devrait marcher, c'est prévu pour marcher comme ça : http://xmlfr.org/w3c/TR/xslt/#tri

  3. #3
    Expert confirmé
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Bonjour,
    Citation Envoyé par yos Voir le message
    dans mes resultat de transformation l'appel de templates ne s'applique pas sur le resulatat de sort
    C'est pourtant bien ce qui doit se passer en réalité. Quel est le traitement du template 'noeud' ?
    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

  4. #4
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    avec un exemple je serai plus explicite
    imaginons un fichier xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <data>
    	<doc id="1" title="title one" />
    	<doc id="2" title="title two" />
    	<doc id="3" title="title three" />
    	<doc id="4" title="title four" />
    </data>
    si je voeux trier sur les @title avec un tri "ascending" je ferais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:apply-templates select="doc">
     <xsl:sort select="@title" order="ascending" lang="fr"/>
    </xsl:apply-templates>
    j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <doc id="4" title="title four"/>
    <doc id="1" title="title one"/>
    <doc id="3" title="title three"/>
    <doc id="2" title="title two"/>
    ça va jusqu'à là
    maintenant j'aimrai pour chaque noeud son précédant direct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <xsl:template match="doc">
     <xsl:copy>
      <xsl:copy-of select="@*"/>
        <xsl:element name="precedant">
    	<xsl:copy-of select="preceding-sibling::doc[1]"/>
       </xsl:element>
      </xsl:copy>
    </xsl:template>
    le resultat est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
            <doc id="4" title="title four">
    		<precedant>
    			<doc id="3" title="title three"/>
    		</precedant>
    	</doc>
    	<doc id="1" title="title one">
    		<precedant/>
    	</doc>
    	<doc id="3" title="title three">
    		<precedant>
    			<doc id="2" title="title two"/>
    		</precedant>
    	</doc>
    	<doc id="2" title="title two">
    		<precedant>
    			<doc id="1" title="title one"/>
    		</precedant>
    	</doc>
    alors que <doc id"4"> n'a pas de précédant dans le résultat de tri
    l'appel de template se fait donc sur l'xml d'origine
    le passage par une variable pourait résoudre le problème mais comment faire autrement?

  5. #5
    Expert confirmé
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par yos Voir le message
    l'appel de template se fait donc sur l'xml d'origine
    L'appel du template se fait bien selon l'ordre spécifié par le tri, et c'est plutôt l'expression XPath preceding-sibling::doc[1] qui est évaluée selon le XML d'origine, nuance.

    Mis à part cela, il n'y a pas de solution simple à ton problème, hormis utiliser la fonction exslt:node-set() si ton processeur XSLT la supporte. Ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:template match="data">
            <xsl:copy>
                <xsl:variable name="docs">
                    <xsl:for-each select="doc">
                        <xsl:sort select="@title"/>
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
                </xsl:variable>
                <xsl:for-each select="exslt:node-set($docs)/*">
                    <xsl:copy>
                        <xsl:copy-of select="@*"/>
                        <xsl:element name="precedent">
                            <xsl:copy-of select="preceding-sibling::doc[1]"/>
                        </xsl:element>
                    </xsl:copy>
                </xsl:for-each>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    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

  6. #6
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Merci GrandFather pour ta réponse
    mon processeur ne supporte pas la fonction exslt:node-set()
    pour résoudre ce problème, un passage par une variable pour stocker le résultat du tri avant d'appliquer l'expression xpath, cette solution est un peut lourde mais fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" encoding="utf-8" indent="yes"/>
        <xsl:template match="/">
            <xsl:apply-templates/>
        </xsl:template>
     
        <xsl:template match="data">
           <xsl:variable name="docs">
                <xsl:for-each select="doc">
                    <xsl:sort select="@title" order="ascending" lang="fr"/>
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </xsl:variable>      
                <xsl:apply-templates select="$docs/doc"/>        
        </xsl:template>
     
     
        <xsl:template match="doc">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:element name="precedant">
                    <xsl:copy-of select="preceding-sibling::doc[1]"/>
                </xsl:element>
            </xsl:copy>
        </xsl:template>
    autres suggestions?

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par yos Voir le message
    pour résoudre ce problème, un passage par une variable pour stocker le résultat du tri avant d'appliquer l'expression xpath, cette solution est un peut lourde mais fonctionne
    Ah non, ça ne peut pas fonctionner. Ta variable ainsi créée n'est pas un node-set, mais un RTF (Result Tree Fragment) qui ne peut pas être utilisé dans une expression XPath ; à moins de le transformer au préalable en node-set, ce que fait justement exslt:node-set().

    Je suis étonné que ton processeur XSLT ne supporte pas les extensions EXSLT, à peu près tous le font... MSXML ne les supporte pas en tant que telles, mais propose sa propre version avec un espace de noms particulier (urn:schemas-microsoft-com:xslt).
    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
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Ah non, ça ne peut pas fonctionner.
    pourtant j'obtient bien le résultat attendu ?!

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par yos Voir le message
    pourtant j'obtient bien le résultat attendu ?!
    Pas possible, en tous cas avec Xalan, MSXML 3.0, MSXML 4.0 et le processeur XSLT d'Altova, avec lesquels je viens de vérifier.

    Soit tu t'es trompé, soit tu utilises un processeur XSLT qui ne respecte pas du tout la spécification XSLT 1.0.

    Edit: Tu n'utiliserais pas un processeur XSLT 2.0, par hasard ?
    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
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Edit: Tu n'utiliserais pas un processeur XSLT 2.0, par hasard ?
    c'est exactement cela
    mais pourquoi ça fonctionne avec XSLT2.0

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par yos Voir le message
    mais pourquoi ça fonctionne avec XSLT2.0
    Parce qu'en XSLT 2.0 le type de variable RTF n'existe (heureusement) plus.
    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
    yos
    yos est déconnecté
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Merci grandFather pour toutes ces précisions
    donc si j'ai bien compris ma solution serait bonne à condition d'utiliser XSLT2.0
    et ma variable est bien un nod-set récupéré avec <xsl:copy> ?

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

Discussions similaires

  1. [XSLT]xsl:sort qui classe mal les éléments (apostrophe)
    Par strat0 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 31/07/2007, 14h14
  2. Réponses: 8
    Dernier message: 26/04/2007, 17h24
  3. [XSLT] problème avec apply-templates
    Par ploxien dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 01/11/2006, 11h20
  4. [XSLT] Problème avec apply-templates
    Par NeoMan dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 29/12/2005, 14h45
  5. [XSLT] Différence entre apply-templates et call-template
    Par Cpt.FLAM dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 04/04/2005, 18h47

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