Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1279 connectés 

  FORUM HardWare.fr
  Programmation
  XML/XSL

  Boucles imbriquées en XSL

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Boucles imbriquées en XSL

n°1621257
rodolpheg
Posté le 09-10-2007 à 17:25:50  profilanswer
 

Alors deuxième question...

 

J'ai bien avancé grâce à vous, et il me faut maintenant passer aux choses sérieuses ;)

 

J'essaie en fait de transformer un XML issu de MS Access en Graphml. Un graphml est un xml composé de deux "sections", une section "nodes" (que vous m'avez aidé -grandement- à résoudre hier) et une section "edges" qui doit définir les liens entre les noeuds.

 

Mon xml d'origine a cette allure-ci :

 
Code :
  1. <dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2007-10-03T16:34:07">
  2. <node>
  3. <Name>***</Name>
  4. <Organization>University of Alberta</Organization>
  5. </node>
  6. <node>
  7. <Name>***</Name>
  8. <Organization>Boreal Ecosystems Research Ltd</Organization>
  9. </node>
  10. <node>
  11. <Name>***</Name>
  12. <Organization>Boreal Ecosystems Research Ltd</Organization>
  13. </node>
  14. ...
  15. </dataroot>
 

Je veux lier tous les noeuds dont les champs "Organisation" sont identiques. Et créer un noeud :

Code :
  1. <edge source="1" target="2"></edge>


Si les nodes 1 et 2 ont des champs "Organisation" identiques, encore une fois.

 

Voilà ce que j'ai tenté, j'ai pensé faire des boucles imbriqués. Dans mon court exemple contenant seulement trois noeuds, le xsl comparerait le premier node avec le second et le troisième, puis le second noeud avec le premier et le troisième, et enfin le troisième noeud avec le premier et le second. Si les champs "Organisation" sont égaux, il crée la ligne décrite plus haut :

 
Code :
  1. <graphml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/g [...] &#034;&gt;
  2.             <graph edgedefault="undirected">
  3.                     <xsl:for-each select="dataroot/node">
  4.                         <xsl:variable name="P1" select="ProjectCode"/>
  5.                         <xsl:variable name="node1" select="position()"/>
  6.                             <xsl:for-each select="dataroot/node">
  7.                                 <xsl:variable name="P2" select="ProjectCode"/>
  8.                                 <xsl:variable name="node2" select="position()"/>
  9.                                 <xsl:if test="P1=P2">
  10.                                     <edge source="{node1}" target="{node2}"></edge>
  11.                                 </xsl:if>
  12.                             </xsl:for-each>
  13.                     </xsl:for-each>
  14.             </graph>
  15.         </graphml>
 

Je ne sais pas si c'est très clair... Hmmm...  :??:


Message édité par rodolpheg le 09-10-2007 à 17:26:29
mood
Publicité
Posté le 09-10-2007 à 17:25:50  profilanswer
 

n°1621289
masklinn
í dag viðrar vel til loftárása
Posté le 09-10-2007 à 18:01:12  profilanswer
 

Quand tu donnes un chemin à for-each qui ne commence pas par "/", il se base sur la node "courante" (comme tous les autres sélecteurs sélecteurs, e.g. "dataroot/node" est en fait "./dataroot/node" ).

 

Le truc, c'est qu'à l'intérieur d'un for-each, la node courante est la node actuellement sélectionnée par ton for-each (donc "." représente non pas "/" comme en dehors de ton for-each, mais un l'élément "node" courant)

 

Dans la mesure où "dataroot" est ton élément racine, tu devrais le binder à "/" et itérer sur "/dataroot/node" dans les deux cas, parce qu'ici ton second for-each itère en fait sur "/dataroot/node/dataroot/node" ;)


Message édité par masklinn le 09-10-2007 à 18:02:05

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1621292
TheRom_S
Posté le 09-10-2007 à 18:05:50  profilanswer
 

Salut, cette fois-ci, on va pouvoir utiliser les params. Avant tout, faut savoir que les "variables" XSL sont en fait des constantes ; donc on ne va pas les utiliser. L'idée, c'est de faire un for-each sur les nodes (tu as toujours leur "id" ) dans lequel tu vas appeler un autre template en lui passant des paramètres (valeur de "Organisation" et de "id" ). Dans ce second template, tu refais un for-each sur tous les nœuds et là tu compare les valeurs de "Organisation" pour créer les edges et les valeurs de "id" de filtrer les nœuds identiques (je suppose que tu ne les veux pas). Donc regardes du côté de <xsl:apply-templates> et <xsl:call-template> pour savoir comment appeler le second template (celui avec le second for-each imbriqué) et regardes aussi <xsl:with-param> pour passer des valeurs comme à l'appel d'une fonction dans un langage de prog plus classique.
 
edit : grillaid by Masklinn et oui, le plus difficile va être de savoir où tu en es de ton arborescence à chaque appel de for-each et de call/apply-template(s) pour t'y retrouver


Message édité par TheRom_S le 09-10-2007 à 18:08:03

---------------
The Rom's, à votre service
n°1621375
rodolpheg
Posté le 09-10-2007 à 23:51:54  profilanswer
 

Cool, je vais essayer ça !!! :)

n°1621749
rodolpheg
Posté le 10-10-2007 à 16:28:18  profilanswer
 

Argh, j'en appelle encore à votre aide !!!  :sweat:

 

Voilà où est mon problème, il semblerait qu'il faille définir les paramètres au tout début, mais comment leur assigner une valeur par la suite ?  :??:

 

J'oublie pour le moment le filtrage des comparaisons de noeuds identiques, j'en suis pas là, et je pense que mon graphml fonctionnerait malgrés ça (mais c'est à voir, haha) ;)

 

J'en suis là, le xsl met bien tous les noeuds, puis s'occupe des côtés (edges), et c'est là que ça se complique :

 
Code :
  1. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  2.    
  3.     <xsl:output method="xml" indent="yes"/>
  4.     <xsl:param name="org1" select="Organization"/>
  5.     <xsl:param name="org2" select="Organization"/>
  6.     <xsl:param name="node1" select="position()"/>
  7.     <xsl:param name="node2" select="position()"/>
  8.    
  9.     <xsl:template match="/"> 
  10.         <graphml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="...">
  11.             <graph edgedefault="undirected">
  12.                 <key id="name" for="node" attr.name="name" attr.type="string"/>
  13.                 <key id="organisation" for="node" attr.name="organisation" attr.type="string"/>
  14.                 <key id="location" for="node" attr.name="location" attr.type="string"/>
  15.                 <key id="sector" for="node" attr.name="sector" attr.type="string"/>
  16.                 <key id="project" for="node" attr.name="project" attr.type="string"/>
  17.         <xsl:for-each select="/dataroot/node">
  18.             <node id="{position()}">
  19.                     <data key="name"><xsl:value-of select="Name"/></data>
  20.                     <data key="organisation"><xsl:value-of select="Organization"/></data>
  21.                     <data key="location"><xsl:value-of select="Location"/></data>
  22.                     <data key="sector"><xsl:value-of select="Sector"/></data>
  23.                     <data key="project"><xsl:value-of select="ProjectCode"/></data>
  24.             </node>
  25.         </xsl:for-each>
  26.                
  27.         <xsl:for-each select="/dataroot/node">
  28.             /////////////// Comment mettre ici la valeur de organisation dans org1 ?
  29.             <xsl:call-template name="xml2graphml_b">
  30.                 <xsl:with-param name="org1" />
  31.                 <xsl:with-param name="node1" />
  32.             </xsl:call-template>
  33.         </xsl:for-each>
  34.             </graph>
  35.         </graphml>
  36.     </xsl:template>
  37.    
  38.     <xsl:template name="xml2graphml_b" match="/">
  39.         <xsl:param name="org1"/>
  40.         <xsl:param name="node1"/>
  41.         <xsl:for-each select="/dataroot/node">
  42.             //////////////// Comment mettre ici la valeur de organisation dans org2 ?
  43.             <xsl:if test="org1=org2">
  44.                 <edge source="{node1}" target="{node2}"></edge>
  45.             </xsl:if>
  46.         </xsl:for-each>
  47.     </xsl:template>
  48.    
  49. </xsl:stylesheet>
 

:pt1cable:

Message cité 1 fois
Message édité par rodolpheg le 10-10-2007 à 16:30:19
n°1621758
masklinn
í dag viðrar vel til loftárása
Posté le 10-10-2007 à 16:37:23  profilanswer
 

rodolpheg a écrit :

Argh, j'en appelle encore à votre aide !!!  :sweat:
 
Voilà où est mon problème, il semblerait qu'il faille définir les paramètres au tout début


NON [:mlc]

rodolpheg a écrit :

mais comment leur assigner une valeur par la suite ?  :??:  


Ben dans le with-param, with-param ça indique quel paramètre on fournit à une template (via un call-template), ça prend un nom (name) requis, et soit un contenu (<with-param name="foo">content here</with-param> ) soit un select (<with-param name="foo" select="@bar"/> ), qui est la valeur qui sera fournie en <param/> à la template.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1621773
rodolpheg
Posté le 10-10-2007 à 16:44:39  profilanswer
 

Je vais essayer ça, MERCI !!! ;)


Message édité par rodolpheg le 10-10-2007 à 16:45:22
n°1621779
rodolpheg
Posté le 10-10-2007 à 16:51:33  profilanswer
 

Voici ce que me dit mon debugger : "E xsl: param must be immediately within a template, function or stylesheet"

 

Voici où l'erreur se produit :

Code :
  1. <xsl:template name="xml2graphml_b" match="/">
  2.         <xsl:for-each select="/dataroot/node">
  3.             <xsl:param name="org2" select="Organization"/>
  4.             <xsl:param name="node2" select="position()"/>
  5.             <xsl:if test="org1=org2">
  6.                 <edge source="node1" target="node2"></edge>
  7.             </xsl:if>
  8.         </xsl:for-each>
  9.     </xsl:template>

Message cité 1 fois
Message édité par rodolpheg le 10-10-2007 à 16:52:28
n°1621789
masklinn
í dag viðrar vel til loftárása
Posté le 10-10-2007 à 17:11:19  profilanswer
 

rodolpheg a écrit :

Voici ce que me dit mon debugger : "E xsl: param must be immediately within a template, function or stylesheet"
 
Voici où l'erreur se produit :

Code :
  1. <xsl:template name="xml2graphml_b" match="/">
  2.         <xsl:for-each select="/dataroot/node">
  3.             <xsl:param name="org2" select="Organization"/>
  4.             <xsl:param name="node2" select="position()"/>
  5.             <xsl:if test="org1=org2">
  6.                 <edge source="node1" target="node2"></edge>
  7.             </xsl:if>
  8.         </xsl:for-each>
  9.     </xsl:template>



Tu fais n'importe quoi.
 
Prière de faire le Zvon Tutorial en entier (les 71 sections).


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1621797
rodolpheg
Posté le 10-10-2007 à 17:19:55  profilanswer
 

Faute de temps, je fais ces tutoriels pour chaque fonction que j'utilise... Ça n'est pas mon domaine du tout mais j'ai besoin d'utiliser XSL pour résoudre un problème précis qui me bloque dans mes travaux, je ne peux malheureusement pas apprendre tout ça de a-z  :(

mood
Publicité
Posté le 10-10-2007 à 17:19:55  profilanswer
 

n°1621809
masklinn
í dag viðrar vel til loftárása
Posté le 10-10-2007 à 17:29:52  profilanswer
 

rodolpheg a écrit :

Faute de temps, je fais ces tutoriels pour chaque fonction que j'utilise... Ça n'est pas mon domaine du tout mais j'ai besoin d'utiliser XSL pour résoudre un problème précis qui me bloque dans mes travaux, je ne peux malheureusement pas apprendre tout ça de a-z  :(


Ben commences déjà par le tuto que je t'ai filé, il est rapide, il est simple, il est clair et tu rencontreras rapidement les solutions à ce que tu recherches.

 

Parce que là t'es parti pour faire 5 pas en avant et 4 pas en arrière (tu as un tout petit problème, quelqu'un te donne une solution simple, mais comme tu ne connais pas le contexte et ne comprends pas complètement la solution par manque de connaissance du domaine ça génère immédiatement un autre tout petit problème, ad vitam aeternam), pour perdre ton temps, et pour faire perdre du temps aux gens du forum, ce qui ne sert à personne. Et surtout pas à toi.


Message édité par masklinn le 10-10-2007 à 17:30:43

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1621841
TheRom_S
Posté le 10-10-2007 à 18:21:05  profilanswer
 

Bah ça va tu peux lui dire de virer les déclarations de params qui sont inutiles. Une fois que tu as définit les params avec <with-param ...>, leur valeur est directement accessible dans le template appelé avec "$org1" ...


---------------
The Rom's, à votre service
n°1621855
rodolpheg
Posté le 10-10-2007 à 19:20:56  profilanswer
 

J'ai réussi !!! C'est pas très élégant mais ça fonctionne !!! Merci beaucoup TheRom_s et Masklinn pour votre aide, vraiment !!! Je me coucherai moins bête ce soir !!! ;)

n°1621864
rodolpheg
Posté le 10-10-2007 à 19:51:05  profilanswer
 

Aïe, j'ai parlé trop vite...

 
Code :
  1. <xsl:if test="$node2 > $node1">
  2. <edge source="{$node1}" target="{$node2}"></edge>
  3. </xsl:if>
 

Me donne :

 
Code :
  1. <edge source="320" target="321"/>
 

Sans le "</edge>" à la fin... C'est étrange ça...

 


Alors qui si je mets :

Code :
  1. <xsl:if test="$node2 > $node1">
  2. <edge source="{$node1}" target="{$node2}">+</edge>
  3. </xsl:if>
 

Je me retrouve bien avec :

Code :
  1. <edge source="318" target="320">+</edge>


Message édité par rodolpheg le 10-10-2007 à 19:59:14
n°1621868
masklinn
í dag viðrar vel til loftárása
Posté le 10-10-2007 à 20:09:23  profilanswer
 

Il n'y a rien dans ta node <edge/>, donc comme tout bon générateur de XML, ton moteur XSL sort une node vide <edge/> et non <edge></edge>, les deux étant parfaitement équivalents en XML.
 
Si tu veux absolument une node non minimisée, tu peux sortir un commentaire XML au milieu (bien que ça n'ait pas d'intérêt si tu ne sors pas du HTML) avec "<xsl:comment/>"


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1621871
rodolpheg
Posté le 10-10-2007 à 20:17:24  profilanswer
 

Ha c'est donc ça, c'est la même chose... J'ai des problèmes pour charger mon xml dans un programme java, et je pensais que c'était à cause de ça... Je vais continuer à chercher l'erreur. :salut:


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  XML/XSL

  Boucles imbriquées en XSL

 

Sujets relatifs
[XSL] problème avec <xsl:attribute name="href">Soucis avec mon premier fichier XSL
La solution PHP+XML+XSL=Template est-elle viable ?Browser-Side XSL
Outils pour indenter un fichier XSL ?[XSL] Changer l'order de tri (sort-order) dynamiquement
concaténation de résultat de boucles (VB)XSL-FO pour PDF à un XSL pour TXT
Problème saut ligne RSS => HTML via XSL[résolu]XSL conditions
Plus de sujets relatifs à : Boucles imbriquées en XSL


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR