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] Aide sur Muench


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut [XSLT] Aide sur Muench
    Bonjour,

    Je vais simplifier mon problème afin que vous puissiez m'aider.

    Je fais une requête de recherche sur des fichiers XML. Les résultats sont stockés dans un seul "fichier virtuel", j'y accède par :

    <xsl:for-each select="/sdx:document/sdx:results/sdx:result">

    La structure est donc la suivante :

    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
     
    <sdx:document>
      <sdx:results>
     
        <sdx:result>
          <adfi:article/> <!--On imaginera ici que @role = breves -->
        </sdx:result>
     
        <sdx:result>
          <adfi:article/>
        </sdx:result>
     
        <sdx:result>
          <adfi:figure/>
        </sdx:result>
     
        <sdx:result>
          <adfi:article/>
        </sdx:result>
     
        <sdx:result>
          <adfi:resource/>
        </sdx:result>
     
        <sdx:result>
          <adfi:resource/>
        </sdx:result>
     
      </sdx:results>
    </sdx:document>
    Jusque là, tout va bien.

    J'ai pris un cas où mon sdx:result contient 6 données (et il peut y avoir des doublons)

    Je voudrai pouvoir mémoriser cette donnée en supprimant les doublons.

    De plus, pour compliquer le tout, je voudrai afficher :
    "Notice" si on a "<adfi:article/>" ,
    "Brèves" si on a "<adfi:article/>" où @role = breves ,
    "Illustrations" si on a "<adfi:figure/>" ,
    "Référence bibliographique" si on a "<adfi:resource/>".

    Et donc obtenir en sortie le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Brèves ; Notices ; Illustrations ; Référence bibliographique.
    Voici le code que j'utilise actuellement pour cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <xsl:for-each select="/sdx:document/sdx:results/sdx:result">				
    	<xsl:choose>
    		<xsl:when test="./adfi:article[@role='breves']">brèves</xsl:when>
    		<xsl:when test="./adfi:figure">illustrations</xsl:when>
    		<xsl:when test="./adfi:resource">références bibliographiques</xsl:when>
    		<xsl:otherwise>notices</xsl:otherwise>
      	</xsl:choose>
     
    	<xsl:choose>
    		<xsl:when test="position() != last()"> ; </xsl:when>
    		<xsl:otherwise>.</xsl:otherwise>
    	</xsl:choose>
    </xsl:for-each select>
    Et j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    brèves ; notices ; illustrations ; notices ; références bibliographiques ; références bibliographiques.
    Bref, j'ai des doublons.

    En effectuant des recherches sur le site, il semblerait que la méthode Muench permette de supprimer les doublons, mais je crois que je n'ai pas entièrement compris son fonctionnement, malgré la FAQ

    J'ai essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    <!--Je suis au début de mon fichier XSL-->
     
    <xsl:key name="typeDoc" match="sdx:result" use="."/> 
     
    <xsl:template match="/">
    	<xsl:apply-templates/>
    </xsl:template>
     
    <!--Je vais dans plusieurs templates avant d'arriver à la partie intéressante-->
     
    <xsl:for-each select="//typeDoc[generate-id(.)=generate-id(key('sdx:result', .)[1])]"> 
    	<xsl:value-of select='.'/> 
    </xsl:for-each>
    Mais cela ne m'affiche rien, même pas les balises <adfi:article> ou autre.

    Je me suis un peu perdue dans les tréfonds de XSL, si quelqu'un veut bien me venir en aide ou me mettre sur la voie...

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    Citation Envoyé par mlny84 Voir le message
    En effectuant des recherches sur le site, il semblerait que la méthode Muench permette de supprimer les doublons, mais je crois que je n'ai pas entièrement compris son fonctionnement, malgré la FAQ
    Certes, mais si ça peut te rassurer ton cas présente aussi quelques spécificités (espaces de nom, combinaison avec l'attribut rôle, etc) qui compliquent un peu la mise en application de la méthode Muench. Maintenant, le principe de la méthode Muench reste inchangé, et il est important de bien le comprendre car il est très fréquent de rencontrer ce genre de problématique.

    Tu n'indexes pas les bons éléments, la clé n'est pas la bonne, et tu as confondu le nom de l'index (typeDoc) que tu es censé utiliser dans la fonction key(), avec un nom d'élément (qui n'existe pas dans ta source).

    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
        <xsl:key name="typeDoc" match="sdx:result/adfi:*" use="concat(local-name(), @role)"/>
     
            <xsl:for-each select="//sdx:result/adfi:*[generate-id() = generate-id(key('typeDoc', concat(local-name(), @role))[1])]">
                <xsl:choose>
                    <xsl:when test="self::adfi:article[@role='breves']">brèves</xsl:when>
                    <xsl:when test="self::adfi:figure">illustrations</xsl:when>
                    <xsl:when test="self::adfi:resource">références bibliographiques</xsl:when>
                    <xsl:otherwise>notices</xsl:otherwise>
                </xsl:choose>
     
                <xsl:choose>
                    <xsl:when test="position() != last()"> ; </xsl:when>
                    <xsl:otherwise>.</xsl:otherwise>
                </xsl:choose>
     
            </xsl:for-each>

  3. #3
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Merci beaucoup pour ton aide, ça marche nickel
    Citation Envoyé par GrandFather Voir le message
    Tu n'indexes pas les bons éléments, la clé n'est pas la bonne, et tu as confondu le nom de l'index (typeDoc) que tu es censé utiliser dans la fonction key(), avec un nom d'élément (qui n'existe pas dans ta source).
    Je crois que je n'avais vraiment rien compris...
    Ma confusion avec "TypeDoc" était plus dû à l'étourderie, mais pour le reste, je n'aurai jamais trouvé toute seule.

    Citation Envoyé par GrandFather Voir le message
    Maintenant, le principe de la méthode Muench reste inchangé, et il est important de bien le comprendre car il est très fréquent de rencontrer ce genre de problématique.
    Je vais donc essayer de décrypter et de comprendre ce que tu as fait...
    Peux-tu valider mon raisonnement ?

    Comme la clé doit prendre en compte à la fois les balises adfi:... et l'attribut role, l'astuce est de faire la concaténation dans la clé.
    Et donc positionner la clé sur le noeud adfi plutôt que sur result pour pouvoir avoir la valeur de l'attribut ?

    Utilisation de self:: au lieu de ./
    Si j'ai bien compris, "self::adfi:figure" permet de sélectionner le noeud de type adfi:figure qui est le noeud contexte, c'est à dire le noeud où on se trouve ?
    Le ./adfi:figure ne marche pas ici car on est déjà positionné sur adfi:figure?
    Le //adfi:figure ne marche pas non plus pour la même raison ?

    Le test "self::adfi:figure" sert donc à savoir si le noeud courant est adfi:figure ?

    Pour ma confusion, la méthode Muench fonctionne donc comme ceci en remettant les éléments à leur place :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:key name="A" match="B" use="C"/>
     
    <xsl:for-each select="//B[generate-id() = generate-id(key('A', C)[1])]">
    ...
    </xsl:for-each>

  4. #4
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par mlny84 Voir le message
    Et donc positionner la clé sur le noeud adfi plutôt que sur result pour pouvoir avoir la valeur de l'attribut ?
    Exactement, ce sont les éléments adfi:* dont tu veux filtrer les doublons, c'est donc eux qu'il faut indexer avec xsl:key
    Citation Envoyé par mlny84 Voir le message
    Le ./adfi:figure ne marche pas ici car on est déjà positionné sur adfi:figure?
    Le //adfi:figure ne marche pas non plus pour la même raison ?
    Tout à fait
    Citation Envoyé par mlny84 Voir le message
    Le test "self::adfi:figure" sert donc à savoir si le noeud courant est adfi:figure ?
    On aurait pu arriver au même résultat avec le test "local-name()='figure'", mais self::adfi:figure est bien plus concis et performant (c'est la seule utilisation pratique qu'on puisse faire de l'axe self, d'ailleurs)
    Citation Envoyé par mlny84 Voir le message
    Pour ma confusion, la méthode Muench fonctionne donc comme ceci en remettant les éléments à leur place :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:key name="A" match="B" use="C"/>
     
    <xsl:for-each select="//B[generate-id() = generate-id(key('A', C)[1])]">
    ...
    </xsl:for-each>
    C'est bien cela.

  5. #5
    Expert éminent

    Avatar de mlny84
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    4 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 4 023
    Points : 8 107
    Points
    8 107
    Par défaut
    Youpi, j'ai tout compris
    Merci encore pour ton aide !

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

Discussions similaires

  1. [XSLT] aide sur la syntaxe xsl, debutant
    Par prugne dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 17/09/2010, 11h25
  2. [XSLT] aide sur l'affichage de données, débutant
    Par prugne dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 14/09/2010, 18h30
  3. Réponses: 2
    Dernier message: 27/02/2003, 01h33
  4. [Kylix] Aide sur BitBlt
    Par mic006 dans le forum EDI
    Réponses: 1
    Dernier message: 10/12/2002, 22h54
  5. Aide sur une fenetre
    Par Ray-j dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 29/11/2002, 08h51

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