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 :

xsl:for-each Conserver la première valeur trouvée


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut xsl:for-each Conserver la première valeur trouvée
    Bonjour,

    Dans une boucle <xsl:for-each>, j'ai une boucle <xsl:if> et je souhaiterais ne conserver que la première valeur trouvée.

    Voici ma boucle xsl:for-each :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <xsl:for-each select="cd/object[@role='Rendering']">
    	<xsl:variable name="RenderingRef" select="substring-after(@Ref,'#')"/>
    	<xsl:variable name="RenderingType" select="cd/Rendering[@id=$RenderingRef]/@type"/>
    	<xsl:if test="($RenderingType='PDF')">
    		<xsl:variable name="RenderingName" select="cd/Rendering[@id=$RenderingRef]/@name"/>
    		<xsl:value-of select="$RenderingName"/>
    	</xsl:if>
    </xsl:for-each>
    Voici une partie du xml d'origine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <cd>
    	<object Ref="#id1" role="Rendering">
    	<object Ref="#id2" role="Rendering">
    	<object Ref="#id3" role="Rendering">
    	<object Ref="#id4" role="Rendering">
    	<Rendering id="id1" type="Excel" name="test.xls">
    	<Rendering id="id2" type="PDF" name="test.pdf">
    	<Rendering id="id3" type="Word" name="test.doc">
    	<Rendering id="id4" type="PDF" name="test2.pdf">
    </cd>
    Je souhaite donc n'avoir en sortie que "test.pdf".

    Avez-vous une idée car là je sèche.

    Merci d'avance pour votre aide.

  2. #2
    Modérateur

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

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

    avec l'exemple donné, le plus simple serait de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="cd/Rendering[@type='PDF']/@name"/>
    En ignorant <object>, role, Ref, id, sans boucle, sans if, et c'est seulement le premier qui sort parce que <xsl:value-of> ne prend que le premier.

    Est-ce que tu peux nous décrire un peu mieux pourquoi c'est pas ce que tu fais ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Hello,

    Malheureusement ce n'est pas aussi simple merci tout de même.

    En fait, je fais un export xml d'une base de données, puis avec le xsl je l'utilise pour créer un rapport html.

    J'ai simplifié pas mal le code xml, car en fait je récupère d'autres informations dans la balise au dessus de <object>, par exemple le nom:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <cd>
    <part id="id1" name="OMEGA">
    	<object Ref="#id1" role="Rendering" nom="alpha">
    	<object Ref="#id2" role="Rendering" nom="beta">
    	<object Ref="#id3" role="Rendering" nom="gamma">
    	<object Ref="#id4" role="Rendering"" nom="epsilon">
    </part>
    	<Rendering id="id1" type="Excel" name="test.xls">
    	<Rendering id="id2" type="PDF" name="test.pdf">
    	<Rendering id="id3" type="Word" name="test.doc">
    	<Rendering id="id4" type="PDF" name="test2.pdf">
    </cd>
    Et donc en sortie je souhaite avoir une ligne telle que :
    Name OMEGA
    Rendering test.pdf

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    D'accord, mais la question, c'est à quoi servent la boucle et le if ?

    Là tu nous dis que tu veux exporter des infos à propos du premier PDF trouvé.

    Dans ce cas-là, il suffit d'aller chercher d'abord le premier PDF <xsl:variable name="pdf" select="cd/Rendering[@type = 'PDF'][1]"/>, et ensuite seulement aller les chercher les informations qui lui correspondent.
    Y a-t-il quelque chose qui fait que ça ne convient pas ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    La boucle me sert à lire tous les "object" lié à mon objet "part", puis le "if" me permet de ne récupérer que le rendering associé avec le type "PDF".

    Le problème est que j'ai au début de mon xml plusieurs objets "part" qui font appel à des objets "rendering".

    A partir de ce 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
    <cd>
    <part id="id1" name="OMEGA">
    	<object Ref="#id1" role="Rendering" nom="alpha">
    	<object Ref="#id2" role="Rendering" nom="beta">
    	<object Ref="#id3" role="Rendering" nom="gamma">
    	<object Ref="#id4" role="Rendering" nom="epsilon">
    </part>
    <part id="id2" name="ALPHA">
    	<object Ref="#id5" role="Rendering" nom="phi">
    </part>
    	<Rendering id="id1" type="Excel" name="test.xls">
    	<Rendering id="id2" type="PDF" name="test.pdf">
    	<Rendering id="id3" type="Word" name="test.doc">
    	<Rendering id="id4" type="PDF" name="test2.pdf">
    	<Rendering id="id5" type="PDF" name="test-12.pdf">
    </cd>
    Donc je souhaite en sortie un tableau du style (je suis trompé dans mon exemple précédent dans l'ordre d'affichage):
    Name Rendering
    OMEGA test.pdf
    ALPHA test-12.pdf

    J'espère avoir été plus clair sur ce que je souhaite faire...

    En tout cas, merci de t'intéresser à mon problème

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Mini-developpeur Voir le message
    La boucle me sert à lire tous les "object" lié à mon objet "part", puis le "if" me permet de ne récupérer que le rendering associé avec le type "PDF".
    Non mais oui mais bien sûr, mais ce que je veux dire, c'est que ce que tu cherches à faire, ce n'est pas ça. Enfin, je crois.
    Vu ce que tu nous dis, ce que tu cherches à faire, c'est récupérer un PDF. Il y a pas d'histoire de lire les object là-dedans.

    Tu as une boucle sur les "part" (puisque eux, tu veux tous les parcourir,) et pour chacun d'entre eux il faut aller chercher le PDF correspondant. Pas de if. Et la boucle n'est pas sur "object".
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    C'est ça, sauf que c'est le premier PDF correspondant (premier PDF lié à mon objet part) uniquement et c'est bien ça mon problème.

    Je passe par une boucle xsl:for-each car sinon je ne sais pas "lire" plusieurs lignes avec des balises identiques (il ne me prend que la première).

  8. #8
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Mini-developpeur Voir le message
    Je passe par une boucle xsl:for-each car sinon je ne sais pas "lire" plusieurs lignes avec des balises identiques (il ne me prend que la première).
    Non non, il n'y a que value-of qui prend la première et jette les autres.
    Quand tu désignes une ligne, tu désignes toujours toutes les lignes correspondantes.

    Le plus simple serait donc, de sélectionner tous les PDF, et utiliser [ et ] pour ne garder que ceux qui correspondent à ton "part". S'il y en a plus d'un, value-of se chargera de ne garder que le premier.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Donc tu me conseilles de faire ceci :
    $id étant l'id de mon part
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="cd/Rendering[@type='PDF' and @id='concat('#',cd/part[@id=$id]/object/@id)']/>
    Est-ce correct? (Par contre je ne suis pas sûr du "and" dans la sélection...)

  10. #10
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    C'est bien raisonné (et le "and" fonctionne parfaitement.)
    Mais ça ne va pas marcher comme ça.

    concat() ne produit qu'une seule valeur, une seule string, et ce sera donc l'id du premier object trouvé. Ça ne va pas, on veut chercher un object, n'importe lequel, dont l'id corresponde. En plus l'appel était en sens inverse, l'id de Rendering n'a pas de #.
    Aussi, à l'intérieur des [ et ] le contexte a changé, et donc si tu fais cd/part il ne va pas chercher cd et part au bon endroit.

    Je me rends compte qu'à partir de là c'est pas évident à trouver tout seul, donc voici comment je ferais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:value-of select="cd/Rendering[@type='PDF' and concat('#', @id) = $part/object/@Ref]"/>
    Avec $part une variable qui contient ton part en cours.
    Normalement ça marche, mais il fallait le trouver. (Surtout le bricolage avec concat() qui aurait pu nous embêter.)

    On sélectionne les Rendering qui :
    - sont de type PDF, ET
    - en calculant leur id précédé d'un #, on obtient une string, et cette string est l'un des Ref des object du part.

    Si les choses avaient été plus compliquées, on aurait été forcé de commencer par créer un index pour pré-lier les éléments entre eux.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Septembre 2015
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel

    Informations forums :
    Inscription : Septembre 2015
    Messages : 11
    Points : 4
    Points
    4
    Par défaut
    Ca marche du tonnerre

    Sans toi, je n'aurai jamais pensé à passer par les Rendering au lieu des parts.

    Merci pour ton aide !!!

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

Discussions similaires

  1. xsl:for-each avec un parametre pour select
    Par arnog dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 26/08/2008, 13h09
  2. [XSL] for-each et variable
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 12/01/2006, 11h42
  3. xsl:for-each
    Par ashurai dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 10/01/2006, 11h54
  4. [XSL] for-each + sort, et comparaison current previous value
    Par johan_barbier dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 18/11/2005, 16h46
  5. [XML/XSL] for-each imbriqués
    Par grome dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 11/11/2005, 12h44

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