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] séparation après tri dynamique


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    175
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 175
    Points : 65
    Points
    65
    Par défaut [XSLT] séparation après tri dynamique
    salut

    je fais un tri dynamique assez complexe (mais qui fonctionne très bien) avec qqchose du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <xsl:apply-templates select="ligne"> 
    <xsl:sort select="*[local-name()=$T_PRI]" data-type="{$temp1}" order="{$O_PRI}"/>
    <xsl:sort select="*[local-name()=$T_SEC]" data-type="{$temp2}" order="{$O_SEC}"/>
    </xsl:apply-templates>
    ce que j'aimerais c'est :

    quand je trie sur une certaine clé primaire (quand T_PRI="val"), je fasse une séparation par groupe (l'équivalent d'un "group by T_PRI" de sql). Il y aura donc une ligne <hr> entre le "groupe1" et le "groupe2", puis une autre entre "groupe2" et "groupe3" et ainsi de suite

    j'ai essayé

    <xsl:if test="not(following::ligne/val=current()/val)">
    <tr>
    <hr/>
    </tr>
    <xsl:if>
    ce qui veut dire que je recherche si dans les noeuds restants à traiter (les noeuds qui suivent dans le fichier xml) il n'y en a pas d'autres qui est le même "val"

    et en toute logique ca ne fonctionne QUE si mon xml était bien ordonné (en raison du following)... et à priori il n'est pas trié suivant la clé "val"

    en effet il me mettra le <hr/> derriere la derniere ligne du fichier, mais qui ne correspond pas forcément à la dernière ligne dans mon tri

    je tourne en rond sur ce prob depuis une grosse semaine, alors si vous pouviez m'aider !

    merci d'avance !!!!

  2. #2
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    Citation Envoyé par MatMeuh
    il faudrait donc faire une sorte d'arbre temporaire... et je ne sais pas si c'ets possible/réalisable
    Oui mais tres couteux en memoire,appel de call-tempalte et recursif et traitement dans le dernier pas.
    Ici la solution la plus simple:
    deux modes:
    Sur le premier tri avec suppression des doublons
    son corps:un apply-templates(ou un for each) avec tri encore sur toutes les données de même clé et separation derriere l'apply ou le for each
    sur le second(ou le corps du for each) traitement des données.

  3. #3
    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 MatMeuh
    donc ne gros faire comme ptitjack a écrit ???
    Non, comme Erwy l'a décrit. (Erwy >> tu m'as grillé la politesse ! )
    Voici une variante de sa solution, qui utilise la méthode Muench ce qui diminue le nombre de tris nécessaires :
    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
      <xsl:key name="champ1" match="ligne" use="champ1"/>
      <xsl:key name="champ2" match="ligne" use="champ2"/>  
     
      <xsl:template match="/test">
        <resultat>
          <xsl:apply-templates select="ligne[generate-id(.)=generate-id(key($T_PRI, *[name() = string($T_PRI)])[1])]" mode="regroupement">
            <xsl:sort select="*[name() = string($T_PRI)]" data-type="{$temp1}"/>
          </xsl:apply-templates>
        </resultat>
      </xsl:template>
     
      <xsl:template match="ligne" mode="regroupement">
        <xsl:variable name="valeur_tri" select="string(*[name() = string($T_PRI)])"/>
        <xsl:apply-templates select="../ligne[string(*[name() = string($T_PRI)]) = $valeur_tri]" mode="detail">
          <xsl:sort select="*[name() = string($T_SEC)]" data-type="{$temp2}"/>
        </xsl:apply-templates>
        <xsl:if test="position() != last()">
          <hr/>
        </xsl:if>
      </xsl:template>
     
     
      <xsl:template match="ligne" mode="detail">
      	<xsl:copy-of select="."/>
      </xsl:template>
    [EDIT] j'ai corrigé la ligne concernant la variable $valeur_tri et celle avec les generate-id; j'avais laissé trainé un 'champ1'...

  4. #4
    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 MatMeuh
    et bien, à premier titre, ce que je ne saisis pas c'est comment je reprends mes données et comment je les organise ??
    La seule partie compliquée est celle qui concerne le regroupement, qui utilise la méthode Muench. Pour une explication de son principe :
    http://www.jenitennison.com/xslt/gro...muenchian.html
    Citation Envoyé par MatMeuh
    est ce qu'il faut que je change le apply-templates de mode "detail" ???
    je reprends le code tel quel ?
    Evidemment, tu dois adapter le template et les noms des éléments dans les xsl:key à ton cas. J'ai mis un xsl:copy-of juste pour tester. Si c'est plus clair pour toi, voici le XML que tu peux utiliser avec ce code sans avoir à le modifier :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <test>
      <ligne>
        <champ1>2</champ1>
        <champ2>3</champ2>
      </ligne>
      <ligne>
        <champ1>1</champ1>
        <champ2>4</champ2>
      </ligne>
      <ligne>
        <champ1>2</champ1>
        <champ2>0</champ2>
      </ligne>
      <ligne>
        <champ1>1</champ1>
        <champ2>1</champ2>
      </ligne>
      <ligne>
        <champ1>4</champ1>
        <champ2>2</champ2>
      </ligne>
      <ligne>
        <champ1>2</champ1>
        <champ2>5</champ2>
      </ligne>
      <ligne>
        <champ1>4</champ1>
        <champ2>1</champ2>
      </ligne>
      <ligne>
        <champ1>3</champ1>
        <champ2>2</champ2>
      </ligne>
      <ligne>
        <champ1>1</champ1>
        <champ2>0</champ2>
      </ligne>
    </test>

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    175
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 175
    Points : 65
    Points
    65
    Par défaut
    c'était juste pour pas surcharger

    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
    <xsl:variable name="temp1"> 
            <xsl:choose> 
                    <xsl:when test="$T_PRI='codeTiers'">text</xsl:when>
    		<xsl:when test="$T_PRI='nomTiers'">text</xsl:when>  
    		<xsl:when test="$T_PRI='piece'">text</xsl:when> 
    		<xsl:when test="$T_PRI='designationArticle'">text</xsl:when> 
    		<xsl:when test="$T_PRI='communeTiers'">text</xsl:when> 
    		<xsl:when test="$T_PRI='magasinAdherent'">text</xsl:when> 
    		<xsl:when test="$T_PRI='memo'">text</xsl:when> 
                    <xsl:otherwise>number</xsl:otherwise> 
            </xsl:choose> 
    </xsl:variable>
    <xsl:variable name="temp2"> 
            <xsl:choose> 
                    <xsl:when test="$T_SEC='codeTiers'">text</xsl:when>
    		<xsl:when test="$T_SEC='nomTiers'">text</xsl:when>  
    		<xsl:when test="$T_SEC='piece'">text</xsl:when>
    		<xsl:when test="$T_SEC='designationArticle'">text</xsl:when>  
    		<xsl:when test="$T_SEC='communeTiers'">text</xsl:when> 
    		<xsl:when test="$T_SEC='magasinAdherent'">text</xsl:when> 
    		<xsl:when test="$T_SEC='memo'">text</xsl:when> 
                    <xsl:otherwise>number</xsl:otherwise>
            </xsl:choose> 
    </xsl:variable>
    ce code est juste avant l'apply-templates

    voila ce que ca donne... mais pour temp1 ca fonctionne... pas temp2... c'ets pour ca que j'ai tenté sans réussite un with-param

    merci et hasta luego !

  6. #6
    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
    Pour ton erreur, ce doit être un problème de portée de variable. Des variables déclarées dans un template ne sont que locales à ce template.
    ce code est juste avant l'apply-templates
    Tes variables temp1 et temp2 (bien mal nommées) sont donc déclarées au niveau du template "/document" et ne sont utilisables que dans ce template ; c'est pour cela que ca fontionne pour temp1 mais pas pour temp2, qui est utilisé dans un autre template. Déplace tes déclarations de variable au niveau du xsl:stylesheet, sous les xsl:param.

    Ceci dit, je suis fort étonné que le processeur XSLT ne proteste pas

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    175
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 175
    Points : 65
    Points
    65
    Par défaut
    ok d'accord ! j'avoue ma très grande faute... c'est juste que je n'avais pas le temps d'approfondir vos solutions (par manque de temps) alros je me limitais a lire et essayer de comprendre "en ligne"


    encore toutes mes confuses !

    quoiqu'il en soit, je ne peux pas définir mes varaibles en "globale".. leur valeur dépend des valeurs que prennent T_PRI et T_SEC (en effet temp1 est soit "text" soit "number" suivant T_PRI, de meme pour temp2)

    c'est pour ca que j'ai eu l'idée de faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <xsl:with-param select="$temp2" name="temp2>
    dans mon appel à apply-templates

    je vosi pas pourquoi ca ne peut pas fonctionner

    ps: je confirme le processeur ne rechigne pas...

  8. #8
    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 MatMeuh
    quoiqu'il en soit, je ne peux pas définir mes varaibles en "globale".. leur valeur dépend des valeurs que prennent T_PRI et T_SEC (en effet temp1 est soit "text" soit "number" suivant T_PRI, de meme pour temp2)
    Si, tu peux. La seule contrainte à respecter est que puisque $temp1 et $temp2 se basent sur les valeurs de $T_PRI et $T_SEC pour leur initialisation, il est nécessaire que ces deux dernières soient initialisées au préalable. C'est pour cela que je te disais de placer l'initialisation de $temp1 et $temp2 APRES les xsl:param de $T_PRI et $T_SEC.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    175
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 175
    Points : 65
    Points
    65
    Par défaut
    bonjour

    au final j'utilise cela comme code, et à priori ca fonctionne (sur les cas que j'ai testé)
    cependant j'aimerais bien avoir, si c'était possible, votre approbation
    merci d'avance !

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     
    <xsl:output indent="yes" method="html"/> 
    <xsl:decimal-format name="francais" decimal-separator="," grouping-separator=" " NaN=" "/>
    <xsl:decimal-format name="test" decimal-separator="," grouping-separator=" " zero-digit=" "/> 
    <xsl:strip-space elements="*"/>
    <xsl:param name="T_PRI"/>
    <xsl:param name="T_SEC"/>
    <xsl:param name="O_PRI">ascending</xsl:param>
    <xsl:param name="O_SEC">ascending</xsl:param>
     
    <xsl:param name="temp1"> 
            <xsl:choose> 
                    <xsl:when test="$T_PRI='codeTiers'">text</xsl:when>
    		<xsl:when test="$T_PRI='nomTiers'">text</xsl:when>  
    		<xsl:when test="$T_PRI='piece'">text</xsl:when> 
    		<xsl:when test="$T_PRI='designationArticle'">text</xsl:when> 
    		<xsl:when test="$T_PRI='communeTiers'">text</xsl:when> 
    		<xsl:when test="$T_PRI='magasinAdherent'">text</xsl:when> 
    		<xsl:when test="$T_PRI='memo'">text</xsl:when> 
                    <xsl:otherwise>number</xsl:otherwise> 
            </xsl:choose> 
    </xsl:param >
    <xsl:param  name="temp2"> 
            <xsl:choose> 
                    <xsl:when test="$T_SEC='codeTiers'">text</xsl:when>
    		<xsl:when test="$T_SEC='nomTiers'">text</xsl:when>  
    		<xsl:when test="$T_SEC='piece'">text</xsl:when>
    		<xsl:when test="$T_SEC='designationArticle'">text</xsl:when>  
    		<xsl:when test="$T_SEC='communeTiers'">text</xsl:when> 
    		<xsl:when test="$T_SEC='magasinAdherent'">text</xsl:when> 
    		<xsl:when test="$T_SEC='memo'">text</xsl:when> 
                    <xsl:otherwise>number</xsl:otherwise>
            </xsl:choose> 
    </xsl:param >
     
    <xsl:key name="codeTiers" match="ligne" use="codeTiers"/> 
    <xsl:key name="nomTiers" match="ligne" use="nomTiers"/> 
    <xsl:key name="designationArticle" match="ligne" use="designationArticle"/> 
     
    <xsl:template match="document">
    ...

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

Discussions similaires

  1. [XSLT] Tri dynamique IE
    Par Wells dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 24/01/2008, 15h26
  2. [XML] Tri Dynamique Firefox
    Par stela86 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/04/2006, 11h16
  3. probleme de tri dynamique de tableau
    Par K_!!! dans le forum ASP
    Réponses: 21
    Dernier message: 15/02/2006, 16h44
  4. [XSLT] Tri dynamique
    Par gregb34 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 06/02/2006, 12h52
  5. tri dynamique avec XSLT
    Par JohnBlatt dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 21/09/2005, 12h30

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