Bonjour a tous,
Voila j'ai un petit problème de XSL.
Je souhaite selectionner des noeuds xml suivant la valeur d'un attribut d'un de leur fils Smiley eek ?!?
Comme un petit exemple est mieux qu'un long discour, voici deux petits exemples de ce que je voudrais réaliser :

<racine>
   <formulaire>
      <commun>
          <class valeur="Toto">
      </commun>
      <toto>
         <Id>1</Id>
         <bureau>12</bureau>
         <batiment>Bat B</batiment>
      </toto>
      <dependances>
         <tutu>
            <id>
               <Nom>toutou</Nom>
               <Toto valeur="2">Coucou</Toto>
               ...
            </id>
            <id>
               <Nom>tonton</Nom>
               <Toto valeur="1">Coucou</Toto>
               ...
            </id>
             <id>
               <Nom>titi</Nom>
               <Toto valeur="1">Coucou</Toto>
               ...
            </id>
            ...
         </tutu>
         <tata>
            <id>
               <Lieu>Ici</lieu>
               <Toto valeur="2">Coucou</Toto>
               ...
            </id>
            <id>
               <Lieu>Labas</lieu>
               <Toto valeur="1">Coucou</Toto>
               ...
            </id>
             <id>
               <Lieu>ailleur</lieu>
               <Toto valeur="1">Coucou</Toto>
               ...
            </id>
            ...
         </tata>
      </dependances>
   </formulaire>
<racine>

voila pour mon fichier xml en entrée.
Je désire donc selectionner tous les noeuds "id" contenus dans "dependances" dont l'attribut "valeur" du noeud "Toto" est égal a la valeur du noeud Id
/racine/formulaire/dependance/*/id/Toto[@valeur=/racine/formulaire/Toto/Id]

Si ce n'était que cela se serais facile, seulement le nom des balises dont je cherche a tester la valeur n'est pas fixe ex :
je voudrais aussi pourvoir faire
/racine/formulaire/dependance/*/id/Pouet[@valeur=/racine/formulaire/Pouet/Id]

Je ne sais pas si j'ai très bien expliqué mon besoin. n'hésitez pas a me demander des précision.

Merci par avance pour votre aide.
Modifié par baptistoux (01 Aug 2006 - 16:42)
Administrateur
Bonjour et bienvenue parmi nous Smiley smile

En tant que modérateur, je me dois de te faire remarquer que tu n'as malheureusement pas respecté l'une des Règles de base du forum qui est d'afficher les codes et exemples proprement à l'aide des boutons [ code]... ici ton code HTML, CSS, PHP, etc.[ /code] (sans espace).

Je te remercie par avance de bien vouloir éditer ton message afin de le rendre conforme à cette règle. Smiley cligne

D'ailleurs, je rappelle que le lien qui apparaît en bandeau tout en haut du forum ("Nouveau sur le forum ?...") est important. Il contient des pistes de recherche, des indications sur les règles de vie de la communauté, etc.
Il serait courtois de ta part de bien vouloir en prendre connaissance.

Bonne continuation Smiley smile

upload/1-code.gif
Raphael a écrit :
En tant que modérateur


Accessoirement, c'est le créateur et propriétaire des lieux, dont nous abusons allègrement.
Modifié par Laurent Denis (01 Aug 2006 - 16:00)
Excusez moi pour mes oublis, je viens d'éditer mon message comme indiqué et je m'en vais de se pas lire "Nouveau sur le forum ?...".
Désolé je suis un "petit nouveau" dans le monde du web. Mon prof m'a fait prendre gout il y a peu à ce type de dévelopement et m'a particulièrement sensibilisé au xml/xsl et autres standards. J'ai déja pratiqué des langages un peu plus conventionnels comme le C, C++, ADA, le shell, SQL... mais le xsl est quelque peu difficile a appréhender c'est pourquoi je sollicite votre aide.

Merci de vos réponses.
Modifié par baptistoux (01 Aug 2006 - 16:58)
Bonjour,

Il est possible d'avoir une expression xpath qui cible la sélection que tu souhaites.

Cependant, afin d'avoir une syntaxe plus claire et concise tu peux définir
<xsl:key name="nom_clef" match="noeud_destination" use="jointure_sur_noeud_destination"/>
- noeud_destination : sélectionne tes différents noeuds Toto, Pouet...
- jointure_sur_noeud_destination : concatène le nom du noeud et le contenu de l'attribut valeur.

Ensuite tu parcours l'arbre source en sélectionnant les noeuds Id qui ont un fils dont les caractéristiques (la concaténation dont il est question au-dessus) correspondent à la clef.
Tout d'abord merci pour ta réponse.
Seulement je ne connais pas a l'avance le nom de ces balises et je n'en ai pas la liste. Je le récupère dans le document xml en entrée :

<racine>
   <formulaire>
      <commun>
          <class valeur="Toto"><!-- Nom de la balise recherchée -->
      </commun>
      ...
<racine>

Modifié par baptistoux (01 Aug 2006 - 17:28)
Oui c'est bien ce que j'avais compris. Pas de problème. Il n'y a pas besoin spécialement de nommer des noeuds pour les sélectionner dans un match.

Par ailleurs, la structure commun>class>valeur est inutile puisque l'on peut déterminer le nom des noeuds à sélectionner de leur présence dans l'élément formulaire.
Ok,
Aurais -tu des exemples concrets ou des liens sur l'utilisation de xsl:key car je t'avourais que j'ai un peu de mal avec cette balise. J'ai fait des recherche sur alsacreation (ou j'ai vu que tu as déja conseillé l'utilisation de celle-ci) ainsi que sur le net mais je n'ai pas vraiment trouvé d'exemples d'autres personnes ayant le même problème que moi.

Merci.

P.S. : Désolé si mes questions peuvent paraitre idiotes ou évidentes mais je suis débutant en xsl.
Désolé, je ne vais pas pouvoir écrire le code qui convient à ton exemple. Sache cependant que l'emploi de <xsl:key /> correspond toujours à la même classe de problème : résolution de cross-references et le cas que tu présentes n'a pas conceptuellement de spécificités particulières.
Je me suis documenté a droite et a gauche pour mieu comprendre l'utilisation de xsl:key.

j'en ai déduit que pour moi ça devrait être un truc de se style là :

<!-- valeur recherchée dans les dépendances -->
<xsl:variable name="valeur"  select="/*/formulaire/*/Id/@valeur" />
<!-- clé sur les noeuds id contenus dans dependances 'selectionnés' suivant la valeur de l'attribut des noeuds fils -->
<xsl:key name='id' match="/*/formulaire/dependances/*/id" use="*/@valeur"/>

<xsl:template match="key('id',$valeur)">
   ...
</xsl:template>

Seulement ceci ne compile pas (au niveau du xsl:template).
[erreur = xsltCompilePattern : failed to compile 'key('id',$valeur)']
et idem si je ne passe pas par une variable :
[erreur = xsltCompilePattern : failed to compile 'key('id',/*/formulaire/*/Id/@valeur)']
Quelqun aurait une idée ?
Modifié par baptistoux (02 Aug 2006 - 10:37)
Concernant, l'erreur que tu reçois : l'attribut match de l'élément xsl:template ne peut pas contenir ni de variable, ni de fonction (tel que key() par exemple). Si ta clef doit impacter l'application d'un template, alors c'est au niveau de l'élément apply-templates qu'il faut le faire.

Par ailleurs, d'après ce que j'ai compris de ton besoin, le lien de référence croisée que tu cherches à établir se fait sur 2 informations (le nom d'un élément, et la valeur d'un autre). Ta clef doit donc forcement rassembler ces 2 informations (concaténation a priori), ou il te faudra utiliser 2 clefs en cascade (sans doute plus difficile à mettre au point).
Merci de ton aide, j'ai trouvé une solution.
Voila je me suis débrouillé comme sa :
Code :

<xsl:template match="/*/formulaire/dependances/*/id"> 
   <xsl:variable name="id1" select="/*/formulaire/*/Id/@valeur" />
   <xsl:variable name="id2" select="*[name() = /*/formulaire/commun/class/@valeur]/@valeur" /> 
   <xsl:if test='$id1=$id2'> 
      ... 
   </xsl:if>
</xsl:template>


Merci pour ton aide @++