Vlastní funkce v XSL

Vlastní funkce v XSL

XSLT nabízí celou řadu nativních funkcí jako například not(), sum() a řada dalších. XSLT 2.0 také přineslo podporu pro definování vlastních funkcí v XSLT šabloně, a právě na ni bych se chtěl podívat v tomto článku.

Vlastní XSLT funkci lze definovat pomocí elementu xsl:function, který má tři atributy. Prvním je jméno funkce, name, které musí obsahovat také namespace prefix. Ten je důležitý zejména proto, aby nedošlo ke kolizi s již existujícími XSLT funkcemi. Prefix také nesmí obsahovat žádný z rezervovaných prefixů viz W3 dokumentace. Druhým atributem je as, který definuje datový typ, jež funkce vrací. Nejčastější datové typy lze nalézt například na webu IBM, nezapomeňme ovšem, že v případě základních typů je nutné užít prefix xs:. Posledním atributem je override, který určuje, co se má stát, pokud již v šabloně existuje stejná funkce se stejným počtem parametrů, aritou. Poslední dva atributy není nutné specifikovat.

1<xsl:function name="rocek:getElementId" as="attribute()" override="yes">
2<!-- ... -->
3</xsl:function>

Funkce může přijímat také parametry, k tomuto účelu slouží element xsl:param. Stejně jako v případě funkce je nutné specifikovat atribut name, tentokrát ovšem není nutné uvádět namespace prefix. Atribut as opět určuje datový typ.

1<xsl:function name="rocek:getElementId" as="attribute()" override="yes">
2  <xsl:param name="element" as="element()" />
3</xsl:function>

Nakonec by měla funkce obsahovat nějaké tělo. V našem případě vrátíme ID elementu, a to buď z atributu xml:id nebo ana. Podle toho, zdali je ID přítomné. Nejsem si jistý, že by kdy bylo takovou funkci potřeba vytvářet, nicméně pro ilustrační účely takto jednoduchá funkce postačuje.

1<xsl:function name="rocek:getElementId" as="attribute()" override="yes">
2  <xsl:param name="element" as="element()" />
3  <xsl:choose>
4    <xsl:when test="$element/@xml:id">
5      <xsl:sequence select="$element/@xml:id"/>
6    </xsl:when>
7    <xsl:otherwise>
8      <xsl:sequence select="$element/@ana"/>
9    </xsl:otherwise>
10  </xsl:choose>
11</xsl:function>

Krom nadefinování funkce je nutné také registrovat vlastní namespace. Toho lze docílit pomocí úpravy XSL stylesheet hlavičky následujícím způsobem. Adresa za rovnítkem může být libovolná.

1<xsl:stylesheet
2  xmlns="http://www.tei-c.org/ns/1.0"
3  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4  xmlns:rocek="http://libovolna.adresa"
5  version="3.0"
6  exclude-result-prefixes="tei lindat"
7>
8  <!-- tělo šablony -->
9</xsl:stylesheet>

Po této úpravě je funkce úspěšně nadefinovaná a připravená na použití v našich transformacích. Třeba tímto způsobem:

1<xsl:template match="div">
2  <div id="section-{rocek:getElementId(current())}">
3    <xsl:apply-templates/>
4  </div>
5</xsl:template>