SyntaxStudy
Sign Up
XML XSLT Control Structures and Variables
XML Beginner 1 min read

XSLT Control Structures and Variables

XSLT provides a set of control-flow instructions that mirror what you would expect in a programming language. The instruction iterates over a node-set and processes each node. The instruction conditionally includes output. The / / construct provides multi-way branching. The element, used inside or , controls the processing order of nodes by specifying a sort key, data type, and sort order. Variables and parameters allow values to be named and reused. A variable is declared with and referenced as $name. Variables in XSLT are immutable — once set they cannot be reassigned, which is a side-effect of the functional programming model underlying the language. Parameters () work like variables but receive their initial value from the caller: a stylesheet parameter is set by the invoking application, and a template parameter is passed via or . Named templates () are called explicitly with , enabling reuse of template logic. This is the XSLT equivalent of a function call, though XSLT 1.0 does not support recursion-based loops with mutable counters. Recursive named templates are used instead to simulate loops, passing an index as a parameter and decrementing it with each call until the base case is reached.
Example
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text" encoding="UTF-8"/>

    <!-- Stylesheet-level parameter (passed by caller) -->
    <xsl:param name="maxPrice" select="50"/>

    <xsl:template match="/">
        <!-- Variable: count of all books -->
        <xsl:variable name="bookCount" select="count(//book)"/>
        <xsl:text>Total books: </xsl:text>
        <xsl:value-of select="$bookCount"/>
        <xsl:text>&#10;</xsl:text>

        <!-- for-each with sort -->
        <xsl:for-each select="//book">
            <xsl:sort select="year" data-type="number" order="descending"/>

            <!-- if: only list affordable books -->
            <xsl:if test="price &lt;= $maxPrice">
                <xsl:value-of select="year"/>
                <xsl:text> — </xsl:text>
                <xsl:value-of select="title"/>
                <xsl:text> ($</xsl:text>
                <xsl:value-of select="price"/>
                <xsl:text>)&#10;</xsl:text>
            </xsl:if>
        </xsl:for-each>

        <!-- choose / when / otherwise -->
        <xsl:variable name="total" select="sum(//price)"/>
        <xsl:text>Budget status: </xsl:text>
        <xsl:choose>
            <xsl:when test="$total &lt; 20">Low spend</xsl:when>
            <xsl:when test="$total &lt; 60">Moderate spend</xsl:when>
            <xsl:otherwise>High spend</xsl:otherwise>
        </xsl:choose>
        <xsl:text>&#10;</xsl:text>

        <!-- Named template call -->
        <xsl:call-template name="separator"/>
    </xsl:template>

    <!-- Named template: reusable output fragment -->
    <xsl:template name="separator">
        <xsl:text>----------------------------&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>