Chapter 56: XSLT Tutorial
XSLT tutorial, written exactly as if I am your personal teacher sitting next to you.
We will go slowly, step by step, from zero to being able to write real, useful XSLT transformations. Every concept comes with:
- clear explanation
- visual analogies
- many small → medium → realistic examples
- common beginner mistakes
- “try this yourself” exercises
- real-world context (where people actually use XSLT today)
Let’s begin.
Lesson 0 – What is XSLT really? (5-minute honest explanation)
XSLT = XSL Transformations It is a special-purpose programming language designed to transform XML documents into other formats.
The most common outputs are:
- another XML document
- HTML (to display in browser)
- plain text
- JSON (in XSLT 3.0)
- PDF (via XSL-FO)
Think of XSLT as a translator + template engine
- The input is XML
- You write rules (“when you see this pattern, output that”)
- The XSLT processor reads the input XML and applies your rules
- You get a completely new document as output
Everyday analogy
Imagine you have a raw ingredients list written in XML:
|
0 1 2 3 4 5 6 7 8 9 10 |
<ingredients> <item>flour</item> <item>sugar</item> <item>eggs</item> </ingredients> |
You want to turn it into a nice recipe card in HTML.
XSLT is the chef who reads the list and follows your instructions:
“When you see <ingredients>, output
Recipe
” “When you see <item>, output
- + the item name +
”
You don’t write loops or if-statements like in Python or JavaScript — you write patterns and templates.
Lesson 1 – The absolute minimal XSLT stylesheet
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <!-- Main template – matches the root --> <xsl:template match="/"> <html> <body> <h1>Hello from XSLT!</h1> <p>This is a very simple transformation.</p> </body> </html> </xsl:template> </xsl:stylesheet> |
What this does:
- When the processor sees the root of any XML document (/), it runs this template
- It outputs a complete HTML page
Even if the input XML is empty — it will still produce this HTML.
Lesson 2 – The two most important concepts
- Templates — rules that say: “when you see this pattern, output that”
- apply-templates — “go find the best matching template for my children”
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<xsl:template match="book"> <div class="book"> <h2><xsl:value-of select="title"/></h2> <p>by <xsl:value-of select="author"/></p> <p>Price: <xsl:value-of select="price"/> <xsl:value-of select="price/@currency"/></p> </div> </xsl:template> |
Lesson 3 – Real example: Transform XML catalog → nice HTML table
Input XML (catalog.xml)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="UTF-8"?> <catalog> <product> <name>Wireless Mouse</name> <price currency="INR">1499.00</price> <stock>45</stock> </product> <product> <name>USB-C Hub</name> <price currency="INR">2499.00</price> <stock>12</stock> </product> </catalog> |
XSLT stylesheet (catalog-to-html.xsl)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes" encoding="UTF-8"/> <!-- Match the root --> <xsl:template match="/"> <html> <head> <title>Product Catalog</title> <style> table { border-collapse: collapse; width: 80%; margin: 20px auto; } th, td { border: 1px solid #ccc; padding: 10px; text-align: left; } th { background-color: #f0f0f0; } .low-stock { color: red; font-weight: bold; } </style> </head> <body> <h1>Product Catalog</h1> <table> <tr> <th>Name</th> <th>Price</th> <th>Stock</th> </tr> <!-- Apply templates to all <product> elements --> <xsl:apply-templates select="catalog/product"/> </table> </body> </html> </xsl:template> <!-- Template for each <product> --> <xsl:template match="product"> <tr> <td><xsl:value-of select="name"/></td> <td> <xsl:value-of select="price"/> <xsl:text> </xsl:text> <xsl:value-of select="price/@currency"/> </td> <td> <xsl:choose> <xsl:when test="stock &lt; 20"> <span class="low-stock"><xsl:value-of select="stock"/> (Low stock!)</span> </xsl:when> <xsl:otherwise> <xsl:value-of select="stock"/> </xsl:otherwise> </xsl:choose> </td> </tr> </xsl:template> </xsl:stylesheet> |
Result HTML (what the browser sees)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<html> <head>...</head> <body> <h1>Product Catalog</h1> <table> <tr><th>Name</th><th>Price</th><th>Stock</th></tr> <tr> <td>Wireless Mouse</td> <td>1499.00 INR</td> <td>45</td> </tr> <tr> <td>USB-C Hub</td> <td>2499.00 INR</td> <td class="low-stock">12 (Low stock!)</td> </tr> </table> </body> </html> |
Lesson 4 – The core building blocks of XSLT (with examples)
4.1 <xsl:template match=”pattern”>
The heart of XSLT.
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<xsl:template match="book"> <div class="book-card"> <h2><xsl:value-of select="title"/></h2> <p>by <xsl:value-of select="author"/></p> </div> </xsl:template> |
- match=”book” → this template runs when the processor sees a <book>
- <xsl:value-of select=”title”/> → copy the text content of the <title> child
4.2 <xsl:apply-templates>
Tells the processor: “now process my children using the best matching template”
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<xsl:template match="catalog"> <div class="catalog"> <h1>Our Products</h1> <xsl:apply-templates select="product"/> </div> </xsl:template> |
Without apply-templates, nothing inside <catalog> would be processed.
4.3 <xsl:value-of select=”expression”/>
The most common way to output text.
|
0 1 2 3 4 5 6 7 8 |
<xsl:value-of select="price"/> <xsl:value-of select="price/@currency"/> <xsl:value-of select="concat('Rs. ', price)"/> |
4.4 <xsl:if>
|
0 1 2 3 4 5 6 7 8 |
<xsl:if test="stock &lt; 10"> <span class="low-stock">Only <xsl:value-of select="stock"/> left!</span> </xsl:if> |
4.5 <xsl:choose> (if-elseif-else)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<xsl:choose> <xsl:when test="stock = 0"> <span style="color:red">Out of stock</span> </xsl:when> <xsl:when test="stock &lt; 10"> <span style="color:orange">Low stock: <xsl:value-of select="stock"/></span> </xsl:when> <xsl:otherwise> <span style="color:green">In stock</span> </xsl:otherwise> </xsl:choose> |
4.6 <xsl:for-each>
Classic loop (use sparingly — prefer apply-templates when possible)
|
0 1 2 3 4 5 6 7 8 |
<xsl:for-each select="product"> <li><xsl:value-of select="name"/> – <xsl:value-of select="price"/></li> </xsl:for-each> |
Lesson 5 – Try yourself exercises (do these!)
- Output only the titles in a bullet list
- Show product name + price with currency symbol
- If stock < 20, show “Low stock!” in red
- Create a table with columns: Name, Price, Stock
- Add a message “Free shipping” if price > 2000
- Show only products from category “electronics”
Lesson 6 – Real-world context (where XSLT is still used in 2025–2026)
- e-Invoice / e-Document transformation (GST, PEPPOL, Factur-X → HTML/PDF)
- Banking / Finance – ISO 20022 messages → human-readable reports
- Publishing – DocBook, DITA, JATS → HTML, PDF, EPUB
- Legacy SOAP web services – transform XML payload → HTML preview
- EDI / B2B integration – EDIFACT → XML → HTML confirmation
- Configuration files – transform XML config → documentation
- Report generation – raw XML data → styled PDF/HTML
Would you like to continue with one of these next?
- Identity transform (copy XML + make small changes)
- Grouping (XSLT 2.0/3.0 – group by category)
- XSLT variables & parameters
- XSLT with namespaces (very common in real data)
- XSLT 1.0 vs 2.0 vs 3.0 – what’s new & why it matters
- Real-world examples — GST invoice → HTML, RSS → styled feed
Just tell me which direction feels most useful or interesting for you right now! 😊
