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] Grouper, trier, compiler une donnée spécifique - trop difficile pour moi


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut [XSLT] Grouper, trier, compiler une donnée spécifique - trop difficile pour moi
    Bonjour,

    Débutant ici :)

    Utilisant ce fichier XML,
    http://pages.infinit.net/plague/top500.xml

    Comment je peux faire un fichier XSLT qui va produire cette sortie:


    Je demande pas nécessairement un fichier XSLT complet, juste quelques astuces pour me pointer dans la bonne direction, s'il vous plait. J'imagine que vous aller mentionner l'algorithme de Muench et xsl:key mais mes attemptives avec ça n'ont pas porté fruit.

    J'ai encore un long bout à faire... voici mon fichier XSLT en progrès.

    Merci! :)
    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
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:top500="http://www.top500.org/xml/top500/1.0">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="sites-by-country" match="top500:site" use="top500:country"/>
    <xsl:template match="/top500:list">
    <html>
    <head>
    <title>ALL COUNTRIES IN TOP 500</title>
    </head>
    <body>
    <table style="text-align:left">
    <tr style="background-color=7777FF">
    <th width="150">Countries</th>
    <th>Count</th>
    <th>Share %</th>
    </tr>
    <xsl:for-each select="top500:site/top500:country">
    <xsl:sort select="top500:country"/>
    <tr>
    <td>
    <xsl:value-of select="."/>
    </td>
    <td>
    <xsl:value-of select="count(//top500:site[top500:country=current()])"/>
    </td>
    </tr>
    </xsl:for-each>
    </table>
    </body>
    </html>
    </xsl:template>
     
    </xsl:stylesheet>

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Pour commencer, vire les styles, la présentation, la table, tout ce qui est cosmétique.
    Fais ton résultat en vrac, et quand tu as trouvé ta méthode, là tu ajoutes du style, des couleurs, et des petits cœurs roses qui font joli.

    Effectivement, c'est une méthode Muench. Et effectivement, il faut regrouper les <site> qui ont le même <country>. Ta clé est donc correcte, tu avais bien compris cela, mais tu ne sais pas t'en servir.

    En résumé :

    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
    <xsl:template match="/">
      <!-- Pour chaque country différent, sélectionner son premier site -->
      <xsl:for-each select="//top500:site[generate-id(.) = generate-id(key('sites-by-country', top500:country))]">
        <!-- Les classer dans l'ordre -->
        <xsl:sort select="top500:country"/>
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </xsl:template>
     
    <xsl:template match="top500:site">
      <xsl:variable name="country" select="top500:country"/>
      <!-- Afficher le nom du pays -->
      <xsl:value-of select="$country"/>
      <!-- Afficher combien de sites sont dans ce pays -->
      <xsl:value-of select="count(//top500:site[top500:country = $country])"/>
    </xsl:template>
    Là j'ai repris ton code, mais à ta place j'utiliserais le préfixe t: au lieu de top500:
    Se concentrer sur le contenu utile, tout ça...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    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
    une amélioration (qui sera notable du point de vue performance...)

    plutôt que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      <xsl:value-of select="count(//top500:site[top500:country = $country])"/>
    écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      <xsl:value-of select="count(key('sites-by-country', $country) )"/>

  4. #4
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Bon, je suis pas un pro en XSL (comparé à Erwy par exemple), mais je dirais que ton XSL est plutôt pas mal déjà.

    Par contre il faut changer l'élément sur lequel tu fais le tri : c'est pas "top500:country" mais "." :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <xsl:for-each select="top500:site/top500:country">
    <xsl:sort select="."/>
    Du moins sous Firefox ça fonctionne avec le ".".

    Sinon, j'utiliserais la fonction distinct-values pour ne récupérer que les pays différents (pas testée car ne fonctionne pas sous FF) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="distinct-values(top500:site/top500:country)">
    A partir de là tu as déjà tes 2 premières colonnes.

    Pour la 3ième, c'est une simple opération :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <!-- variable à déclarer en dehors (avant) de la boucle -->
    <xsl:variable name="total" select="count(//top500:site/top500:country)" />
    ...
    <!-- Dans la boucle -->
    <xsl:variable name="count" select="count(//top500:site[top500:country=current()])" />
    <xsl:value-of select="$count * 100 div $total"/>
    Après pour ce qui est de l'optimisation du code, ça doit pas être optimal
    Mais au moins ça marche chez moi (sauf le distinct-values vu que je teste sous FF) et ça s'affiche instantanément.

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Loceka Voir le message
    Sinon, j'utiliserais la fonction distinct-values pour ne récupérer que les pays différents (pas testée car ne fonctionne pas sous FF) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:for-each select="distinct-values(top500:site/top500:country)">
    Effectivement c'est à savoir, mais attention, distinct-value() c'est du XPath 2, autrement dit pour du XSLT 2.0.
    C'est très souvent pour ça qu'en XSLT 1.0 on s'emmerde avec la méthode Muench.

    Et effectivement Firefox ne gère pas XSLT 2.0, d'ailleurs si on veut XSLT 2.0 il faut le déclarer dans l'attribut version de la stylesheet.

    Citation Envoyé par Loceka Voir le message
    Après pour ce qui est de l'optimisation du code, ça doit pas être optimal
    Mais au moins ça marche chez moi (sauf le distinct-values vu que je teste sous FF) et ça s'affiche instantanément.
    En même temps, avec 500 entrées et sans calcul récursif dupliqué, les performances, bon... Ça peut pas être mauvais, à part avec une calculatrice...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Ceci explique cela alors... je croyais juste que firefox n'avait pas implémenté toutes les fonctions XPath.

    Sur w3school ils ne précisent pas à quelle version est associée chaque fonction.

    Ben sans passer par Muench, je vois une solution en Javascript si l'affichage est forcément du HTML lu par un navigateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var pays = new Array();
    pays["<xsl:value-of select="."/>"] = <xsl:value-of select="count(//top500:site[top500:country=current()])"/>;
    Après, un simple parcourt de la table de hashage permet de construire le tableau HTML :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (var p in pays) {
      // p -> country
      // pays[p] -> count
      // pays[p] * 100 / total -> share
    }

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci énormément thelvin, ça a marché du premier coup!

    Pour la colonne de pourcentage, j'ai juste eu à faire la même chose et diviser par cinq.

    J'ai un cours de HMTL/CSS en ce moment, alors ta remarque sur les coeurs roses m'a fait énormément rire, car mon prof de HTML (une jeune femme, très "artiste") aime BEAUCOUP les coeurs roses et les frivolités.

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Maintenant supposons que j'aimerais trier par nombre d'ordinateurs (le COUNT dans le tableau) au lieu d'ordre alphabétique?

    J'ai essayé de placer ceci dans le sort,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:sort select="count(//top500:site[top500:country = $country])"/>
    Mais pour cela j'ai besoin de la variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:variable name="country" select="top500:country"/>
    et j'ai pas le droit de placer cette ligne avant xsl:sort (xsl:sort doit immédiatement suivre for-each)

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Laissez tomber - Finalement j'ai réglé mon problème grace a la fontion
    current().

    Ca m'a permis de laisser tomber xsl:variable.

    Maintenant je peux tout faire mes calculs dans un seul xpath (dans xsl:sort)

Discussions similaires

  1. [XL-2007] Trier suivant une liste spécifique en VBA
    Par duduSKS dans le forum Macros et VBA Excel
    Réponses: 18
    Dernier message: 14/06/2013, 19h31
  2. Licence trop difficile pour moi ?
    Par jeanmini dans le forum Etudes
    Réponses: 6
    Dernier message: 14/09/2010, 21h05
  3. une requête multiple trop compliquée pour moi
    Par Invité dans le forum Requêtes
    Réponses: 1
    Dernier message: 24/08/2010, 22h38
  4. [AC-2007] Mise à jour d'une donnée spécifique dans la BD
    Par christophe31 dans le forum VBA Access
    Réponses: 4
    Dernier message: 23/03/2010, 11h23
  5. Réponses: 1
    Dernier message: 18/04/2006, 23h16

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