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 :

groupement + fonction distinct-values() [XSLT 1.0]


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Par défaut groupement + fonction distinct-values()
    Bonsoir,
    soit le doc votes.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
    21
    22
     
    <?xml version="1.0"?>
    <Votes>											
    <Ville nom="Cachan" dept="94">
    <Bureau num="1">
    <Candidat nom="Toto" voix="3398"/><Candidat nom="Dupont" voix="6589"/>
    </Bureau>
    <Bureau num="2">
    <Candidat nom="Toto" voix="5645"/><Candidat nom="Dupont" voix="4090"/>
    </Bureau>
    </Ville>
    <Ville nom="L’Hay" dept="94">
    <Bureau num="1">
    <Candidat nom="Toto" voix="2067"/><Candidat nom="Dupont" voix="4089"/>
    </Bureau>
    </Ville>
    <Ville nom="Bagneux" dept="92">
    <Bureau num="1">
    <Candidat nom="Toto" voix="4723"/><Candidat nom="Dupont" voix="5167"/>
    </Bureau>
    </Ville>
    </Votes>
    Question:
    Écrivez un programme XSLT qui calcule la somme des voix pour chacun des candidats. Le résultat de la transformation donnera le document :
    <Votes>
    <Candidat nom="Toto">15833</Candidat>
    <Candidat nom="Dupont">19935</Candidat>
    </Votes>

    Mon essai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ...
    xsl:template match="Votes">
    <votes>
    	<xsl:for-each select="Ville/Bureau/Candidat">
    	<xsl:if test="not(@nom=following::Candidat/@nom)">
    	<xsl:variable name="nom" select="@nom"/>
    	<candidat nom="{@nom}"><xsl:value-of select="sum(//Candidat[@nom=$nom]/@voix)"/> </candidat>
    	</xsl:if>
    	</xsl:for-each>
    	</votes>
    	</xsl:template>
    ...
    çà marche tés bien. je veux une autre solution utilisant la fonction:
    distinct-values ()
    merci d'avance

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    distinct-values() c'est une fonction pour XSLT 2.0, pas 1.0
    Mais ok, très bien, il suffit d'utiliser du 2.0.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <root>
      <a>Hello</a>
      <a>Bonjour</a>
      <a>Hello</a>
    </root>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <xsl:template match="/">
      <root>
        <xsl:for-each select="distinct-values(//a)">
          <a>
            <xsl:value-of select="."/>
          </a>
        </xsl:for-each>
      </root>
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éclairé
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Par défaut
    voici un code utilisant la fonction: distinct-values:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="2.0">
        <xsl:template match="Votes">
            <votes>
            <xsl:for-each select="distinct-values(//Candidat/@nom)">
                <candidat nom= "{.}">
                   <xsl:value-of select="sum(//Candidat[@nom=.]/@voix)" />
                </candidat>
            </xsl:for-each>
            </votes>
        </xsl:template>
    </xsl:stylesheet>
    érreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     ...
    Description: Leading '/' cannot select the root node of the tree containing the context item: the context item is an atomic value
    Emplacement de début: 8:0
    URL: http://www.w3.org/TR/xpath20/#ERRXPTY0020

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Marrant. C'est vrai que moi j'aurais utilisé xsl:for-each-group au lieu de distinct-values(), et donc le problème se poserait pas. Je m'attendais pas à ce que XPath 2.0 nous fasse un coup pareil.

    Il existe peut-être une solution triviale, mais si ce n'est pas le cas, il suffit de mettre l'ensemble des candidats dans une variable, avant de commencer le for-each. Comme ça on peut y accéder avec cette variable au lieu de //

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:variable name="candidats" select="//Candidat"/>
    Reste à régler le problème qui apparaît ensuite. La solution est la même.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre Expert
    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
    Par défaut
    Citation Envoyé par win_ubuntu Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="sum(//Candidat[@nom=.]/@voix)" />
    Je doute que cette partie-là fasse ce que tu souhaites :
    Là tu testes que l'attribut nom de l'élément Candidat a la même valeur que le contenu texte de ce même élément Candidat.

    Toi ce que tu veux c'est le comparer à l'attribut nom actuellement sélectionné. Pour ça, il faut que tu passes soit par une variable, soit par la fonction XSL current():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="sum(//Candidat[@nom=current()]/@voix)" />

  6. #6
    Membre éclairé
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2010
    Messages
    212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 212
    Par défaut
    merci infiniment les gars; voila la solution, çà marche trés bien:
    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
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="2.0">
        <xsl:template match="Votes">
            <votes>
                <xsl:variable name="candidats" select="//Candidat"/>
                <xsl:for-each select="distinct-values(//Candidat/@nom)">
                    <candidat nom= "{.}">
                        <xsl:value-of select="sum($candidats[@nom=current()]/@voix)" />
                    </candidat>
                </xsl:for-each>
            </votes>
        </xsl:template>
    </xsl:stylesheet>
    mais remarquez vous que le parser a accepté cette ligne :
    dans la première solution, et l'a refusé dans la deuxième!.

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par win_ubuntu Voir le message
    mais remarquez vous que le parser a accepté cette ligne :
    dans la première solution, et l'a refusé dans la deuxième!.
    Ben oui, pour la raison indiquée.
    Un XPath s'évalue toujours à partir du contexte en cours.
    Lorsqu'on fait un for-each, à l'intérieur de la boucle, le contexte en cours est l'élément pour lequel on fait la boucle. C'est pour ça qu'on peut utiliser le . dans <candidat nom= "{.}">.

    Or un XPath qui commence par / signifie "commence déjà par remonter au document," et par "le document" on veut dire "le document qui contient le contexte en cours."
    Si le for-each se fait sur un ensemble d'éléments du document,comme par exemple //machin , ça marche très bien.
    Mais dans le cas de distinct-values(), on ne sélectionne pas des éléments. On extrait la valeur des éléments, sous forme de strings, et on en renvoie la liste d'occurrences uniques. Une string n'appartient à aucun document, comme il le dit c'est un atome. Et donc commencer par / n'a pas de sens si le contexte est une simple string, obtenue avec distinct-values().


    La solution correcte à ce besoin est <xsl:for-each-group>, et non pas distinct-values(). Ainsi le problème ne se poserait pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. [XPATH] distinct values
    Par yannick29000 dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 19/08/2010, 15h11
  2. appel d'une fonction dans value
    Par ASP.net dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 03/07/2008, 15h08
  3. [xslt 1.0] - distinct value sur un attribut
    Par jacquesh dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 30/10/2007, 07h38
  4. 4D Open for 4D:pb OP Distinct Values
    Par Kendael dans le forum 4D
    Réponses: 3
    Dernier message: 20/04/2007, 12h43
  5. Fonction DISTINCT ne fonctionne pas sur une date
    Par cramouille dans le forum Access
    Réponses: 5
    Dernier message: 25/10/2006, 15h42

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