XSLT Guides

Common XSLT transformation patterns, each tagged with the version it needs so you know whether it'll run in the compiler's XSLT 1.0 engine or the XSLT 2.0/3.0 engine. Sample XML and the matching stylesheet sit side by side — paste both straight into the XSLT Compiler to try them.

1. XML to HTML Table

All Versions

Transform a list of XML elements into an HTML table.

Sample XML
<catalog>
  <book>
    <title>XML Toolkit</title>
    <author>A. Novak</author>
  </book>
  <book>
    <title>Data Pipelines</title>
    <author>R. Singh</author>
  </book>
</catalog>
XSLT
<table>
<xsl:for-each select="catalog/book">
  <tr>
    <td><xsl:value-of select="title"/></td>
    <td><xsl:value-of select="author"/></td>
  </tr>
</xsl:for-each>
</table>

2. XML to Plain Text

All Versions

Use method="text" in <xsl:output> to extract plain text with no markup.

Sample XML
<catalog>
  <book>
    <title>XML Toolkit</title>
    <author>A. Novak</author>
  </book>
</catalog>
XSLT
<xsl:output method="text"/>
<xsl:template match="/">
  <xsl:for-each select="//book">
    <xsl:value-of select="title"/> by <xsl:value-of select="author"/><xsl:text>
</xsl:text>
  </xsl:for-each>
</xsl:template>

3. Filtering with xsl:if

All Versions

Show only books published after 1950.

Sample XML
<catalog>
  <book>
    <title>Old Classic</title>
    <year>1932</year>
  </book>
  <book>
    <title>Modern Read</title>
    <year>1998</year>
  </book>
</catalog>
XSLT
<xsl:for-each select="catalog/book">
  <xsl:if test="year > 1950">
    <p><xsl:value-of select="title"/></p>
  </xsl:if>
</xsl:for-each>

4. Sorting with xsl:sort

All Versions

Sort books alphabetically by title before rendering.

Sample XML
<catalog>
  <book><title>Zebra Facts</title></book>
  <book><title>Apple Pie</title></book>
  <book><title>Mango Tree</title></book>
</catalog>
XSLT
<xsl:for-each select="catalog/book">
  <xsl:sort select="title" order="ascending"/>
  <p><xsl:value-of select="title"/></p>
</xsl:for-each>

5. Grouping with xsl:for-each-group

XSLT 2.0 XSLT 3.0

Group orders by customer and total each group. xsl:for-each-group was introduced in XSLT 2.0, so this won't run on the compiler's 1.0 engine.

Sample XML
<orders>
  <order customer="Acme">100</order>
  <order customer="Acme">250</order>
  <order customer="Globex">75</order>
</orders>
XSLT (2.0/3.0)
<xsl:for-each-group select="orders/order" group-by="@customer">
  <p>
    <xsl:value-of select="current-grouping-key()"/>:
    <xsl:value-of select="sum(current-group())"/>
  </p>
</xsl:for-each-group>

6. Pattern Matching with xsl:analyze-string

XSLT 2.0 XSLT 3.0

Reformat a phone number using a regular expression. xsl:analyze-string and regex support arrived in XSLT 2.0.

Sample XML
<contact>
  <phone>5551234567</phone>
</contact>
XSLT (2.0/3.0)
<xsl:analyze-string select="contact/phone" regex="(\d{3})(\d{3})(\d{4})">
  <xsl:matching-substring>
    (<xsl:value-of select="regex-group(1)"/>)
    <xsl:value-of select="regex-group(2)"/>-<xsl:value-of select="regex-group(3)"/>
  </xsl:matching-substring>
</xsl:analyze-string>

7. Custom Functions with xsl:function

XSLT 2.0 XSLT 3.0

Define a reusable function to compute a discounted price. User-defined functions (xsl:function) need XSLT 2.0 or later and a namespace for the function name.

Sample XML
<item>
  <price>100</price>
</item>
XSLT (2.0/3.0)
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ex="http://example.com/fn">

  <xsl:function name="ex:discount">
    <xsl:param name="price"/>
    <xsl:sequence select="$price * 0.9"/>
  </xsl:function>

  <xsl:template match="item">
    <xsl:value-of select="ex:discount(price)"/>
  </xsl:template>
</xsl:stylesheet>

8. Splitting Output with xsl:result-document

XSLT 2.0 XSLT 3.0

Write one output file per book instead of a single combined result. xsl:result-document is a 2.0/3.0 feature for producing multiple outputs from a single transformation.

Sample XML
<catalog>
  <book id="bk101">
    <title>XML Toolkit</title>
  </book>
  <book id="bk102">
    <title>Data Pipelines</title>
  </book>
</catalog>
XSLT (2.0/3.0)
<xsl:for-each select="catalog/book">
  <xsl:result-document href="{@id}.xml">
    <book><xsl:copy-of select="title"/></book>
  </xsl:result-document>
</xsl:for-each>

9. JSON Output with xsl:map

XSLT 3.0

Produce JSON directly from XML using maps and xsl:output method="json" — both are XSLT 3.0-only additions, so this needs the 3.0 engine specifically.

Sample XML
<person>
  <name>Ada</name>
  <age>32</age>
</person>
XSLT (3.0 only)
<xsl:output method="json"/>
<xsl:template match="/person">
  <xsl:map>
    <xsl:map-entry key="'name'" select="name"/>
    <xsl:map-entry key="'age'" select="number(age)"/>
  </xsl:map>
</xsl:template>

Open Compiler →