Software is like sex... It's better when it's free.

Blog - Simuler une boucle for en XSL

Simuler une boucle for en XSL

Si vous débutez en XSL, au delà des features basiques (select, for-each, choose, if, variable), vous avez dû être surpris de ne pas trouver de simple boucle for, alors que le for-each était présent ; or le for-each ne permet pas toujours de tout faire. Ainsi, si vous souhaitez faire une petite boucle for, plusieurs solutions s'offrent à vous. Pour les illustrer, nous allons prendre un exemple simple : une note/5 d'article (en float) en partant du fait que vous avez cette note dans votre flux xml, et que vous souhaitez afficher le nombre d'étoiles correspondant à cette note.

1ère solution, vous utilisez PHP5 et à l'aide de la fonction registerPHPFunctions() de la classe XSLTProcessor(), vous pouvez simplement utiliser l'une de vos fonctions PHP pour réaliser le traitement.

<?php
$xml = new DOMDocument()
$xml->load('flux.xml');
$xsl = new DOMDocument()
$xsl->load('flux.xsl');
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsl); 
echo $proc->transformToXML($xml);

function displayStars($note)
{
  $html = "";
  for($i=0 ; $i<floor($note) ; $i++)
    $html .= '<img src="Public/Styles/Img/star.gif" title="'.floor($note).'/5" />';
  echo $html;
}
?>

Ainsi, en XSL, vous n'avez qu'à appeler directement votre fonction PHP grâce au xmlns php, en ommettant pas l'attribut disable-output-escaping afin d'interpréter le HTML retourné pas votre fonction.

<!--
- Test passant par PHP
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:template match="root">
    <html>
      <head></head>
      <body>
        <xsl:value-of select="php:function('displayStars',//article/note)" disable-output-escaping="yes" />
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

La 2eme solution se base uniquement sur XSL et consiste en l'utilisation de templates récursifs afin de simuler une boucle for.

<!--
- Template récursif
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl"" version="1.0">
  <xsl:template name="displayStars">
    <xsl:param name="i" />
    <xsl:param name="length" />

    <!-- Traitement du for -->
    <img src="Public/Styles/Img/star.gif" alt="{concat($length,'/5')}" title="{concat($length,'/5')}" />
    <!-- /Traitement du for -->

    <!-- Tant que length n'est pas atteint, l'on rappele le template pour continuer la boucle -->
    <xsl:if test="$i < $length">
      <xsl:call-template name="displayStars">
        <xsl:with-param name="i" select="$i + 1" />
        <xsl:with-param name="length" select="$length" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Que l'on appellera comme ceci :

<!--
- Test d'appel du template récursif
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:template match="root">
    <html>
      <head></head>
      <body>
        <xsl:call-template name="displayStars">
          <xsl:with-param name="i" select="'1'" />
          <xsl:with-param name="length" select="round(//article/note)" />
        </xsl:call-template>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

A noter que même si la boucle for reste exploitable en XSL, il devient vite fastidieux de rédevelopper des templates spécifiques à chaque traitement de boucles.

Une 3e solution, pour les gros projets, si l'on conserve le même exemple de la note, est de s'arranger pour modifier légèrement la structure de son flux XML formé par PHP pour pouvoir réaliser son traitement avec seulement le for-each.

Ici, au lieu de former :

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <article>
    <note><![CDATA[3.4]]></note>
  </article>
</root>

On aurait pu former :

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <article>
    <note>
      <item><![CDATA[]]></item>
      <item><![CDATA[]]></item>
      <item><![CDATA[]]></item>
    </note>
  </article>
</root>

où le nombre d'item correspondant au floor() php afin de pouvoir "foreacher" tranquillement sur notre note et simuler une boucle for :

<!--
- For-each détourné
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:template match="root">
    <html>
      <head></head>
      <body>
        <xsl:variable name="note" select="count(//article/note/item)" />

        <xsl:for-each select="//article/note/item">
          <img src="Public/Styles/Img/star.gif" alt="{concat($note,'/5')}" title="{concat($note,'/5')}" />
        </xsl:for-each>

      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Vous pouvez voir que plusieurs solutions vous permettent de réaliser votre boucle, libre à vous de choisir celle qui vous convient le mieux, en rapport avec votre envirronnement technique et vos choix en matière d'architecture.

Tags:  phpxmlxsl.
Posté le Mercredi 06 mai 2009 19:32:22

Commentaires :

Xhfffugm, le jeudi 29 juillet 2010 23:31:05
This site is crazy :) statute of limitations on child sexual abuse in georgiasex position photos ybkbok teen bikinis ass butts pictures mjzxe hiliary clinton in a bikini
rjsej ls magazine is european =D mega cock blowjob tiny tits fgwcdg teen young anal porn fyanj little liza video clips 24351 cute teen pornstar rxt free tattoo designs virgin mary 48138 lost virginity videos 844937 teens in skimpy bikinis lowc virgin asian porn 343 young czech girl fuck 236401 cute brown teens vtot free youngest pussy 770459 chicago child porn lawyer 8( teen non nude 17yr ktpg gary sinise young 279 pre-teen incest rape sites ezydxq youngteen pussy wjpkc
Lldfejml, le jeudi 29 juillet 2010 23:30:54
magic story very thanks non nude art teen >:-) very young nude angels 909825 pubescent young girls pics =-((( nn kids tgp 854245 tiny girl penis 607824 candid non nude teen top 100
ysim free porn teen virgin 76178 12 years old young pussy :)) sexy young teen blonde on blonde red nude raider hentai games full length young children sex videos 0222 bikini club girl night philippine 8-] how can you tell im a virgin 8-[ kate cute teen =))) nakid girl photo %[[ very young preeten 8127 sister teaches young nerd brother 99503 3 d kiddie porn =)) bead bikini girls bogclf little girl in pink dress with 'blonde hair mhq cute porn toon 537
Feaetsdh, le jeudi 29 juillet 2010 23:30:41
Jonny was here youth 2008 theme young women :-)) young teen free nude photo %-))) ls magazine bbs ls land %DD nn child pics free 2129 divorce from keener files virgin mulroney 3315 white teen on young black cock 8-( the young americans eileen 7956 little years old girl nude pussy pics 7719 young pussy lesbian :-OO ls magazine doctor play =[[[ free illegal teen pics kjf nude young boy incest =-( european girl bbs
yeixjr child's first nude >:-OOO free child nudist pictures =OOO young nudist gallerys 5184 baby sissies loses her virginity %OO innocent cute teen anal >:-(( bikini cat fight girl in dez kid and nude girl 446
Satyre, le mercredi 03 juin 2009 19:35:39
Et Dieu dit : "Laurent, Wake up, XSL is waiting for you !" ;)
Très bon article !

Laisser un commentaire :

  
Captcha 
Ok