Chapter 58: XSL(T) Languages
What does “XSL(T)” actually mean?
XSL = Extensible Stylesheet Language XSLT = XSL Transformations (the most important part)
These are three related but different specifications that were created together in the late 1990s / early 2000s:
| Name | Full name | Main purpose | Current version (2025–2026) | Still actively used? |
|---|---|---|---|---|
| XSLT | XSL Transformations | Transform XML into other XML / HTML / text / JSON | XSLT 3.0 (2017) | Very much alive |
| XSL-FO | XSL Formatting Objects | Describe page layout → create PDF | XSL-FO 1.1 (2006) | Niche / declining |
| XPath | XML Path Language | Select nodes in XML (used inside XSLT) | XPath 3.1 (2017) | Extremely common |
Most people say “XSLT” when they actually mean the whole family — because XSLT is the part that is used the most.
Lesson 1 – The big picture: What does XSLT do?
XSLT takes an XML document as input and produces a completely new document as output.
Most common outputs in real life:
- HTML (to display data in browser)
- Another XML (change structure, filter, rename tags, add/remove elements)
- Plain text (CSV, logs, email body…)
- JSON (XSLT 3.0+)
- PDF (via XSL-FO + processor like Apache FOP)
Everyday analogy
Imagine you have a raw shopping receipt written in XML:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<receipt> <item> <name>Milk</name> <quantity>2</quantity> <price>45.00</price> </item> <item> <name>Bread</name> <quantity>1</quantity> <price>35.00</price> </item> </receipt> |
You want to turn this into a nice printable bill that your customer can understand:
- Heading “Your Purchase”
- Numbered list
- Total at the bottom
- Thank you message
XSLT is the smart assistant who reads your raw receipt and follows your instructions to produce the nice bill.
You don’t write loops or variables like in Python/JavaScript — you write rules:
“When you see <receipt>, output
Your Purchase
” “When you see <item>, output
- + name + quantity + price +
” “At the end, calculate sum and output
Total: …
”
This is the declarative style of XSLT — you describe what the result should look like, not how to build it step by step.
Lesson 2 – The absolute minimal XSLT stylesheet (copy-paste & understand)
|
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 |
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Tell the processor: output HTML --> <xsl:output method="html" indent="yes" encoding="UTF-8"/> <!-- Main template – matches the root of any input XML --> <xsl:template match="/"> <html> <head> <title>Hello from XSLT</title> </head> <body> <h1>Welcome!</h1> <p>This page was created by XSLT.</p> <p>Even if your input XML is empty, I still produce this HTML.</p> </body> </html> </xsl:template> </xsl:stylesheet> |
What this does (very important to understand):
- The processor starts reading any XML document
- It looks for a template that matches the root of the document (/)
- It finds this template → runs the code inside
- It outputs a complete HTML page — even if the input was <nothing/>
This is the entry point of every XSLT transformation.
Lesson 3 – Real example 1: Transform product list → nice HTML table
Input XML (products.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 (products-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 64 65 66 |
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Output settings --> <xsl:output method="html" indent="yes" encoding="UTF-8"/> <!-- Match 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>Our Products</h1> <table> <tr> <th>Name</th> <th>Price</th> <th>Stock</th> </tr> <!-- Process every <product> --> <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>Our Products</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 – Core XSLT building blocks (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="product"> <div class="product-card"> <h3><xsl:value-of select="name"/></h3> <p>₹<xsl:value-of select="price"/></p> </div> </xsl:template> |
- match=”product” → this rule runs when the processor sees a <product>
- <xsl:value-of select=”price”/> → copy the text content of the <price> child
4.2 <xsl:apply-templates> – “now process my children”
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<xsl:template match="catalog"> <div class="catalog"> <h1>Products</h1> <xsl:apply-templates select="product"/> </div> </xsl:template> |
Without apply-templates, the <product> elements would be ignored.
4.3 <xsl:value-of select=”expression”/> – 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('Total: ₹', price * 1.18)"/> |
4.4 <xsl:if> – simple condition
|
0 1 2 3 4 5 6 7 8 |
<xsl:if test="stock &lt; 10"> <span style="color:red">Only <xsl:value-of select="stock"/> left!</span> </xsl:if> |
4.5 <xsl:choose> – if / else-if / 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</span> </xsl:when> <xsl:otherwise> <span style="color:green">Available</span> </xsl:otherwise> </xsl:choose> |
4.6 <xsl:for-each> – classic loop (use sparingly)
|
0 1 2 3 4 5 6 7 8 9 10 |
<ul> <xsl:for-each select="product"> <li><xsl:value-of select="name"/> – ₹<xsl:value-of select="price"/></li> </xsl:for-each> </ul> |
Best practice: Prefer <xsl:apply-templates> over <xsl:for-each> when possible — it’s more modular and reusable.
Lesson 5 – Try yourself exercises (do these!)
- Output only the product names in a bullet list
- Show 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-Invoicing — GST XML → human-readable HTML/PDF
- Financial messages — ISO 20022 → reports
- Publishing — DocBook/DITA → HTML/PDF/EPUB
- Legacy SOAP services — transform XML → preview
- EDI / B2B — EDIFACT → XML → confirmation page
- Configuration — XML config → documentation
Would you like to continue with one of these next?
- Identity transform (copy everything + make small changes)
- Grouping (group products by category – XSLT 2.0/3.0)
- XSLT variables & parameters
- XSLT with namespaces (real e-invoice, SOAP, Android manifest…)
- XSLT 1.0 vs 2.0 vs 3.0 – what’s new & why it matters
- Real-world example — GST invoice → nice HTML
Just tell me which direction feels most useful or interesting for you right now! 😊
