Kompletní průvodce XSLT – řízení toku transformace
Znalosti z předchozích článků nám stačí k vytváření poměrně mocných transformací, občas se však hodí mít k dispozici některé konstrukce známé z běžných programovacích jazyků, jako je podmíněné provádění a iterace. A právě s nimi se seznámíme v tomto článku.
Podmíněné provádění
Podmínky jsme částečně schopni nasimulovat již teď, například pomocí <xsl:apply-templates />
s parametrem select
. Pokud je výsledkem vyhodnocení tohoto parametru nějaký uzel, aplikují se na něj další šablony, v opačném případě průběh transformace pokračuje normálně dále. Pokud je však výsledkem více uzlů, jsou zpracovány všechny, což ale někdy není vhodné. Lze to sice ošetřit XPath predikátem (select="...[1]"
– vrací pouze první uzel v pořadí), jistě však souhlasíte, že to není zrovna to pravé ořechové. A proto nastupují další syntaktické prvky jazyka XSLT.
<xsl:if test=“…“>
Tato XSLT instrukce je synonymem pro příkaz if
, známý z běžných programovacích jazyků. Syntaxe a použití jsou určitě zřejmé již z nadpisu. Parametr test
obsahuje výraz podmínky, který se vyhodnotí a, je-li třeba, je převeden na logickou hodnotu pomocí XPath funkce boolean()
. Tato funkce pracuje s různými datovými typy dle následující tabulky:
Datový typ | Výsledek je true pokud… |
---|---|
number | hodnota není nulová nebo NaN |
node-set (seznam uzlů) | seznam obsahuje alespoň jeden uzel |
string (řetězec) | řetězec má nenulovou délku |
jiný typ | způsob závisí na konkrétním datovém typu |
Takto je podmínka vyhodnocena a pokud je její výsledek logická pravda (true), šablona uvnitř značek <xsl:if>
a </xsl:if>
se provede, jinak je ignorována. Malý příklad:
<?xml version=’1.0′?>
<xsl:stylesheet
xmlns:xsl=’http://www.w3.org/1999/XSL/Transform‘
version=’1.0′>
<xsl:template match=’/‘>
…
<xsl:if test=“price“>
cena: <xsl:value-of select=“price“ />,- Kč
</xsl:if>
…
</xsl:template>
</xsl:stylesheet>
Pokud vstupní dokument obsahuje element price
, například <price>660</price>
, je vygenerován jeho obsah v tomto formátu: cena: 660,- Kč. V opačném případě nebude na výstupu o ceně ani zmínka.
<xsl:choose>, <xsl:when> a <xsl:otherwise>
Možná jste si všimli, že v popisu předchozí instrukce xsl:if
schází popis použití sekce else
, která je jinak poměrně obvyklá. Tato možnost v XSLT vůbec neexistuje – pokud chcete zpracovat i stav nesplnění podmínky, musíte použít ještě jednou instrukci xsl:if
s opačnou podmínkou nebo raději použít vícenásobné větvení.
Tyto instrukce jsou obdobou příkazu switch
, známého z mnoha programovacích jazyků vycházejících z C, respektive select
, který možná znáte z Visual Basicu a podobných. Je zde však podstatný rozdíl – zatímco jinde je nejdříve vyhodnocen výraz a jeho hodnota je pak srovnávána s hodnotami v jednotlivých větvích, v XSLT má každá větev svou podmínku (kromě výchozí větve). Všechny větve se procházejí v tom pořadí, v jakém jsou definovány, a obsah první, jejíž podmínka je vyhodnocena jako pravdivá, je zpracován, jinak je zpracována výchozí větev (xsl:otherwise
), pokud je definována. Následuje opět jednoduchý příklad:
…
<xsl:choose>
<xsl:when test=“number(price) > 600″>
velmi vysoká cena
</xsl:when>
<xsl:when test=“number(price) > 400″>
normální cena
</xsl:when>
<xsl:when test=“price“>
pozor – akční cena!!!
</xsl:when>
<xsl:otherwise>
cena neurčena
</xsl:otherwise>
</xsl:choose>
…
Pokud vás zarazila entita >
v XPath výrazu, uvědomte si, že do XML atributu nemůžeme přímo zapsat znak >
. Výraz je procesorem nejdříve dekódován a teprve pak zpracován. Předposlední větev se zpracuje, pokud element price
alespoň existuje, ať už je jeho hodnota jakákoli, a pokud element vůbec není přítomen, zpracuje se větev poslední. Myslím, že k příkladu už není co dodat.
Iterace
Iterace, smyčky, prostě opakované zpracování dat stejným způsobem. Ačkoli v XSLT díky šablonám je tento úkol řešitelný mnoha způsoby, které jsou schopny splnit nám téměř všechna přání, přesto zde existuje také alternativa známého příkazu for
v trochu upravené podobě:
<xsl:for-each>
Zjednodušeně řečeno, šablona uvnitř této instrukce je zpracována pro každý uzel vrácený z parametru select
této instrukce. Každý takový uzel se pro tuto šablonu zároveň stane aktuálním (kontextovým) uzlem. Mějme tedy například následující fragment vstupního XML dokumentu:
<price-list>
<variant>
<code>UF-1</code>
<price>399</price>
</variant>
<variant>
<code>UF-1a</code>
<price>499</price>
</variant>
</price-list>
Je to v podstatě jednoduchý ceník se dvěma položkami, který budeme chtít zpracovat do HTML tabulky. Můžeme k tomu použít tuto transformaci:
<table>
<tr>
<th>Varianta</th>
<th>Cena</th>
</tr>
<xsl:for-each select=“price-list/variant“>
<tr>
<td><xsl:value-of select=“code“/></td>
<td><xsl:value-of select=“price“/> Kč</td>
</tr>
</xsl:for-each>
</table>
Myslím, že je zřejmé, jak tento příklad funguje. Hodnoty code
a price
jsou vyhodnoceny vždy relativně vzhledem k aktuálnímu uzlu, kterým je právě zpracovávaná varianta.
Řazení uzlů
Instrukce xsl:apply-templates
a xsl:for-each
podporují seřazení zpracovávaných uzlů předtím, než jsou zpracovány. K tomu slouží instrukce xsl:sort
, vložená jako první do jejich těla. Tato instrukce umožňuje řazení podle určitého klíče, pokud chcete řadit podle více klíčů, není nic jednoduššího, než přidat řadících instrukcí více. Přednost má ta, která je uvedena dříve.
<xsl:sort>
Instrukce má několik parametrů, kterými můžeme způsob řazení specifikovat podrobněji.
select
- Klíč pro řazení. Je to XPath výraz, který je počítán relativně vzhledem k momentálně vyhodnocovanému uzlu, a podle výsledků tohoto výrazu jsou pak uzly seřazeny pro další zpracování. Výchozí hodnotou je
.
, tedy celý textový obsah aktuálního uzlu. data-type
- Udává, jak se má klíč vyhodnotit. Možnými hodnotami jsou
text
,number
a nebo plně kvalifikovaný název jiného typu, který není v XSLT definován. Protext
je klíč vyhodnocen XPath funkcístring()
a pronumber
překvapivě funkcínumber()
. lang
- Pokud se klíč vyhodnocuje jako text, tímto parametrem lze specifikovat jazyk, dle kterého budou řetězce porovnány. Možné hodnoty jsou stejné jako pro
xml:lang
. Výchozí hodnotou by mělo být aktuální jazykové prostředí počítače. case-order
- Může být buď
upper-first
nebolower-first
. Udává, zda mají přednost nejdříve velká písmena (první případ) a nebo malá. Pokud parametr není uveden, způsob řazení závisí na nastaveném jazyce. order
- Pokud je
ascending
(výchozí hodnota), řazení je vzestupné, jinakdescending
znamená sestupné řazení.
Ukázkový vstupní dokument:
<contacts>
<person>
<given>Petr</given>
<family>Bříza</family>
<email>petr.briza@spol.cz</email>
</person>
<person>
<given>Vilém</given>
<family>Málek</family>
<email>vilem.malek@interval.cz</email>
</person>
</contacts>
Tato data seřadíme vzestupně podle příjmení a jména do HTML seznamu:
<ul>
<xsl:for-each select=“contacts/person“>
<xsl:sort select=“family“>
<xsl:sort select=“given“>
<li>
<a href=“mailto:{email}“>
<xsl:value-of select=“concat(given, ‚ ‚, family)“/>
</a>
</li>
</xsl:for-each>
</ul>
Příklad opět sdružuje ukázky hned několika syntaktických prvků XSLT: iterace, řazení, generování fragmentů atributů, vkládání hodnoty a praktického využití XPath funkce concat
. Výsledkem je seřazený seznam všech kontaktních osob, zahrnující interakci s aktuálním emailovým klientem uživatele.
Číslování
K číslování slouží velice mocná instrukce xsl:number
, umožňující číslování například nadpisů a dalších částí výsledku podle mnoha různých formátů číselných a jiných řad. Jednoduché použití pro vstupní dokument z předchozího příkladu:
<xsl:for-each select=“contacts/person“>
<p>
<xsl:number value=“position()“ format=“1. „/>
<a href=“mailto:{email}“>
<xsl:value-of select=“concat(given, ‚ ‚, family)“/>
</a>
</p>
</xsl:for-each>
Parametr format
může obsahovat definice známé z parametru type
elementu OL
v HTML 4.0, tedy například a
a A
znamenají řadu malých či velkých písmen, a i
a I
je řada římských číslic. Tato instrukce toho umí podstatně více a já ji v některém z dalších článků rozeberu podrobněji. Zájemce o toto téma prozatím odkazuji na specifikaci, nebo příručku Jiřího Koska.
Odkazy, zdroje
- The Extensible Stylesheet Language Family (XSL) (W3C)
- XSLT v příkladech – Jiří Kosek
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
inPage AI: Jak na generování obsahu
18. července 2024 -
Windows App: Pracujte odkudkoliv, kdykoliv
3. listopadu 2024 -
Optimalizace a zlepšení výkonu kódu: tipy a triky
14. srpna 2023
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024