<xsl:function> XSLT

Элемент xsl:function определяет функцию, которая может использоваться в выражениях XPath в таблице стилей.

Элементы-родители:

Элементы-потомки:

Синтаксис

XSLT 2.0

<xsl:function
    name = "qname"
    as = "sequence-type"
    override = "yes | no">
    <!-- Content: (xsl:param*, sequence-constructor) -->
</xsl:function>

Атрибуты

  • nameобязательный атрибут, определяет имя функции.
  • asнеобязательный атрибут, определяет тип данных, возвращаемый функцией.
  • overrideнеобязательный атрибут, определяет, должна ли функция замещать другую функцию с теми же именем и количеством аргументов, которая предоставляется процессором за пределами области видимости таблицы стилей. Значение по умолчанию override="yes" означает, что использоваться должна определяемая функция (то есть она замещает внешнюю функцию); со значением override="no" используется внешняя функция.

XSLT 3.0

<xsl:function
    name = eqname
    as? = sequence-type
    visibility? = "public" | "private" | "final" | "abstract"
    streamable? = boolean
    override-extension-function? = boolean
    [override]? = boolean
    identity-sensitive? = boolean
    cache? = "full" | "partial" | "no" >
    <!-- Content: (xsl:param*, sequence-constructor) -->
</xsl:function>

Описание и примеры

Пример

Таблица стилей использует три элемента <xsl:function> для получения цвета фона, размера шрифта и стиля различных элементов HTML. Размещение этой логики в функции позволяет обратиться к функции из шаблона значения атрибута. Таблица стилей выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<!-- function.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sample="http://www.oreilly.com/catalog/xslt" exclude-result-prefixes="xs sample">
    <xsl:output method="html" include-content-type="no"/>
    <xsl:variable name="colors" as="xs:string *" select="('yellow', 'white', 'blue')"/>
    <xsl:variable name="fontSizes" as="xs:integer *" select="(18, 24, 36)"/>
    <xsl:variable name="styles" as="xs:string *" select="('color: black;', 'color: black;', 'color: white; font-weight: bold;')"/>
    <xsl:template match="/">
        <html>
            <head>
                <title>
                    <xsl:value-of select="/list/title"/>
                </title>
            </head>
            <body style="font-family: sans-serif;">
                <h1 style="font-size: 48;">
                    <xsl:value-of select="/list/title"/>
                </h1>
                <table border="3" cellpadding="5" cellspacing="5" width="50%">
                    <tr>
                        <xsl:for-each select="/list/listitem">
                            <td style="font-size: {sample:getFontSize(position())}; {sample:getStyle(position())}" bgcolor="{sample:getColor(position())}">
                                <xsl:value-of select="."/>
                            </td>
                        </xsl:for-each>
                    </tr>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:function name="sample:getColor" as="xs:string">
        <xsl:param name="pos” as="xs:integer"/>
        <xsl:value-of select="$colors[($pos mod count($colors)) + 1]"/>
    </xsl:function>
    <xsl:function name="sample:getStyle" as="xs:string">
        <xsl:param name="pos” as="xs:integer"/>
        <xsl:value-of select="$styles[($pos mod count($styles)) + 1]"/>
    </xsl:function>
    <xsl:function name="sample:getFontSize" as="xs:integer">
        <xsl:param name="pos" as="xs:integer"/>
        <xsl:value-of select="$fontSizes[($pos mod count($fontSizes)) + 1]"/>
    </xsl:function>
</xsl:stylesheet>

Функции работают с переменными colors и fontSizes, определяемыми как последовательности строк и целых чисел соответственно. Функции getColor() и getFontSize() вызываются с позицией текущего узла; для определения возвращаемого объекта последовательности в них используется оператор mod.

Обратите внимание: индекс объекта, возвращаемого функциями, увеличивается на 1. Первый объект последовательности находится в позиции 1, а не 0. Кроме того, чтобы упростить сопровождение кода, мы используем функцию count() для определения второго операнда оператора mod. При добавлении в последовательности новых цветов или размеров шрифтов нам не придется изменять определения функций в соответствии с новым размером.

Для преобразования списка альбомов используется следующая таблица стилей:

<?xml version="1.0"?>
<!-- albums.xml -->
<list xml:lang="en">
    <title>Albums I've bought recently:</title>
    <listitem>The Sacred Art of Dub</listitem>
    <listitem>Only the Poor Man Feel It</listitem>
    <listitem>Excitable Boy</listitem>
    <listitem xml:lang="sw">Aki Special</listitem>
    <listitem xml:lang="en-gb">Combat Rock</listitem>
    <listitem xml:lang="zu">Talking Timbuktu</listitem>
    <listitem xml:lang="jz">The Birth of the Cool</listitem>
</list>

Сгенерированный документ HTML выглядит так:

<html>
    <head>
        <title>Albums I've bought recently:</title>
    </head>
    <body style="font-family: sans-serif;">
        <h1 style="font-size: 48;">Albums I've bought recently:</h1>
        <table border="3" cellpadding="5" cellspacing="5" width="50%">
            <tr>
                <td style="font-size: 24; color: black;" bgcolor="white">The Sacred Art of Dub</td>
                <td style="font-size: 36; color: white; font-weight: bold;" bgcolor="blue">     Only the Poor Man Feel It</td>
                <td style="font-size: 18; color: black;" bgcolor="yellow">Excitable Boy</td>
                <td style="font-size: 24; color: black;" bgcolor="white">Aki Special</td>
                <td style="font-size: 36; color: white; font-weight: bold;" bgcolor="blue">Combat Rock</td>
                <td style="font-size: 18; color: black;" bgcolor="yellow">Talking Timbuktu</td>
                <td style="font-size: 24; color: black;" bgcolor="white">The Birth of the Cool</td>
            </tr>
        </table>
    </body>
</html>

Значения атрибутов bgcolor и style генерируются определенными нами функциями XSLT.

Функции XSLT способны заметно упростить как сами таблицы стилей, так и их сопровождение. В нашей таблице стилей XSLT 2.0 атрибут bgcolor создается следующей разметкой:

bgcolor="{sample:getColor(position())}"

А вот как то же самое делается в XSLT 1.0:

<xsl:attribute name="bgcolor">
    <xsl:choose>
        <xsl:when test="position() mod 3 = 0">
            <xsl:text>yellow</xsl:text>
        </xsl:when>
        <xsl:when test="position() mod 3 = 1">
            <xsl:text>white</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>blue</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:attribute>