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 :

Rassemblement des noeuds, maximum et xsl:key


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 Rassemblement des noeuds, maximum et xsl:key
    Bonjour,

    Tout d'abord pardon pour le titre, mais je n'ai pas réussi à en trouver un mieux.

    Voici mon XML simplifié :

    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
     
    <sdx:results>
    <sdx:result>
    	<article id="N1">
    		<event role="operation">
    			<date>	
    				<year> 1992 </year>
    			</date>
    		</event>
    	</article>
    </sdx:result>
    <sdx:result>
    	<article id="N2">
    		<event role="operation">
    			<date role="debut">
    				<year> 1991 </year>
    			</date>
    			<date role="fin">
    				<year> 1993 </year>
    			</date>
    		</event>
    		<event role="operation">
    			<date>
    				<year> 1995 </year>
    			</date>
    		</event>
    	</article>
    </sdx:result>
    <sdx:result>
    	<article id="N3">
    		<event role="operation">
    			<date role="debut">
    				<year> 1992 </year>
    			</date>
    			<date role="fin">
    				<year> 1993 </year>
    			</date>
    		</event>
    	</article>
    </sdx:result>
    <sdx:result>
    	<article id="N4">
    		<event role="operation">
    			<date>
    				<year> 1992 </year>
    			</date>
    		</event>
    		<event role="operation">
    			<date role="debut">
    				<year> 1990 </year>
    			</date>
    			<date role="fin">
    				<year> 1991 </year>
    			</date>
    		</event>
    	</article>
    </sdx:result>
    </sdx:results>
    Chaque event "operation" est daté, soit il n'y a qu'une seule date (car durée d'1 an ou moins), soit il y a une date de début et de fin.
    Il peut y avoir plusieurs event "operation" par article.

    Ce que je voudrai faire, c'est récupérer l'id de mes articles selon la date de fin (si il y a plusieurs event, prendre la plus grande date). Dans cet exemple, cela donnerai donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    1992 : N1, N4
    1993 : N3
    1995 : N2
    Je pense qu'il faut que j'utilise xsl:key pour "rassembler" mes nœuds selon les dates, et en triant la valeur de la date maximale avec un tri et un position()=1, mais cela fait déjà un moment que je tourne en rond, et je m'y suis emmêler les neurones.
    Tout ce que j'ai réussi à faire, c'est mettre mes articles par date :

    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
     
    <xsl:key name="date" match="adfi:event[@role='operation']/adfi:date/adfi:year" use="."/>
    <xsl:key name="dateF" match="adfi:event[@role='operation']/adfi:date[@role='fin']/adfi:year" use="."/>
     
     
    <xsl:for-each select="//adfi:event[@role='operation']/adfi:date/adfi:year[generate-id() = generate-id(key('dateF', .)[1]) or generate-id() = generate-id(key('date', .)[1])]">
    	<xsl:sort select="." />
     
    	<xsl:variable name="vdate" select=".">
    		<xsl:value-of select="."/>
    	</xsl:variable>
    	<xsl:value-of select="$vdate"/>
     
    	<xsl:for-each select="//sdx:result[./adfi:article/adfi:event/adfi:date/adfi:year=$vdate]">
    		<xsl:value-of select="./adfi:article/@id"/>
    	</xsl:for-each>
     
    </xsl:for-each>
    Ce qui me donne quelque chose de se style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    1991 : N4
    1992 : N1, N4
    1993 : N2, N3
    1995 : N2
    Si vous avez une idée pour m'aiguiller sur la bonne 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
    Je pense qu'il faut que j'utilise xsl:key pour "rassembler" mes nœuds selon les dates, et en triant la valeur de la date maximale avec un tri et un position()=1, mais cela fait déjà un moment que je tourne en rond, et je m'y suis emmêler les neurones.
    Il faut effectivement utiliser un xsl:key pour faire le regroupement, mais le position()=1 ne fonctionne pas dans ce contexte (la position est calculée dans la liste de noeuds sélectionnés dans l'ordre du document, pas dans la liste triée). Ce qui complique davantage la chose, c'est que le regroupement porte sur les années maximales pour chaque event. Ce qui donne des expressions XPath un peu complexes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        <xsl:key name="annees" match="date[not(@role) or @role='fin']/year[not(. &lt; ../../preceding-sibling::event/date[not(@role) or @role='fin']/year) and not(. &lt; ../../following-sibling::event/date[not(@role) or @role='fin']/year)]" use="."/>
        <xsl:template match="sdx:results">
            <xsl:for-each select="sdx:result/article/event/date[not(@role) or @role='fin']/year[not(. &lt; ../../preceding-sibling::event/date[not(@role) or @role='fin']/year) and not(. &lt; ../../following-sibling::event/date[not(@role) or @role='fin']/year)][generate-id() = generate-id(key('annees', .)[1])]">
                <xsl:sort select="."/>
                <xsl:value-of select="."/>
                <xsl:for-each select="key('annees', .)/ancestor::article/@id">
                    <xsl:value-of select="."/>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:template>
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  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 pour ta réponse GrandFather,

    Les expressions XPATH sont déjà compliquées, mais elles devraient l'être encore plus
    Ce n'est pas un regroupement sur les années maximales pour chaque event, mais un regroupement sur les années maximales sur chaque article (donc en fait l'année maximale de tous les event d'un même article), c'était justement cette partie là qui me bloquait.

    EDIT : Ton code est impeccable pour les années sur chaque event, je vais essayer de l'adapter pour résoudre mon problème.

  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
    Ce n'est pas un regroupement sur les années maximales pour chaque event, mais un regroupement sur les années maximales sur chaque article (donc en fait l'année maximale de tous les event d'un même article), c'était justement cette partie là qui me bloquait.
    C'est bien ce que fait mon code : l'année maximum est déterminée parmi tous les events frères (siblings) d'un article, d'où les ../../preceding-sibling::event et ../../following-sibling::event dans le prédicat. J'ai fait un rapide test avec tes données, et ça a l'air de coller.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  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
    Bon, c'est moi qui me suis plantée en adaptant ton code au mien
    J'ai en fait un XML qui a beaucoup plus de nœuds, et les events ne sont pas frères en fait, ils sont contenu dans un autre nœud...

    En ajoutant un ../ dans le prédicat, ça marche impeccablement

    Bref, tout est de ma faute

    Mais un grand merci à toi pour ton aide !

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

Discussions similaires

  1. XSL: Probleme avec des noeuds parent
    Par kururin dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 24/03/2009, 15h20
  2. [XSL] Renommer des noeuds en XSL
    Par mcheit dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 16/04/2008, 14h38
  3. [XSL][Noob]Compter des noeuds de meme valeur??
    Par Devil666 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 22/07/2005, 10h07
  4. xsl ---> filtrage des noeuds avec "not"
    Par yos dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 12/07/2005, 11h26
  5. Couleur des noeuds ds 1 TTreeView
    Par vincent DD dans le forum Composants VCL
    Réponses: 3
    Dernier message: 18/09/2002, 13h54

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