Boucle for(i=0;i<var;i++) en XSL... ?

Boucle for(i=0;i<var;i++) en XSL... ? - XML/XSL - Programmation

Marsh Posté le 27-01-2005 à 10:38:13    

Salut,
 
 
Dans un XML j'ai une description de pagination:
Nombre de pages, nombre d'item par page, nombre total de résultat, page en cours...
 
J'aimerais générer le HTML pour les N° de page et pour ca j'ai besoin de boucler sur mon nombre de page...
 
 
Comment est ce que je fait ca en XSL?
y'a pas de truc genre <xsl:for  ?
 
Paquerette

Reply

Marsh Posté le 27-01-2005 à 10:38:13   

Reply

Marsh Posté le 27-01-2005 à 11:05:05    

Oui avec -each  au bout  
 :fou: [:aless]
C dans l'aide !

Reply

Marsh Posté le 27-01-2005 à 11:31:48    

Quelle aide?
 
avec l'XML suivant :
<queue>
  <numberOfPage>10</numberOfPage>
</queue>
 
<xsl:for-each select="queue/numberOfPage">
 <xsl:value-of select="position()"/>
</xsl>
 
ca va me faire  
012345678910
 
Je trouve ca étrange....

Reply

Marsh Posté le 27-01-2005 à 11:31:57    

gedeon a écrit :

Oui avec -each  au bout  
 :fou: [:aless]
C dans l'aide !


Du calme gedeon, du calme.
 
"for-each", c'est pour boucler sur les items d'un ensemble.
Et c'est pas ce que demande paquerette !
 
paquerette veux générer des données à partir de rien (ou presque), ce pour quoi XSLT n'est pas du tout fait.
 
Mais on peut s'en sortir ;)
 
Avec la récursivité des templates :
 
On veut donc par exemple générer x fois le code : '<a href="page.php?num=n" class="page_num"> n </a>' ou 'n' va de N à N'.
 
On fait donc un template qui prend des paramètres en entrée :
 

Code :
  1. <xsl:template name="gen-page-nums">
  2. <xsl:param name="num" />
  3. <xsl:param name="total" />
  4. <a class="page_num">
  5.  <xsl:attribute name="href>page.php?num=<xsl:value-of select="$num" /></xsl:attribute>
  6.  <xsl:value-of select="$num" />
  7. </a>
  8. <xsl:if test="$num &lt; $total">
  9.  <xsl:call-template name="gen-page-nums">
  10.   <xsl:with-param name="num" select="$num + 1" />
  11.   <xsl:with-param name="total" select="$total" />
  12.  </xsl:call-template>
  13. </xsl:if>
  14. </xsl:template>


 
Pour appeler le template pour générer les numéros de pages de 15 à 30 :
 

Code :
  1. <xsl:call-template name="gen-page-nums">
  2. <xsl:with-param name="num" select="15" />
  3. <xsl:with-param name="total" select="30" />
  4. </xsl:call-template>


 
Et, ça, je ne suis pas sûr que se soit dans l'aide...
 
[Edit] Correction de quelques bugs...


Message édité par Mara's dad le 27-01-2005 à 12:42:43

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 27-01-2005 à 11:38:35    

Je me disais bien aussi.... ca aurait été trop simple !
 
Merci Mara's dad :)

Reply

Marsh Posté le 27-01-2005 à 11:42:38    

le &lt; de <xsl:if test="$num &lt; $total"> c'est voulu ou c'est le forum?
 
Je vais essayer d'ajouter a ca, un fenetrage pour n'afficher que les 9 pages autours de la page courante...

Reply

Marsh Posté le 27-01-2005 à 11:44:49    

après reflexion je pense que c'est voulu :D

Reply

Marsh Posté le 27-01-2005 à 11:51:33    

Oui, c'est voulu !
'<' en xml, c'est mal vu ;)


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 27-01-2005 à 12:18:59    

il manquait des / sur les value-of dans le lien
 

Code :
  1. <xsl:template name="gen-page-nums">
  2.      <xsl:param name="num" />
  3.      <xsl:param name="total" />
  4. <a class="page_num">
  5.          <xsl:attribute name="href>page.php?num=<xsl:value-of select="$num"/></xsl:attribute>
  6.          <xsl:value-of select="$num"/>
  7. </a>
  8.   <xsl:if test="$num &lt; $total">
  9.     <xsl:call-template name="gen-page-nums">
  10.       <xsl:with-param name="num" select="$num + 1" />
  11.       <xsl:with-param name="total" select="$total" />
  12.     </xsl:call-template>
  13.   </xsl:if>
  14. </xsl:template>


Message édité par paquerette le 27-01-2005 à 12:19:59
Reply

Marsh Posté le 27-01-2005 à 12:23:46    

Ok , c'etatit quoi la question ?
 
y'a pas de truc genre <xsl:for  ?  
 
Ma reponse est bonne !! non ?
(avec une peu de mauvaise foi)
 
Bref sinon tu peux nous donner un petit exemple de code xml que tu as à traiter, j'aimerai verifier un truc

Reply

Marsh Posté le 27-01-2005 à 12:23:46   

Reply

Marsh Posté le 27-01-2005 à 12:41:19    

paquerette a écrit :

il manquait des / sur les value-of dans le lien


 
Ok, je corrige pour la postérité ;)


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 27-01-2005 à 14:43:06    

Ben la qestion elle est marquée et le code de  Mara's dad fonctionne très bien...
 
Je posterais une version avec la gestion d'une fenetre glissante pour l'affichage des liens genre :
 
1 2 ... 7 8 9 10 11 ... 24 25

Reply

Marsh Posté le 27-01-2005 à 15:27:23    

C bien comme ça on avance  !
Bon ben merci quand meme.

Reply

Marsh Posté le 28-01-2005 à 17:10:39    

Voila le XSL qui permet a partir de 3 chiffre de genéner les liens de pagination :
 
<< 1, 2, 3, ... 9, 10, [11], 12, 13, ... 25, 26, 27 >>
 
à partir de 3 infos :  
Page courante,
Nombre de page,
Taille de la fenetre glissante (nombre de liens a afficher autour de la page courante, de la premiere et derniere page)
 
le XSL est constitué de 2 templates (l'une récursive qui boucle sur les n° de page et l'autre qui affiche les liens << >>  et appel le template récursif)
 
Les choses a modifier : La facon dont les liens sont fait.
Dans mon environnement de dev, j'ai besoin de faire des onclick()... donc c'est des onclick...
Et il faut 2 images, changer les liens.
 
Merci à Mara's dad pour le script original...
Pour ma part, je me suis bien pris la tete pour afficher les '...' une fois.
 
 
La template à appeler :

Code :
  1. <!--
  2. Affiche une pagination pour une liste du type :
  3. << 1, 2, 3, ... 9, 10, [11], 12, 13, ... 25, 26, 27 >>
  4. Paramètres :
  5. currentPageNb : N° de page courante  (dans l'exemple précédent: 11)
  6. numberOfPage  : Nombre de page totale(dans l'exemple précédent: 27)
  7. windowSize    : détermine le nombre de liens à afficher autour de la première, dernière page et de la page courante (dans l'exemple précédent: 3)
  8. exemple d'appel :
  9. <xsl:call-template name="ListeTacheFragment_pagination">
  10.   <xsl:with-param name="currentPageNb"   select="queue/pageNumber"  />
  11.   <xsl:with-param name="numberOfPage"   select="queue/numberOfPage" />
  12.   <xsl:with-param name="windowSize"    select="3"         />
  13. </xsl:call-template>
  14. -->
  15. <xsl:template name="ListeTacheFragment_pagination">
  16.   <xsl:param name="currentPageNb"  />
  17.   <xsl:param name="numberOfPage"   />
  18.   <xsl:param name="windowSize"    />
  19. <center>
  20. <table border="0"  class="ListeTacheFragment_pagination_table">
  21. <tr>
  22. <td class="ListeTacheFragment_pagination_td_prev">
  23. <xsl:if test="$currentPageNb!='1'">
  24. <xsl:variable name="previousPage"></xsl:variable>
  25. <img  src="../../theme/images/Evenement/prev.gif"
  26. onclick="document.getElementById('ListeTacheFragment_pageNb').value={$currentPageNb - 1};document.getElementById('ListeTacheFragment_ACTION').value='EVENEMENT.ListeTacheFragment.navigate';submitPage();"
  27.     alt="Page pr&#233;c&#233;dente"
  28.   class="ListeTacheFragment_pagination_prev"
  29. />
  30. </xsl:if>
  31. </td>
  32. <td  class="ListeTacheFragment_pagination_td_nav">
  33.     <xsl:call-template name="ListeTacheFragment_pagination_rec">
  34.       <xsl:with-param name="currentPageNb"   select="$currentPageNb "   />   
  35.       <xsl:with-param name="pageToDisplay"   select="1" />
  36.       <xsl:with-param name="numberOfPage"    select="$numberOfPage"    />
  37.       <xsl:with-param name="windowSize"      select="$windowSize"    />     
  38.       <xsl:with-param name="displayLeftDots"  select="false" />
  39.       <xsl:with-param name="displayRightDots" select="false"/>
  40.     </xsl:call-template>
  41. </td>
  42. <td class="ListeTacheFragment_pagination_td_next">
  43. <xsl:if test="$currentPageNb!=$numberOfPage">
  44. <img  src="../../theme/images/Evenement/next.gif"
  45. onclick="document.getElementById('ListeTacheFragment_pageNb').value={$currentPageNb + 1};document.getElementById('ListeTacheFragment_ACTION').value='EVENEMENT.ListeTacheFragment.navigate';submitPage();"
  46.     alt="Page suivante"
  47.   class="ListeTacheFragment_pagination_next"
  48. />
  49. </xsl:if>
  50. </td>
  51. </tr>
  52. </table>
  53. </center>
  54. </xsl:template>


 
 
 
La template Récursive :  
 

Code :
  1. <!-- template récursif pour la pagination à ne pas appeler directement -->
  2. <xsl:template name="ListeTacheFragment_pagination_rec">
  3.   <xsl:param name="currentPageNb"  />
  4.   <xsl:param name="pageToDisplay"  />
  5.   <xsl:param name="numberOfPage"   />
  6.   <xsl:param name="windowSize"    />
  7.   <xsl:param name="displayLeftDots" />
  8.   <xsl:param name="displayRightDots"/>
  9. <xsl:variable name="displayCondition"><xsl:value-of select="$pageToDisplay &lt; $windowSize or $pageToDisplay &gt; $currentPageNb - $windowSize and $pageToDisplay &lt; $currentPageNb+$windowSize or $pageToDisplay &gt; $numberOfPage - ($windowSize - 1)"/></xsl:variable>
  10. <!--debug
  11. <div style="border:1px solid red;color:black;">
  12.   currentPage    :<xsl:value-of select="$currentPageNb"  /><br/>
  13.   pageToDisplay   :<xsl:value-of select="$pageToDisplay"  /><br/>
  14.   numberOfPage   :<xsl:value-of select="$numberOfPage"   /><br/>
  15.   windowSize    :<xsl:value-of select="$windowSize"    /><br/>
  16.   displayCondition :<xsl:value-of select="$displayCondition" /><br/>
  17.   displayLeftDots  :<xsl:value-of select="$displayLeftDots"  /><br/>
  18.   displayRightDots :<xsl:value-of select="$displayRightDots" /><br/>
  19. </div>
  20. -->
  21. <!-- Affiche le numéro de page en lien si ce n'est pas la page courante -->
  22. <xsl:if test="$displayCondition='true'">
  23. <xsl:if test="$pageToDisplay = $currentPageNb">
  24.  <span class="ListeTacheFragment_pagination_selected">
  25.     <xsl:value-of select="$pageToDisplay"/>
  26.  </span>
  27.  <xsl:if test="$pageToDisplay != $numberOfPage">
  28.   <b>,</b>
  29.   </xsl:if>
  30. </xsl:if>
  31. <xsl:if test="not($pageToDisplay = $currentPageNb)">
  32.  <a class="ListeTacheFragment_pagination">
  33.     <xsl:attribute name="onClick">document.getElementById('ListeTacheFragment_pageNb').value=<xsl:value-of select="$pageToDisplay"/>;document.getElementById('ListeTacheFragment_ACTION').value='EVENEMENT.ListeTacheFragment.navigate';submitPage();</xsl:attribute>
  34.     <xsl:value-of select="$pageToDisplay"/>
  35.    
  36.      <xsl:if test="$pageToDisplay != $numberOfPage">
  37.       <b>,</b>
  38.   </xsl:if>
  39.    
  40.  </a>
  41. </xsl:if>
  42. </xsl:if>
  43. <!-- Détermine s'il faut afficher les '...' (on est dans du récursif et il faut n'afficher les ... qu'une seule fois) -->
  44. <xsl:variable name="leftDotsOn"  ><xsl:if test="$displayCondition='false'"><xsl:if test="$pageToDisplay &lt; $currentPageNb"><xsl:value-of select="not($displayLeftDots='false')" /></xsl:if><xsl:if test="not($pageToDisplay &lt; $currentPageNb)">false</xsl:if></xsl:if><xsl:if test="$displayCondition='true'">false</xsl:if></xsl:variable>
  45. <xsl:variable name="rightDotsOn" ><xsl:if test="$displayCondition='false'"><xsl:if test="$pageToDisplay &gt; $currentPageNb"><xsl:value-of select="not($displayRightDots='false')"/></xsl:if><xsl:if test="not($pageToDisplay &gt; $currentPageNb)">false</xsl:if></xsl:if><xsl:if test="$displayCondition='true'">false</xsl:if></xsl:variable>
  46. <!-- debug
  47. <div style="border:1px solid blue;color:black;">
  48.   leftDotsOn     :'<xsl:value-of select="$leftDotsOn"           />'<br/>
  49.   rightDotsOn     :'<xsl:value-of select="$rightDotsOn"           />'<br/>
  50.   displayLeftDots  :'<xsl:value-of select="$displayLeftDots"         />'<br/>
  51.   displayRightDots :'<xsl:value-of select="$displayRightDots"        />'<br/>
  52.   nextParamLeft    :'<xsl:value-of select="$displayLeftDots='true'  or $leftDotsOn='true'" />'<br/>
  53.   nextParamRight   :'<xsl:value-of select="$displayRightDots='true' or $rightDotsOn='true'"/>'<br/>
  54. </div>
  55. -->
  56. <xsl:if test="$leftDotsOn='true' or $rightDotsOn='true'">
  57. <span class="ListeTacheFragment_pagination_dots">...</span>
  58. </xsl:if>
  59. <!-- appel de la page suivante-->
  60.   <xsl:if test="$pageToDisplay &lt; $numberOfPage">
  61.     <xsl:call-template name="ListeTacheFragment_pagination_rec">
  62.       <xsl:with-param name="currentPageNb"   select="$currentPageNb "   />   
  63.       <xsl:with-param name="pageToDisplay"   select="$pageToDisplay + 1" />
  64.       <xsl:with-param name="numberOfPage"    select="$numberOfPage"    />
  65.       <xsl:with-param name="windowSize"      select="$windowSize"    />
  66.      
  67.       <xsl:with-param name="displayLeftDots"  select="$displayLeftDots='true'  or $leftDotsOn='true'" />
  68.       <xsl:with-param name="displayRightDots" select="$displayRightDots='true' or $rightDotsOn='true'"/>
  69.      
  70.     </xsl:call-template>
  71.   </xsl:if>
  72. </xsl:template>


 
 
 
 
CSS :

Code :
  1. .ListeTacheFragment_pagination        {cursor: pointer;margin-left:3px;font-size: 15px;font-family: Verdana;}
  2. .ListeTacheFragment_pagination_selected  {margin-left:3px;font-size: 15px;font-family:Verdana;font-weight:bold;color:blue;}
  3. .ListeTacheFragment_pagination:hover     {color: red;}
  4. .ListeTacheFragment_pagination_dots      {margin-left:10px; margin-right:10px;font-size:30px;font-weight:bolder;}
  5. #ListeTacheFragment_pagination_row td    {height:36px;padding:2px;text-align:center;}
  6. .ListeTacheFragment_pagination_prev   {cursor: pointer;margin-right:10px;}
  7. .ListeTacheFragment_pagination_next   {cursor: pointer;margin-left:10px;}
  8. .ListeTacheFragment_pagination_td_prev  {}
  9. .ListeTacheFragment_pagination_td_nav  {height:34px;vertical-align:middle;}
  10. .ListeTacheFragment_pagination_td_next  {}
  11. .ListeTacheFragment_link      {cursor: pointer;}


Message édité par paquerette le 28-01-2005 à 17:11:42
Reply

Marsh Posté le 28-01-2005 à 17:22:44    

:jap:  
 
J'avais commencé de résoudre le pb des ..., mais j'ai vite arrêté parcequ'on peux voir la chose de plusieurs manières et que je ne savais pas ce qui te conviendrais.
 
En tout cas, c'est un truc à garder bien au chaud !


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 28-01-2005 à 17:33:11    

Ce qui est corriace c'est qu'on est dans un appel récursif et qu'en XSL visiblement une fois qu'on a déclarer une variable on peut pas la modifier...
 
Du coup, je passe 2 parametres qui me disent si j'ai déja afficher les '...' et comme c des boolean j'arrive a m'en sortir...
 
Sinon autre truc chiant en XSL c'est que y'a pas de else...  du coup si on veut vraiment un else sur une condition composer (genre a && b && c || d && e && f)...
 
parce que  
 
if(a && b && c || d && e && f)
a();
else
b();
 
n'est pas équivalent a  
 
if(a && b && c )
a();
 
if(!(a && b && c))
b();
 
 
Sinon, j'aurais pu modifier mon XML à la voler... mais je trouvais ca pas très propre de metre un truc genre dans le XML alors que finalement on a toute l'info qui faut avec 2 entier...:
<pagination>
 <value>1</value>
 <value>2</value>
 <value>...</value>
 <value>4</value>
 <value selected="true">5</value>
 <value>6</value>
 <value>7</value>
</pagination>
 
et puis ca m'a amusé  :pt1cable:


Message édité par paquerette le 28-01-2005 à 17:34:15
Reply

Marsh Posté le 28-01-2005 à 17:44:29    

Démo avec un fichier XML contenant la feuille XSL : http://www.surleau.com/hfr/pagination.xml
 
PS : J'ai remplacé les images par << et >>
 
PS2 : Pour ceux qui utilient autre choose qu'IE bien sûr...


Message édité par Mara's dad le 28-01-2005 à 17:49:44

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 28-01-2005 à 17:47:20    

cool :)
 
En ce moment, je bosse dans un boite ou je suis derrière un #$£* de proxy : pas de SSH, pas de ftp, pas de pop :'(, du coup, je peux pas faire ce genre de truc...


Message édité par paquerette le 28-01-2005 à 17:47:59
Reply

Marsh Posté le 28-01-2005 à 17:47:43    

Y'a pas de else, mais y'a :

Code :
  1. <xsl:choose>
  2. <xsl:when test="condition 1">
  3. ...
  4. </xsl:when>
  5. <xsl:when test="condition 2">
  6. ...
  7. </xsl:when>
  8. ...
  9. <xsl:when test="condition n">
  10. ...
  11. </xsl:when>
  12. <xsl:otherwise>
  13. ...
  14. </xsl:otherwise>
  15. </xsl:choose>


Du coup le xsl:otherwise peut servir de else ;)
 
 
   


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 28-01-2005 à 17:48:41    

ah ouais... cool...
Merci du tuyau.. :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed