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 :

Somme totale... Défi !


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 34
    Points : 29
    Points
    29
    Par défaut Somme totale... Défi !
    Salut !

    Ceci est un exemple inventé qui relate mon problème...
    Donc imaginons, j'ai une bibliothèque de livres. Chaque livre est décrit dans un fichier XML. J'ai un autre fichier XML qui référence tous les livres de la bibliothèque :

    ListingBiblio.xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <BIBLIO>
      <LIVRE ref="051"/>
      <LIVRE ref="062"/>
      <LIVRE ref="840"/>
      ...
    </BIBLIO>
    Exemple : fichier Livres/051.xml :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <LIVRE ref="051" intitulé="blabla">
      <CHAP titre="blabla">
        kjkgsdjhg<IMG src="..."/>sdc
        lkushdckshck<IMG src="..."/>kdhsckjshc
      </CHAP>
      <CHAP titre="blibli">
      ...
      </CHAP>
    </LIVRE>
    Maintenant ce que je voudrais c'est afficher le nombre total d'images (compte le nombre de balises images dans tous les fichiers livre.xml) dans la bibliothèque. Pour cela je fais une xsl qui va s'appliqué au fichier ListingBiblio.xml, et c'est là que j'ai du mal...

    NombreTotalImages.xsl (extrait)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <xsl:for-each select="LIVRE">		
       <xsl:variable name="LivreCourant">	
          <xsl:value-of select="@ref"/>
       </xsl:variable>
       Livre <xsl:value-of select="@ref"/> : 
       <xsl:call-template name="NbreImagesDuLivre">
           <xsl:with-param name="RefLivreCourant" select="$LivreCourant"/>
       </xsl:call-template>	
       images <br/>
    </xsl:for-each>
    Le template NbreImagesDuLivre serait ici assez simple du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <xsl:template name="NbreImagesDuLivre">
      <xsl:param name="RefLivreCourant"/>
      <xsl:variable name="FichierLivre">
         <xsl:value-of select="$RefLivreCourant"/>.xml
      </xsl:variable>
      <xsl:value-of select="count(document(../Livres/$FichierLivre)//*/IMG)"/>
    </xsl:template>
    Je n'ai pas testé cet exemple car il est fictif et dans mon pb réel le template fonctionne très bien (il s'agit d'un calcul plus complexe, une grosse "fonction" qui va compter certains trucs dans chaque fichier "livre.xml")

    Bref mon problème se situe au niveau de la somme total. Dans le cas présent j'obtient en sortie :
    livre 051.xml : 5 images
    livre 062.xml : 7 images
    livre 840.xml : 3 images

    Et moi j'aimerais afficher :
    Bibliothèque : 15 images

    (5+7+3)

    Et là je n'y arrive plus, je sens bien qu'il faut utiliser de la recursivité mais je n'arrive pas à mettre en oeuvre...HELP !

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 34
    Points : 29
    Points
    29
    Par défaut
    J'ai imaginé un début de solution mais ça ne marche pas non plus, peut être à peu de choses...

    Je sais qu'en xsl je peux faire <xsl:value-of select="1+2+3"/> ce qui va donné 6 à l'affichage.

    Pour mon problème j'ai stocké dans une variable 'chaine' la somme à éffectuer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <xsl:variable name="Chaine">			 
       <xsl:for-each select="LIVRE">       
          <xsl:variable name="LivreCourant">    
             <xsl:value-of select="@ref"/> 
          </xsl:variable> 
          <xsl:call-template name="NbreImagesDuLivre"> 
              <xsl:with-param name="RefLivreCourant" select="$LivreCourant"/> 
          </xsl:call-template>  
          <xsl:if test="position()!=last()">					+
          </xsl:if>					
       </xsl:for-each>	
    </xsl:variable>
    Dans ce cas, la variable 'chaine' vaut '5+7+3' mais lorsque je fais <xsl:value-of select="$chaine"/> il n'affiche pas 15 mais '5+7+3', n'y a -t-il pas moyen de dire au processeur qu'il fait prendre en compte l'expression numérique de $chaine et non pas littérale...?

  3. #3
    Membre du Club Avatar de philemon_siclone
    Inscrit en
    Septembre 2003
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 67
    Points : 67
    Points
    67
    Par défaut
    Je relève le défi!

    Voici une solution recursive (testée avec le processeur XSLT de XmlSpy):
    1) le document 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    <BIBLIO>
      <LIVRE ref="051" intitulé="blabla">
        <CHAP titre="blabla">
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
        </CHAP>
        <CHAP titre="blibli">
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
          <IMG src="youplaboum"/>
        </CHAP>
      </LIVRE>
      <LIVRE ref="0523" intitulé="blabla">
        <CHAP titre="blabla">
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
        </CHAP>
        <CHAP titre="blibli">
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
          <IMG src="youplaboum"/>
        </CHAP>
      </LIVRE>
      <LIVRE ref="0589" intitulé="blabla">
        <CHAP titre="blabla">
          <IMG src="tralalaitou"/>
          <IMG src="youplaboum"/>
        </CHAP>
        <CHAP titre="blibli">
          <IMG src="tralalaitou"/>
        </CHAP>
      </LIVRE>
    </BIBLIO>
    2) la feuille 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <xsl:template match="BIBLIO">
        <html>
          <HEAD>
            <TITLE>Document Title</TITLE>
          </HEAD>
          <body>
            <xsl:for-each select="LIVRE">       
       Livre <xsl:value-of select="@ref"/> : 
       <xsl:call-template name="NbreImagesDuLivre">
                <xsl:with-param name="livreCourant" select="."/>
              </xsl:call-template>    
       images <br/>
            </xsl:for-each>
            <xsl:call-template name="somme">
              <xsl:with-param name="noeuds" select="LIVRE"/>
            </xsl:call-template>
          </body>
        </html>
      </xsl:template>
     
      <xsl:template name="somme">
        <xsl:param name="noeuds"/>
        <xsl:choose>
          <xsl:when test="not($noeuds)">
            <xsl:value-of select="0"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:variable name="sommeDesSuivants">
              <xsl:call-template name="somme">
                <xsl:with-param name="noeuds" select="$noeuds[position()!=1]"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="nbImg">
              <xsl:call-template name="NbreImagesDuLivre">
                <xsl:with-param name="livreCourant" select="$noeuds[1]"/>
              </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="$sommeDesSuivants+$nbImg"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>
     
      <xsl:template name="NbreImagesDuLivre">
        <xsl:param name="livreCourant"/>
        <xsl:value-of select="count($livreCourant/*/IMG)"/>
      </xsl:template>
    </xsl:stylesheet>
    3) le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Livre 051 : 5 images 
    Livre 0523 : 7 images 
    Livre 0589 : 3 images 
    15
    Par contre, je n'ai pas trouvé de réponse à ta seconde question (sur l'évaluation arithmetique d'une variable). Si quelqu'un a une solution, ça m'interesse aussi.

    Tcho,

    Phil

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 34
    Points : 29
    Points
    29
    Par défaut
    Je viens de regarder ta solution et c'est bien qqchose dans ce style que je cherchais !
    Je déprimais hier, j'arrivais plus à avancer dans mon projet... mais là ça va nettement mieux
    En voyant la solution, ça parait tout de suite évident et pourtant, il fallait trouver... mes neuronnes n'ont plus l'habitude de ce genre d'exercice

    Bref, MERCI beaucoup !!! et bravo pour le défi

    Je vais tout de suite intégrer ça à mon projet en espérant que l'exemple inventé de bibliothèque puisse s'adapter ss pb.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 34
    Points : 29
    Points
    29
    Par défaut
    Quelqu'un sur une mailing list sur xsl m'a envoyé une autre solution assez expetionnelle je trouve, elle permet de faire ce calcul sans utilisé la reccursivité !

    Le principe et de compter toutes les images de tous les fichiers LIVRE.xml en une seule passe.

    Pour cela on regroupe d'abord dans une variable LesLivresXML tous les livres avec en id le nom du fichier correspondant (avec éventuellement le chemin d'accès "../../Repertoire/") sous forme <LIVRE id="051.xml">

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:variable name="LesLivresXML">
    <xsl:for-each select="LIVRE">
      <LIVRE id="{@ref}.xml"/>
    </xsl:for-each>
    </xsl:variable>
    Et ensuite on fait le calcul :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="document(msxsl:node-set($LesLivresXML)/LIVRE/@id)/*//IMG"/>
    J'utilise ici la fonction node-set de mon processeur XSL qui est MSXML, s'il s'agissait de saxon par exemple la fonction est saxon:node-set.

    Ce qui ce passe ici c'est que ce xsl-value-of va aller ouvrir TOUS les fichiers Livre.xml et faire la somme totale de toutes les balise IMG qu'il va rencontrer ! je trouve ça assez terrible

    Merci à David Carlisle !

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 17
    Points : 7
    Points
    7
    Par défaut A peu près le même problème
    Bonjour, je suis débutante en programmation xsl, et voilà mon problème, je dois faire un moteur de recherche portant sur certains champs.
    Seulement voila ma structure,
    fiche1.xml
    fiche2.xml
    fiche3.xml etc...
    Et je dois en fait parcourir tous ces fichier pour ne garder que ceux qui répondent à la recherche.
    En m'insipirant du code trouvé ci dessus j'ai créé un fichier xml du genre:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <archiveFiche>
    <experience num="fiche1"/>
    <experience num="fiche2"/>
    <experience num="fiche3"/>
    </archiveFiche>

    et voici le xml d'une fiche:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <!DOCTYPE experience SYSTEM "recherche.dtd">
    <experience>
    <num>fiche1</num>
    <labo>gepv</labo>
    <equipe>metaux lourds</equipe>
    <responsable>
    <nomr>MONNOM</nomr>
    <prenomr>Amoi</prenomr>
    <telephoner>0320XXXXXX</telephoner>
    <mailr>monmail@free.fr</mailr>
    </responsable>
    <manipulateur>
    <nomm>SONNOM</nomm>
    <prenomm>ALUI</prenomm>
    <telephonem>0320XXXXXX</telephonem>
    <mailm>sonmail@free.fr</mailm>
    </manipulateur>
    <datedebut>01/08/2005</datedebut>
    <datefin>14/08/2005</datefin>
    <espece>arenosa</espece>
    <objectif>graine</objectif>
    <etape>
    <nom> semis</nom>
    <duree>3</duree>
    <debut>01/08/2005</debut>
    <fin>04/08/2005</fin>
    <nbplante>5</nbplante>
    <contenant>barquette de semis</contenant>
    <temperature>ambiante</temperature>
    <lumiere>null</lumiere>
    <terreau>null</terreau>
    <arrosage>null</arrosage>
    <autre>null</autre>
    <surface>5</surface>
    </etape>
    <cellule>chat</cellule>
    </experience>


    Voilà, et j'en ai plusieurs des fiches, et je dois sortir les fiches que de Monsieur Untel, ou les fiches qui traitent de telle plante etc...(un moteur de recherche quoi )

    Je suis bloquée, alors je me suis dis qu'au lieu d'avoir plusieurs fichiers xml je ne devais en avoir qu'un seul, mais en voyant les post ci-dessus, je me suis dis que ça devait être faisable...

    Quelqu'un pourrait-il me guider, juste pour pouvoir commencer, car là je sèche totalement, et je suis donc bloquée dans mon projet.

    Je vous remercie d'avance

  7. #7
    Expert confirmé
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Points : 4 166
    Points
    4 166
    Par défaut
    Vous utilisez XSLT qui un langage de transformation pour effectuter des interrogations de document XML. Un langage de requête "à la SQL" a été développé spécialement pour cela : XQuery.

    Autant utiliser les bons outils et ne pas se compliquer la vie.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup je vais m'interesser à cela!!!!!

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

Discussions similaires

  1. Requête qui retourne la somme totale de durées
    Par fayred dans le forum Requêtes
    Réponses: 3
    Dernier message: 04/01/2008, 17h21
  2. recuperer et réeutiliser uns somme totale sous BO
    Par bibi5883 dans le forum Deski
    Réponses: 9
    Dernier message: 25/05/2007, 09h35
  3. [2.1.1] [Debutant] probleme de somme Total.sum
    Par lilou77 dans le forum BIRT
    Réponses: 5
    Dernier message: 09/01/2007, 11h09
  4. Calcul de la somme total
    Par Velsy dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/06/2006, 14h29
  5. somme totale et autres champs
    Par melou dans le forum Requêtes
    Réponses: 2
    Dernier message: 01/04/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