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

XML/XSL et SOAP Discussion :

Filtre d'affichage de balise selon leur attributs


Sujet :

XML/XSL et SOAP

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut [Resolu] Filtre d'affichage de balise selon leur attributs
    Bonjour.

    j'ai la série de balises suivante :
    <Mesure Nom="Taille" Date="2001-01-01"/>
    <Mesure Nom="Poids" Date="2003-01-01"/>
    <Mesure Nom="Taille" Date="2003-01-01"/>
    <Mesure Nom="Pointure" Date="2001-01-01"/>
    <Mesure Nom="Poids" Date="1999-01-01"/>

    Je veux afficher pour chaque balise de "Nom" différent uniquement la plus récente : celle de nom taille la plus récente, celle de nom poids la plus récente, etc...

    Je n'y arrive pas, merci de votre aide...

  2. #2
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    il n'existe pas de type date en XSL, par contre on peut comparer des chaines de caractères. Comme on compare car par car dans l'ordre lexicographique, il faut absolument mettre la date sous forme AAAA-MM-JJ. Je sais pas si c'était fait exprès mais garde ce format

    donc 2001-01-01 < 2001-02-30 par ex...

    Bon maintenant il faut une fonction de recherche par ex celle-ci (je n'ai pas testé). Tu l'appelles au début avec nom='taille', pos=0, curmin='9999-99-99' et tu obtiendras sur ton exemple le chiffre 0 qui correspond à mesure[0]...

    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
    <template name="getMinPos">
     <param name="nom"/>
     <param name="pos"/>
     <param name="curmin"/>
     <param name="posmin"/>
     <xsl:choose>
     <xsl:when test="pos != count(mesure)">
      <xsl:if test="mesure[position() = pos]/@nom = $nom">
        <xsl:when test="mesure[position() = pos]/@date < curmin">
          <xsl:call-template select="getMinPos">
            <xsl:with-param name="nom" select="$nom"/>
            <xsl:with-param name="pos" select="$pos+1"/>
            <xsl:with-param name="curmin" select="mesure[position() = pos]/@date "/>
            <xsl:with-param name="posmin" select="position()"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
     
          <xsl:call-template select="getMinPos">
            <xsl:with-param name="nom" select="$nom"/>
            <xsl:with-param name="pos" select="$pos+1"/>
            <xsl:with-param name="curmin" select="$curmin"/>
            <xsl:with-param name="posmin" select="$posmin"/>
          </xsl:call-template>
         </xsl:otherwise>
       </xsl:if>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$posmin"/>
     </xsl:otherwise>
     </xsl:choose>
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    OK, sauf que c'est la date la plus grande (récente) qu'il faut mais ça c'est pas le plus dur, il suffit d'inverser.

    En fait je ne sais pas à l'avance quels sont tous les différents "nom" de mes mesures. Je ne peux donc pas renseigner ton paramètre $nom.
    Et si j'appelle ta méthode via une boucle <xsl:for-each select="Mesure">, je vais me retrouver avec autant de fois la plus récente taille qu'il y a de mesure taille par exemple.

  4. #4
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    tss, tss, non ca marche pas comme ca, tu ne dois pas faire de for-each sur les mesures mais un appel au template getMinPos pour obtenir UN minimum correspondant à UN nom. bon concernant le prbl des noms inconnus à l'avance, il te suffit d'extraire l'ensemble des noms avant.
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Désolée, je sais j'abuse mais justement comment j'extrais la liste des valeurs des attributs "nom" avant ?

  6. #6
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    je viens de trouver une solution plus simple, mais je sais pas si ca marche!

    <xsl:copy-of select="mesure[@date > ../mesure/@date and @nom='taille']"/>

    ca récupère la balise mesure de date la plus récente

    En plus la complexité doit être en O(n^2), donc c'est bien si tu n'as pas trop de mesures. La solution récursive à l'avantage d'être en O(n)...donc mieux quoi

    dans les 2 cas tu seras obliger de chercher les noms d'abords :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:for-each select="mesure">
    <xsl:sort select="@nom" />
            <xsl:if test="not(@nom=preceding::@nom)">
               //tu cherches le min
            </xsl:if>
    </xsl:for-each>
    le truc c'est d'ordonner les noeuds mesure par nom afin de tester si on a un changement de nom, et donc une nouvelle recherche de min à faire
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    sauf que preceding:: fait référence au noeud précédant le noeud courant dans l'ordre du docuement, et non dans l'ordre issu du <xsl:sort> !

    J'ai essayé d'utiliser ce genre de trie, mais les fonction XPATH sur les axes se réfèrent toujours à l'ordre initial des balises dans le document...d'où mon problème...

  8. #8
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    sauf que preceding:: fait référence au noeud précédant le noeud courant dans l'ordre du docuement, et non dans l'ordre issu du <xsl:sort> !
    ah et oui, c'est ce qui arrive quand on ne teste pas ce qu'on dit

    en fait c'était preceding::Mesure/@Nom ou même preceding-sibling::Mesure/@Nom

    la fonction xpath tient compte du tri des noeuds Mesure maintenant.

    allez, ca va marcher...
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Désolée mais le preceding-sibling::Mesure/@Nom ne tient toujours pas compte du tri effectué sur les noms de mesure.

    Voici le contenu de mon fichier de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <Mesure Nom="Pointure" Date="2001-01-01"/> 
    <Mesure Nom="Taille" Date="2002-01-01"/> 
    <Mesure Nom="Taille" Date="2003-01-01"/> 
    <Mesure Nom="Poids" Date="1999-01-01"/>
    <Mesure Nom="Taille" Date="2001-01-01"/> 
    <Mesure Nom="Tension" Date="2001-01-01"/>
    Quand j'appelle ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:for-each select="mesure"> 
    <xsl:sort select="@nom" /> 
            <xsl:if test="not(@nom=preceding-sibling::Mesure/@Nom)"> 
               <xsl:value-of select="preceding-sibling::Mesure/@Nom"/>
            </xsl:if> 
    </xsl:for-each>
    il rentre systématiquement dans le IF car la balise précédente est toujours "Pointure" ! Je ne comprends pas ce que fait cette fonction, elle ne se réfère ni à l'ordre de mon document, ni à l'ordre issu de <xsl:sort>...

  10. #10
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    je ne sais pas si c'est réellement ton code, mais si c'est le cas, il faut respecter la casse des nom d'éléments et d'attributs donc Mesure, @Nom partout.Donc c'est normal qu'il rentre toujours dans le if...
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 8
    Points
    8
    Par défaut
    Effectivement c'était un problème de majuscule ! Merci beaucoup Grégory ! Voici pour info le code que j'utilise :
    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
    59
    60
    61
    <xsl:template name="Mesures">
      <table cellpadding="3" cellspacing="0" border="0" width="100%">
        <xsl:for-each select="//Mesure">
          <xsl:sort select="@Nom"/>
          <xsl:if test="not(@Nom = preceding-sibling::Mesure/@Nom)">
            <xsl:call-template name="AffichMesure">
              <xsl:with-param name="maxnum">
                <xsl:call-template name="getMaxPos">
                  <xsl:with-param name="nombalise"><xsl:value-of select="@Nom"/></xsl:with-param>
                  <xsl:with-param name="curmin">0000-00-00</xsl:with-param>
                  <xsl:with-param name="pos">1</xsl:with-param>
                </xsl:call-template>
              </xsl:with-param>
            </xsl:call-template>
          </xsl:if>
        </xsl:for-each>
      </table>
    </xsl:template>
    <xsl:template name="AffichMesure">
      <xsl:param name="maxnum"/>
      <tr>
        <td align="left" width="25%">
          <xsl:value-of select="../Mesure[position() = $maxnum]/@Nom"/>
          <xsl:text> :</xsl:text>
        </td>
        <td align="left" width="25%">
          <xsl:value-of select="../Mesure[position() = $maxnum]/@DAte"/>
        </td>
      </tr>
    </xsl:template>
    <xsl:template name="getMaxPos">
      <xsl:param name="nombalise"/>
      <xsl:param name="pos"/>
      <xsl:param name="curmin"/>
      <xsl:param name="posmin"/>
      <xsl:choose>
        <xsl:when test="$pos &= count(../Mesure)">
          <xsl:choose>
            <xsl:when test="../Mesure[position() = $pos]/@Nom = $nombalise and translate(../Mesure[position() = $pos]/@Date, '-', '') > translate($curmin, '-', '')">
              <xsl:call-template name="getMaxPos">
                <xsl:with-param name="nombalise" select="$nombalise"/>
                <xsl:with-param name="pos" select="$pos+1"/>
                <xsl:with-param name="curmin" select="../Mesure[position() = $pos]/@Date "/>
                <xsl:with-param name="posmin" select="$pos"/>
              </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
              <xsl:call-template name="getMaxPos">
                <xsl:with-param name="nombalise" select="$nombalise"/>
                <xsl:with-param name="pos" select="$pos+1"/>
                <xsl:with-param name="curmin" select="$curmin"/>
                <xsl:with-param name="posmin" select="$posmin"/>
              </xsl:call-template>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$posmin"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

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

Discussions similaires

  1. [MySQL] Affichage de resultat selon le contenu de la balise select
    Par redoran dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 22/05/2012, 13h20
  2. xml acces direct a une balise multiple selon l'attribut
    Par exter666 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 23/04/2012, 19h28
  3. [XSLT] Selectionner une balise selon la valeur de son attribut
    Par Monkon dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 03/09/2009, 17h03
  4. [SimpleXML] Filtrer des balises grâce à leurs attributs
    Par tatayecorp dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 15/08/2006, 20h06
  5. Probleme affichage dans tableau selon requête
    Par moulette85 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 01/03/2005, 15h44

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