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 synthèse regroupée par valeurs


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut XSLT synthèse regroupée par valeurs
    bonjour
    je débute sur xml et xslt et je dois avouer que j e rencontre quelque soucis de compréhension.

    Je vous expose mon problème.

    Je dispose d'un fichier XML pour lequel je désire que soit effectué un traitement via un fichier xslt.

    Mon fichier xml est le récapitulatif de valeur de paramètres sur une période.

    Je souhaite que le traitement suivant soit effectué pour chacun des paramètres :
    - avoir la valeur minimale obtenue ainsi que la date
    - avoir la valeur maximale obtenue ainsi que la date
    - avoir la valeur moyenne
    - avoir le nombre d itérations


    Voici un aperçu de mon 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
    <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
    <GeneratedReport>
        <Interval Start="2013/04/01 00:00:00.000" End="2013/04/01 23:59:59.000">
    <EngTm Mnemonic="AAA" EngValue="10" Description="description A" Date="2013/04/01 00:00:05.568"/>
    <EngTm Mnemonic="BBB" EngValue="20" Description="description B" Date="2013/04/01 00:00:05.568"/>
    <EngTm Mnemonic="CCC" EngValue="20" Description="description C" Date="2013/04/01 00:00:05.568"/>
    <EngTm Mnemonic="AAA" EngValue="20" Description="description A" Date="2013/04/01 00:00:15.568"/>
    <EngTm Mnemonic="BBB" EngValue="22" Description="description B" Date="2013/04/01 00:00:15.568"/>
    <EngTm Mnemonic="CCC" EngValue="19" Description="description c" Date="2013/04/01 00:00:15.568"/>
    <EngTm Mnemonic="AAA" EngValue="20" Description="description A" Date="2013/04/01 00:00:25.568"/>
    <EngTm Mnemonic="BBB" EngValue="23" Description="description B" Date="2013/04/01 00:00:25.568"/>
    <EngTm Mnemonic="CCC" EngValue="21" Description="description c" Date="2013/04/01 00:00:25.568"/>
    <EngTm Mnemonic="AAA" EngValue="21" Description="description A" Date="2013/04/01 00:00:35.568"/>
    </Interval>
    </GeneratedReport>

    ---------------------------

    le résultat que j attends serait

    AAA 10 2013/04/01 00:00:05.568 21 2013/04/01 00:00:35.568 17.75 4
    BBB 20 2013/04/01 00:00:05.568 22 2013/04/01 00:00:25.568 21.00 3
    CCC 19 2013/04/01 00:00:15.568 21 2013/04/01 00:00:25.568 20.00 3



    Je vous remercie pour vos prochaines réponses et espère que mon demande est suffisamment explicite

    amicalement

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Ça peut être assez compliqué car il s'agit d'un regroupement de tous les paramètres AAA, tous les BBB, tous les CCC, etc.

    Tu as le droit d'utiliser XSLT 2.0 ou tu es coincé en XSLT 1.0 ?

    Avec le 2.0, c'est facile, juste une question de <xsl:for-each-group>
    Avec le 1.0, ça va être la mort, il faut un regroupement Muench.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Merci de votre réponse non je ne suis pas limité au 1.0

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Alors utilise le 2.0

    Et un <xsl:for-each-group select="EngTm" group-by="@Mnemonic">.

    Pour plus de détails, montre-nous déjà le genre de choses que tu sais faire en XSLT.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    pour l instant je n ai pas encore fait quoique ce soit sous xslt

    Je traitais le fichier avec vba mais la lourdeur du traitement et la lenteur m ont fait réfléchir à une autre solution

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Alors c'est parti vers les tutoriels. Ou un bon bouquin, moi j'ai appris comme ça, je trouve ça mieux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    Une fois que tu auras trié par groupe (avec la méthode donnée par thelvin), il te suffira d'utiliser les méthodes XPath pour ce que tu veux afficher :
    - avoir la valeur minimale obtenue ainsi que la date -> fonction min()
    - avoir la valeur maximale obtenue ainsi que la date -> fonction max()
    - avoir la valeur moyenne -> fonction avg()
    - avoir le nombre d itérations -> fonction count()

  8. #8
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Bonjour

    merci pour ces précieuses informations .

    Débutant dans ce type de "langage" j'évolue en tatonnant.

    Je n'hésiterai pas à revenir vers vous afin de vous communiquer l'état d'avancement de mon travail et peut être de vous solliciter à nouveau.


    cordialement

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Voilà j'ai appliqué vous différents conseils et j'arrive désormais à afficher chaque "Mnémonic" distinct.
    Cependant lorsque j utilise la fonction moyenne, seule la première valeur s'affiche et non la moyenne des valeurs.
    Je vous affiche ci dessous le code que j 'utilise.

    Nota : pour l instant je ne souhaite afficher que la moyenne & l intil=tulé du mnémonique

    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
    <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="title"/>
    <xsl:output indent="yes"  method="text"/>
    <xsl:template match="/">
    # <xsl:value-of select="$title"/>
     
    # Date Start <xsl:value-of select="//Interval/@Start"/> End <xsl:value-of select="//Interval/@End"/><xsl:text>
    </xsl:text>
    <xsl:for-each-group select="//EngTm" group-by="@Mnemonic">
     <xsl:for-each select="current-group()">
     
     
        </xsl:for-each>
            <xsl:value-of select="@Mnemonic"/>, <xsl:value-of select="avg(current-group()/@EngValue)"/><xsl:text>
     </xsl:text>
        </xsl:for-each-group>
     
    </xsl:template>
    </xsl:transform>
    En dépit de mes recherches, je ne vois pas où je fais une erreur.


    merci d'avance pour votre aide et vos éclaircissements

  10. #10
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Moi avec ton XML et ton XSL (avec Saxon Home Edition,) j'obtiens :
    Code plaintext : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # 
     
    # Date Start 2013/04/01 00:00:00.000 End 2013/04/01 23:59:59.000
    AAA, 17.75
     BBB, 21.666666666666668
     CCC, 20

    Ce qui m'a l'air conforme à tes attentes.
    Tu es sûr que c'est bien ce XSLT-là que tu utilises ? Ça fait quoi si tu ajoutes un "bonjour" quelque part ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    bonsoir et merci de votre aide

    j ai ajouté bonjour dans la boucle for each et j ai bonjour qui s inscrit à chaque fois donc cela semble ok

    il semblerait que ce soit la fonction average qui ne fonctionne pas

  12. #12
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Je viens de m apercevoir que j'ai fait une erreur.

    en fait le fichier xml que j exploite avec ce xsl est un peu plus complexe et surtout est constitué de bien plus de "Mnemonique".

    En fait, le fichier que j'ai ne contient qu une valeur pour chacun des mnémonics d'où ce résultat valeur moyenne = valeur max = valeur min .

    Je viens de lancer la génération d un nouveau fichier source xml qui contiendra plusieurs mesures pour chaque mnemo.

    J'aurai la réponse dès demain

  13. #13
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Comme je le signalais hier j ai fais une petite erreur.

    Ce matin le résultat du traitement est bien conforme à mon attente .

    J'ai bien la valeur min max et moyenne.

    Je dois opérer un petit traitement afin que ces valeurs aient la forme ##,## ( 2 chiffres après la virgule )
    Je devrais trouver cela dans les cours et tuto.

    Par contre je ne sais pas comment récupérer la date ( & heure ) pour les valeurs min et max

    Est il possible d'associer la recherche de cette valeur min avec son horodatage ?


    cordialement

  14. #14
    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
    Pour le formattage du nombre, tu as apparement la fonction format-number(...), faut voir si elle dispo dans ton parseur XSL.

    Pour avoir la date associée à la valeur min c'est tout simple.
    Mettons que tu aies stocké la valeur min dans une variable, il te suffit d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    current-group()[@EngValue = $min]/@Date
    Par contre, si tu as plusieurs fois la valeur minimal, ça te retournera une liste de date.

    Si tu veux récupérer la date de la première occurence de la valeur minimale, tu peux écrire : (current-group()[@EngValue = $min]/@Date)[1].

    Si tu veux récupérer la première date (la plus petite) à laquelle la valeur minimale apparaît, il faut écrire min(current-group()[@EngValue = $min]/@Date) (ça marche parce que tes dates sont bien formattées : YYYY/MM/dd hh:mm:ss.SSS, si c'était dd/MM/YYYY ce serait plus compliqué).

  15. #15
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Rebonjour
    voilà mon script me permet désormais d obtenir les valeurs à 2 chiffres après la virgule ( en utilisant comme conseillé les variables )

    Cependant je n arrive pas à faire apparaître les dates.
    Je poste ci après le script afin que vous puissiez vérifier et en toute vraisemblance me corriger

    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
    <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="title"/>
    <xsl:output indent="yes"  method="text"/>
    <xsl:template match="/">
    # <xsl:value-of select="$title"/>
     
    # Date Start <xsl:value-of select="//Interval/@Start"/> End <xsl:value-of select="//Interval/@End"/><xsl:text>
    </xsl:text>
    <xsl:for-each-group select="//EngTm" group-by="@Mnemonic">
    <xsl:for-each select="current-group()">
     
     
    </xsl:for-each>
     
    <xsl:variable name="mini" select="min(current-group()/@EngValue)"/>
    <xsl:variable name="maxi" select="max(current-group()/@EngValue)"/>
    <xsl:variable name="moye" select="avg(current-group()/@EngValue)"/>
    <xsl:variable name="datemini" select="current-group()[@EngValue = $mini]/$Date"/>         
     
    <xsl:value-of select="@Mnemonic"/><xsl:text> </xsl:text><xsl:value-of select="format-number($mini, '#.00')"/> <xsl:value-of select="@datemini"/>
    <xsl:text> </xsl:text><xsl:value-of select="format-number($maxi, '#.00')"/>
    <xsl:text> </xsl:text><xsl:value-of select="format-number($moye, '#.00')"/><xsl:text>
    </xsl:text>       
     
    </xsl:for-each-group>
     
    </xsl:template>
    </xsl:transform>

    J'ai utilisé une variable "datemini" qui devrait recevoir la date et l heure du moment où la valeur était à son minimum . Mais ca ne fonctionne pas

    J'ai essayé également :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:variable name="datemini" select="(current-group()[@EngValue = $mini]/@Date)[1]"/>
    Code xpath : Sélectionner tout - Visualiser dans une fenêtre à part
    min(current-group()[@EngValue = $mini]/@Date)

    Mais sans plus de résultat

    cordialement

  16. #16
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Les variables s'accèdent avec $, pas @
    @ c'est pour les attributs, c'est un axe de sélection.
    $ indique juste "on part de ce qu'il y a dans la variable de ce nom"
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    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
    Comme le dit thelvin, tu as inversé les notations pour les attributs et pour les variables à ces deux endroits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:variable name="datemini" select="current-group()[@EngValue = $mini]/$Date"/>
    
    <xsl:value-of select="@datemini"/>
    De plus, je te déconseille fortement d'utiliser un ensemble de noeuds (<xsl:variable name="datemini" select="current-group()[@EngValue = $mini]/@Date"/>) alors que tu ne veux qu'une seule date.
    Il vaut mieux que tu sois sûr de ce que tu veux obtenir (soit la première date rencontrée dans l'ordre du XML, soit la plus petite date (la plus ancienne) en faisant un min), ça t'évitera des interrogations potentielles par la suite, et c'est beaucoup plus propre.

  18. #18
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    bonsoir et merci de vos réponses

    En fait après avoir poster mon dernier message je me suis aperçu de mon erreur et l ai corrigé : une erreur de débutant que je suis

    Le résultat est désormais conforme à mon attente.
    Etant à mon domicile je ne suis pas en mesure de mettre le code complet.

    Je ferais cela dès mardi et clôturerai le sujet.

    Je vous remercie de votre aide

    cordialement

  19. #19
    Membre confirmé
    Inscrit en
    Mai 2013
    Messages
    86
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 86
    Par défaut
    Comme promis mais avec un peu de retard je poste mon code
    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
    	<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:param name="title"/>
    	<xsl:output indent="yes"  method="text"/>
    	<xsl:template match="/">
    	# <xsl:value-of select="$title"/>
     
    	# Date Start <xsl:value-of select="//Interval/@Start"/> End <xsl:value-of select="//Interval/@End"/><xsl:text>
    	</xsl:text>
    	<xsl:for-each-group select="//EngTm" group-by="@Mnemonic">
    	<xsl:for-each select="current-group()">
     
     
    	</xsl:for-each>
     
    	<xsl:variable name="mini" select="min(current-group()/@EngValue)"/>
    	<xsl:variable name="maxi" select="max(current-group()/@EngValue)"/>
    	<xsl:variable name="moye" select="avg(current-group()/@EngValue)"/>
     
     
    	<xsl:value-of select="@Mnemonic"/><xsl:text> </xsl:text><xsl:value-of select="format-number($mini, '#.00')"/> 
    	<xsl:text> </xsl:text><xsl:value-of select="(current-group()[@Engvalue = $mini]/@Date[1]"/>
    	<xsl:text> </xsl:text><xsl:value-of select="format-number($maxi, '#.00')"/> 
    	<xsl:text> </xsl:text><xsl:value-of select="(current-group()[@Engvalue = $maxi]/@Date[1]"/>
    	<xsl:text> </xsl:text><xsl:value-of select="format-number($moye, '#.00')"/><xsl:text>
    	</xsl:text>       
     
    	</xsl:for-each-group>
     
    	</xsl:template>
    	</xsl:transform>

    Par contre je suis confronté à un problème .

    Le fichier XML est réalisé par une application et le fichier xsl est intégré automatiquement.

    Si j 'ai bien le résultat escompté lorsque le fichier récupère des données sur de courte période, il ne s'exécute plus lorsqu'il s'agit de longue période.



    Je souhaite donc disculper mon fichier XSL en essayant d'intégrer ce fichier au sein même de mon fichier XML

    J'ai dans cette optique inséré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?xml-stylesheet type="text/xsl" href="test_cu.xsl"?>
    juste après la première ligne de mon fichier XML et tenté d'ouvrir ce dernier à partir des explorateurs IE et Firefox

    J'obtiens les messages d'erreur suvant :

    Message d’erreur sous IE : Le mot clé xsl:template ne peut pas contenir xsl:for-each-group.
    Message d’erreur sous firefox : Erreur lors de la transformation XLST : Échec de transformation XSLT.

    Suis je dans l 'erreur en procédant de cette manière

    merci

    cordialement

  20. #20
    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 raphael75015 Voir le message
    juste après la première ligne de mon fichier XML et tenté d'ouvrir ce dernier à partir des explorateurs IE et Firefox
    [...]
    Suis je dans l 'erreur en procédant de cette manière
    Oui et non.

    Oui parce que IE comme FF ne prennent pas en charge le XSL 2.0, à l'heure actuelle. Uniquement le XSL 1.0 (et XPath 1.0).
    Il faudrait donc adapter tout ton code pour le passer en 1.0 et ce ne serait pas de la tarte...

    Non parce que c'est une façon de faire qui serait viable s'il n'y avait pas cette limitation.

    Ce que tu peux faire par contre c'est récupérer ton fichier XML d'un côté, avoir ton fichier XSL de l'autre et appeller toi-même ton parseur en lui passant le XML et le XSL, pour voir ce que ça donne.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [XSLT 1.0] Générer des index en regroupant par valeurs d'attributs
    Par hilyd dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 17/02/2011, 15h10
  2. [XSLT 2.0] Regrouper par valeur d'attribut + compteur
    Par karote dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 24/01/2011, 14h15
  3. Regroupement par valeurs
    Par laurentabj dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 28/09/2007, 12h13
  4. Réponses: 3
    Dernier message: 13/12/2006, 09h19
  5. [XSLT]Regroupement par attribut.
    Par zserdtfg dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 08/12/2006, 11h35

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