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 :

Grouper sur une valeur identique d'attribut et faire la somme sur l'attribut quantité [XSLT 1.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Août 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Août 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Grouper sur une valeur identique d'attribut et faire la somme sur l'attribut quantité
    Bonjour à tous,

    Je viens demander un peu d'aide pour réaliser un xslt qui me permette de regrouper des articles identiques et d'en réaliser la somme (quantité).

    Voici le fichier XML d'origine (gestion rayon bricolage):

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    <?xml  version='1.0' encoding='utf-8'?>
    <BOUTIQUE>
      <MAGASIN_BRICO name="Type" value="Nomenclature article" />
      <RAYONAGE>
        <OUTILLAGE>
          <FIELD name="Name" value="CATERPILLARD" />
          <FIELD name="Type" value="ELEC" />
          <FIELD name="CODE_CLIENT" value="CAT_145789" />
          <FIELD name="QTE" value="1" />
          <LIST_ARTICLE>
            <ITEM>
              <FIELD name="Name" value="SPEED Z100" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="P100255" />
              <FIELD name="QTE" value="4" />
            </ITEM>
            <ITEM>
              <FIELD name="Name" value="SPEED Z200" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="P100300" />
              <FIELD name="QTE" value="2" />
            </ITEM>
            <ITEM>
              <FIELD name="Name" value="SPEED Z100" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="P100255" />
              <FIELD name="QTE" value="2" />
            </ITEM>
          </LIST_ARTICLE>
        </OUTILLAGE>
        <OUTILLAGE>
          <FIELD name="Name" value="BOSCH" />
          <FIELD name="Type" value="ELEC" />
          <FIELD name="CODE_CLIENT" value="BOSCH_245896" />
          <FIELD name="QTE" value="1" />
          <LIST_ARTICLE>
            <ITEM>
              <FIELD name="Name" value="ACTIV G01" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="AC100500" />
              <FIELD name="QTE" value="4" />
            </ITEM>
            <ITEM>
              <FIELD name="Name" value="ACTIV G01" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="AC100500" />
              <FIELD name="QTE" value="2" />
            </ITEM>
            <ITEM>
              <FIELD name="Name" value="ACTIV G02" />
              <FIELD name="Type" value="ELEC" />
              <FIELD name="CODE_ARTICLE" value="AC100550" />
              <FIELD name="QTE" value="2" />
            </ITEM>
          </LIST_ARTICLE>
        </OUTILLAGE>
      </RAYONAGE>
    </BOUTIQUE>
    Avec mon XSLT j'obtiens un fichier csv pour une lecture dans Excel avec ce format:

    OUTILLAGE;CAT_145789;1
    ARTICLE;ELEC;P100255;4
    ARTICLE;ELEC;P100300;2
    ARTICLE;ELEC;P100255;2
    OUTILLAGE;BOSCH_245896;1
    ARTICLE;ELEC;AC100500;4
    ARTICLE;ELEC;AC100500;2
    ARTICLE;ELEC;AC100550;2

    Ma question porte sur les articles identiques en doublon, car j'aimerai au final les grouper en une ligne et avoir la somme dans l'attribut QTE.
    Ce que j'aimerai obtenir:

    OUTILLAGE;CAT_145789;1
    ARTICLE;ELEC;P100255;6
    ARTICLE;ELEC;P100300;2
    OUTILLAGE;BOSCH_245896;1
    ARTICLE;ELEC;AC100500;6
    ARTICLE;ELEC;AC100550;2

    Voici le code de mon XSLT complet, sans la gestion des regroupements:

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
      <xsl:output method="text" version="1.0" encoding="iso-8859-1" indent="yes" omit-xml-declaration="yes"/>
     
     
    <xsl:template match="/">
    <xsl:apply-templates select="//OUTILLAGE"/>
    </xsl:template>
     
    <xsl:template match="OUTILLAGE" >
    	<xsl:text>OUTILLAGE;</xsl:text>
    	<xsl:for-each select="FIELD">
    	<xsl:if test="@name!='Name'">
    	<xsl:if test="@name!='Type'">
     
        <xsl:value-of select="@value"/>
        <!--Suppression de la dernière ';'-->
        <xsl:if test="position() != last()">
          <xsl:text>;</xsl:text>
        </xsl:if>
     
    	</xsl:if>
    	</xsl:if>
      </xsl:for-each>
     
    	<xsl:text>
    </xsl:text>
     
     
      <xsl:for-each select="LIST_ARTICLE/ITEM">
     
      <xsl:text>ARTICLE;</xsl:text>
    	<xsl:for-each select="FIELD">
    	<xsl:if test="@name!='Name'">
    	<xsl:if test="@name!='CONFIG'">
      <xsl:value-of select="@value"/>
     
        <!--Suppression de la dernière ';'-->
          <xsl:if test="position() != last()">
            <xsl:text>;</xsl:text>
          </xsl:if>
    	  </xsl:if>
    	 </xsl:if>
      </xsl:for-each>
     
      <xsl:text>
    </xsl:text>
    </xsl:for-each>
     
    </xsl:template>
    </xsl:stylesheet>
    J'avoue que je sèche sur la manière de programmer ce type de regroupement et calcul
    Merci d'avance à tous pour votre aide sur ce sujet !

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Hello,

    En XSLT 1.0 c'est un peu compliqué, en fait. Voir la méthode dans la FAQ.

  3. #3
    Candidat au Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Août 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Août 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Grouper sur valeur identique d'attribut et somme sur les quantités
    Citation Envoyé par thelvin Voir le message
    Hello,

    En XSLT 1.0 c'est un peu compliqué, en fait. Voir la méthode dans la FAQ.
    Merci de suivre ma demande,

    En effet j'avais regardé ce FAQ au préalable, mais je n'ai pas su en comprendre de manière claire le principe pour le réappliquer à mon cas.
    La structure du fichier XML traitée en exemple dans le FAQ me semble assez éloignée de la mienne, ce qui fait que je ne sais pas trop par ou commencer.

    Je remercierai bien volontiers les courageux qui pourraient m'aider à poser les premières briques de ce casse tête !

    Merci pour votre aide,

  4. #4
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Je peux vous proposer une version qui ne peut être plus primitive, pas plus simple pourtant. Elle ne utilse que les concepts les plus simples. Elle a la mérite de mettre à nu la logique et le raisonnement explicit. Je ne peux vous priver le plaisir d'apprendre l'outil xsl:key en xslt par vous-même après la construction dessous soit claire. Elle se veut remplacer le bloc correspondant.
    Code xslt : 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
    <xsl:for-each select="LIST_ARTICLE/ITEM">
        <xsl:if test="count(preceding-sibling::ITEM[FIELD[@name = 'CODE_ARTICLE']/@value=current()/FIELD[@name='CODE_ARTICLE']/@value])=0">
            <xsl:text>ARTICLE;</xsl:text>
            <xsl:for-each select="FIELD">
            <!--
            <xsl:if test="@name!='Name'">
            <xsl:if test="@name!='CONFIG'">
            -->
            <xsl:if test="@name != 'Name' and @name != 'CONFIG' and @name !='QTE'">
                <xsl:value-of select="@value"/>
            </xsl:if>
            <xsl:if test="@name='QTE'">
                <xsl:value-of select="sum(
                    @value 
                    |
                    parent::ITEM/following-sibling::ITEM[
                        FIELD[
                            @name='CODE_ARTICLE'
                            and 
                            @value=current()/preceding-sibling::FIELD[@name='CODE_ARTICLE']/@value
                        ]
                    ]/FIELD[@name='QTE']/@value
                )" />
            </xsl:if>
            <!--Suppression de la dernière ';'-->
            <xsl:if test="position() != last()">
                <xsl:text>;</xsl:text>
            </xsl:if>
            </xsl:for-each>
            <xsl:text>&#x0d;&#x0a;</xsl:text>
        </xsl:if>
    </xsl:for-each>

  5. #5
    Candidat au Club
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Août 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Août 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Regroupement et somme sur les qantités
    Bonjour,

    Merci tsuji pour cette précieuse aide, cela marche plutôt bien en effet.
    Je vais essayé d'explorer également l'usage de xsl:key pour parfaire ma maitrise du langage.

    Merci, vous faites un super travail !

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

Discussions similaires

  1. faire un max sur une valeur varchar
    Par pelloq1 dans le forum Requêtes
    Réponses: 2
    Dernier message: 18/05/2009, 22h13
  2. Faire des sommes sur chaque valeur
    Par karidrou dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 17/11/2008, 10h39
  3. Filtrer sur une valeur d'un attribut XPATH
    Par jbnoel dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 31/01/2008, 10h00
  4. Trier sur une valeur de champs et non sur le nom du champs
    Par kamalkam dans le forum Langage SQL
    Réponses: 1
    Dernier message: 09/05/2006, 17h41
  5. [XSL]appliquer la fonction substring sur une valeur récupéré
    Par totoranky dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 22/02/2006, 17h21

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