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] Sort avec mémorisation de la position


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 2
    Points
    2
    Par défaut [XSLT] Sort avec mémorisation de la position
    Bonjour,

    je cherche, je cherche, ... mais je ne trouve pas

    mon problème parait pourtant simple...
    1) Je souhaite trier un document xml par points afin d'établir le classement.
    résultat :
    1er : YOUPI
    2eme : AYO
    3eme : TAMI

    2) Ensuite je souhaite trier le document par nom tout en conservant le classement.
    résultat :
    2eme : AYO
    3eme : TAMI
    1er : YOUPI



    fichier xml :
    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
     
    <?xml version="1.0" encoding="iso-8859-1"?>
    <?xml-stylesheet type="text/xsl" href="mise_en_forme.xsl"?>
    <resultats>
    <utilisateur>
    	<nom>YOUPI</nom>
    	<prenom>JM</prenom>
    	<points>50</points>
    </utilisateur>
    <utilisateur>
    	<nom>AYO</nom>
    	<prenom>JP</prenom>
    	<points>40</points>
    </utilisateur>
    <utilisateur>
    	<nom>TAMI</nom>
    	<prenom>JL</prenom>
    	<points>37</points>
    </utilisateur>
    </resultats>

  2. #2
    Membre expérimenté
    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
    Points : 1 610
    Points
    1 610
    Par défaut
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:template match="/">
        <root>
          <sortedByPoint>
            <xsl:for-each select="//utilisateur">
              <xsl:sort order="points" data-type="number"/>
              <xsl:copy-of select="."/>
            </xsl:for-each>
          </sortedByPoint>
          <sortedByName>
            <xsl:for-each select="//utilisateur">
              <xsl:sort order="nom"/>
              <xsl:copy-of select="."/>
            </xsl:for-each>
          </sortedByName>  
        </root>
     
      </xsl:template>
     
    </xsl:stylesheet>

  3. #3
    Candidat au Club
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci Morbo pour ta réponse.

    Le xsl que tu as posté permet d'obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <sortedByPoint>
    	<!--éléments <utilisateur> ordonnés par points-->
    </sortedByPoint>
    <sortedByName>
    	<!--éléments <utilisateur> ordonnés par nom-->
    </sortedByName>
    Or je souhaite afficher le classement ordonné par nom.
    La nuance est subtile et difficile à exprimer clairement...
    Voici un exemple de l'affichage voulu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /* CLASSEMENT 	*|* NOM
    /*--------------*|*-------
    /* 2eme		*|* AYO (2eme car 40 points)
    /* 3eme		*|* TAMI (3eme car 37 points)
    /* 1er		*|* YOUPI (1er car 50 points)
    J'espère avoir été clair...

  4. #4
    Membre expérimenté
    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
    Points : 1 610
    Points
    1 610
    Par défaut
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method = "text"  version="1.0" encoding="UTF-8" omit-xml-declaration="yes" standalone="no" indent="no"  />
       <xsl:template match="/">
    /* CLASSEMENT 	*|* NOM
    /*--------------*|*-------
    <xsl:for-each select="//utilisateur">
    <xsl:sort select="nom" />
    <xsl:variable name="nom" select="nom" />
    <xsl:for-each select="//utilisateur">
    <xsl:sort select="points" data-type="number" />
    <xsl:if test="nom = $nom">
    <xsl:value-of select="concat('/*            ',position(),' *|* ',$nom)" /><xsl:text>
    </xsl:text>
    </xsl:if>
    </xsl:for-each>
    </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>
    Par contre c'est pas terrible au niveau des perf .
    C'est quoi ton processeur xslt?

  5. #5
    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,

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method = "text" />
       <xsl:template match="/">
           <xsl:text>/* CLASSEMENT 	*|* NOM</xsl:text>
           <xsl:text>
    </xsl:text>
            <xsl:text>/*---------------*|*-------</xsl:text>
            <xsl:text>
    </xsl:text>
            <xsl:for-each select="//utilisateur">
                <xsl:sort select="nom" />
                <xsl:text>/*                   </xsl:text>
                <xsl:value-of select="count(//utilisateur[points &gt; current()/points]) + 1"/>
                <xsl:text>*|*</xsl:text>
                <xsl:value-of select="nom" />
                <xsl:text>
    </xsl:text>
                </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>

  6. #6
    Candidat au Club
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    pouaf ! c'est exactement ce que je voulais Morbo ...

    c'est vrai que l'execution est longue sur de gros fichiers
    L'objectif est de faire un simple affichage sur IE ou sur FireFox.

    J'ai légèrement modifier le script pour les problèmes causés par les homonymes.
    Du coup je me suis basé sur l'attribut "code" qui est unique pour le if et le sort.
    Sinon les résultats obtenus sont différents sur IE et sur FireFox.



    fichier xml :
    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
    <?xml version="1.0" encoding="iso-8859-1"?>
    <?xml-stylesheet type="text/xsl" href="mise_en_forme.xsl"?>
    <resultats>
    <utilisateur code="BBYOJM">
    	<nom>YOUPI</nom>
    	<prenom>JM</prenom>
    	<points>50</points>
    </utilisateur>
    <utilisateur code="BBAYJP">
    	<nom>AYO</nom>
    	<prenom>JP</prenom>
    	<points>40</points>
    </utilisateur>
    <utilisateur code="BBTAJL">
    	<nom>TAMI</nom>
    	<prenom>JL</prenom>
    	<points>37</points>
    </utilisateur>
    </resultats>
    fichier mise_en_forme.xsl :
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    	<xsl:template match="/">
    		<html>
    			<head>
    				<title>Exemple de sortie HTML</title>
    				<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    			</head>
    			<body>
    				<xsl:for-each select="//utilisateur">
    					<xsl:sort select="nom" data-type="text" order="ascending" />
    					<xsl:sort select="@code" data-type="text" order="ascending" />
    					<xsl:variable name="code" select="@code" />
    					<xsl:for-each select="//utilisateur">
    						<xsl:sort select="points" data-type="number" order="descending"/>
    						<xsl:sort select="@code" data-type="text" order="ascending" />
    						<xsl:if test="@code = $code">
    							<xsl:value-of select="position()" /> -->
    							<xsl:value-of select="nom" /> - 
    							<xsl:value-of select="prenom" />
    							 [<xsl:value-of select="@code" />]
    							<br />
    						</xsl:if>
    					</xsl:for-each>
    				</xsl:for-each>
    			</body>
    		</html>
    	</xsl:template>
    </xsl:stylesheet>
    Merci encore

  7. #7
    Candidat au Club
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    je ne comprends pas bien l'expression :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="count(//utilisateur[points &gt; current()/points]) + 1"/>
    Comment est-il possible de sélectionner le classement d'un utilisateur sans avoir ordonné les utilisateurs par points au préalable ?

  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 bloublouc
    Comment est-il possible de sélectionner le classement d'un utilisateur sans avoir ordonné les utilisateurs par points au préalable ?
    Le seul tri à faire obligatoirement est celui par nom. Pour obtenir le classement, pas besoin de tri. Il suffit de sélectionner tous les utilisateurs dont le score est supérieur à celui de l'utilisateur courant (c'est le prédicat [points &gt; current()/points] qui se charge de cette condition), de les compter et d'ajouter 1 pour obtenir son classement.

    Quand on se lance dans XPath et XSLT, il ne faut pas hésiter à abandonner les schémas classiques qu'on utilise par réflexe avec des langages plus "classiques".

  9. #9
    Candidat au Club
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci à vous pour votre aide et vos explications
    Je cloture la discussion

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

Discussions similaires

  1. [XSLT] XSLT sort dans un for-each avec select sur un param
    Par tralloc dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 23/11/2012, 09h06
  2. Réponses: 2
    Dernier message: 27/09/2007, 14h04
  3. [XSLT]Sort sur un attribut dont la valeur est en param
    Par Trin dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 07/11/2005, 16h16
  4. [ XSLT ] probleme avec generate-id()
    Par Pi2 dans le forum XSL/XSLT/XPATH
    Réponses: 12
    Dernier message: 02/11/2005, 12h11
  5. [XSL] xsl:sort avec parametre et condition
    Par elraton dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 15/01/2005, 20h59

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