Potřebujete pomoci s XSLT?
Nabízím školení, konzultace, vývoj XSLT kódu na zakázku. Nevájte a kontaktujte mne.

Podpořte provoz stránek
Platba probíhá pomocí služby PayPal a je možné platit kartou nebo převodem z vašeho PayPal účtu.

11.3 Nahrazení iterace rekurzí

Při řešení některých úloh nás XSLT nutí zcela změnit návyky, které máme z jiných jazyků. I tak triviální úloha jako vypsání čísel od 1 do 100 se v XSLT může na první pohled jevit jako netriviální. Samotné XSLT nemá klasický příkaz cyklu, můžeme jen pomocí xsl:for-each provést iteraci nad seznamem uzlů. Máme-li jistotu, že ve vstupním dokumentu je alespoň 100 elementů, lze použít XPath výraz (//*)[position <= 100] k vybrání prvních 100 elementů. Kompletní použití této metody demonstruje následující příklad.

Příklad 11.4. Iterace pochybným způsobem – iterace1.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:template match="/">
  Pokus o vypsání čísel od 1 do 100:
  <xsl:for-each select="(//*)[position()&lt;=100]">
    <xsl:value-of select="position()"/>,
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Problém je v tom, že pokud bude v dokumentu méně než 100 elementů, nevypíší se všechna čísla až do 100. Správné řešení problému spočívá v použití rekurze. Vytvoříme si pojmenovanou šablonu, která v parametrech dostane informace o počátečním a koncovém čísle, která se mají projít. Šablona zpracuje počáteční číslo, a pokud je menší než koncové, zavolá sebe sama rekurzivně s počátečním číslem o jedničku zvýšeným. Toto počáteční číslo tak simuluje řídící proměnnou v klasických cyklech for, které známe z konvenčních jazyků.

Příklad 11.5. Iterace správným způsobem – iterace2.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:template match="/">
  Vypsání čísel od 1 do 100:
  <xsl:call-template name="iteruj">
    <xsl:with-param name="od" select="1"/>
    <xsl:with-param name="do" select="100"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="iteruj">
  <xsl:param name="od"/>
  <xsl:param name="do"/>

  <xsl:value-of select="$od"/>,
  <xsl:if test="$od &lt; $do">
    <xsl:call-template name="iteruj">
      <xsl:with-param name="od" select="$od + 1"/>
      <xsl:with-param name="do" select="$do"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Opět tedy využíváme metodu rozděl a panuj a problém dělíme na jednodušší podúlohy.

Jen dodejme, že v nové verzi XSLT 2.0 je řešení problému až směšně jednoduché:

<xsl:value-of select="1 to 100" separator=", "/>
© Jiří Kosek 2014

Tento dokument je určen výhradně pro osobní potřebu seznámení s jazykem XSLT. Jakékoliv jiné použití, včetně dalšího šíření, pořizování kopií, použití při školeních a výuce apod. je výslovně zakázáno a bude považováno za porušení autorských práv.


Copyright © 2000-2014 Jiří Kosek