XSLT (eXtensible Stylesheet Language Transformations) is a powerful XML-based language used to transform XML documents into various formats like HTML, plain text, or another XML. It utilizes XPath expressions to navigate through elements and attributes in an XML document and transform them using defined rules and templates. This guide explains how to write and structure XSLT code for complex XML data, including handling nested nodes, conditional logic, filtering, output formatting, and advanced techniques
How to Start an XSLT File
An XSLT file starts with a standard XML declaration followed by the root <xsl:stylesheet> element, which contains the entire transformation logic.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- XSLT logic here -->
</xsl:stylesheet>
Purpose:
- The XML declaration specifies the version and encoding.
- The xsl:stylesheet tag defines the transformation logic and associates it with the appropriate XSL namespace.
- The xsl:output tag specifies the desired output format and formatting options (like indentation).
Linking XSLT to an XML Document
To use XSLT with an XML document in a browser, include a processing instruction:
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
Place this after the XML declaration. This tells the processor or browser which XSLT file to apply for transforming the XML.
Templates and XPath
Templates are the building blocks of XSLT. Each template matches specific nodes in the XML using XPath.
<xsl:template match="/">
<result>
<xsl:value-of select="/root/data/value"/>
</result>
</xsl:template>
This template matches the root node and extracts the value from a specific path.
Number of Templates: You can define **multiple **<xsl:template> blocks in a single XSLT file. Each template is triggered by matching specific XPath expressions. This allows XSLT to process various parts of your XML document modularly.
Example:
<xsl:template match="/">
<xsl:apply-templates select="catalog/book"/>
</xsl:template>
<xsl:template match="book">
<title><xsl:value-of select="title"/></title>
</xsl:template>
<xsl:template match="author">
<author><xsl:value-of select="."/></author>
</xsl:template>
Looping: for-each vs apply-templates
A. Using xsl:for-each
Use this when you want to explicitly iterate over a set of nodes:
<xsl:for-each select="/catalog/book">
<title>
<xsl:value-of select="title"/>
</title>
</xsl:for-each>
B. Using xsl:apply-templates
This allows more modular processing by delegating work to other templates:
<xsl:apply-templates select="/catalog/book"/>
<xsl:template match="book">
<title>
<xsl:value-of select="title"/>
</title>
</xsl:template>
The * Wildcard:
In XPath, * selects all child elements regardless of their name. It is useful when you want to apply a rule to all children without listing them:
<xsl:for-each select="*">
<xsl:value-of select="name()"/>
</xsl:for-each>
This is especially helpful when processing an unknown or dynamic XML structure
Conditional Logic in XSLT
XSLT supports conditional logic using xsl:if, xsl:choose, xsl:when, and xsl:otherwise. These constructs allow decision-making based on the data in the XML.
A. xsl:if
Use xsl:if to test a single condition and process content only if the condition is true:
<xsl:if test="price > 100">
<xsl:text>Premium Product</xsl:text>
</xsl:if>
B. xsl:choose, xsl:when, and xsl:otherwise
These tags provide multi-branch logic similar to if-else if-else in traditional programming languages:
<xsl:choose>
<xsl:when test="price > 100">
<xsl:text>Premium</xsl:text>
</xsl:when>
<xsl:when test="price > 50">
<xsl:text>Midrange</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Budget</xsl:text>
</xsl:otherwise>
</xsl:choose>
These control structures help tailor the output according to the content or attributes in your XML.
You can also nest conditional statements and combine them with logical operators like and, or, and not() for more complex decision trees.
Commonly Used Built-in Functions in XSLT
XSLT provides several built-in XPath functions to help with string manipulation, numeric calculations, and node handling. Here are some of the most commonly used functions:
- Position functions: position(), last()
- String functions: contains(), starts-with(), substring(), string-length(), normalize-space()
- Boolean functions: not(), boolean(), true(), false()
- Node set functions: count(), name(), local-name(), namespace-uri()
- Number functions: floor(), ceiling(), round()
A. Node and Position Functions
- position(): Returns the position of the current node in the context.
<xsl:value-of select="position()"/>
- last(): Returns the position of the last node in the current context.
<xsl:value-of select="last()"/>
B. String Functions
- contains(string1, string2): Checks if string1 contains string2.
<xsl:if test="contains(name, 'John')">Contains John</xsl:if>
- starts-with(string1, string2): Checks if string1 starts with string2.
<xsl:if test="starts-with(id, 'EMP')">Employee ID</xsl:if>
- substring(string, start, length?): Extracts a substring.
<xsl:value-of select="substring(name, 1, 3)"/>
- string-length(string): Returns the length of the string.
<xsl:value-of select="string-length(description)"/>
- normalize-space(string): Removes leading/trailing spaces and normalizes internal whitespace.
<xsl:value-of select="normalize-space(notes)"/>
C. Boolean Functions
- not(expression): Returns true if the expression is false.
<xsl:if test="not(active)">Inactive</xsl:if>
- boolean(expression): Converts the expression to a boolean.
<xsl:if test="boolean(price)">Price Exists</xsl:if>
- true() / false(): Return boolean constants.
D. Node Set Functions
- count(nodeset): Counts the number of nodes in a nodeset.
<xsl:value-of select="count(book)"/>
- name(): Returns the name of the current node.
<xsl:value-of select="name()"/>
- local-name(): Returns the local part of the name (excluding namespace).
<xsl:value-of select="local-name()"/>
- namespace-uri(): Returns the namespace URI.
E. Number Functions
- floor(number), ceiling(number), round(number): Rounding operations.
<xsl:value-of select="floor(3.9)"/>
These functions can be used in select, test, or any XPath context in XSLT.
Example:
<xsl:for-each select="item">
<xsl:if test="position() = 1">
<xsl:text>This is the first item</xsl:text>
</xsl:if>
</xsl:for-each>
Variables and Parameters
- Variables: Immutable values or node sets.
<xsl:variable name="discount" select="0.1"/>
<xsl:value-of select="price * (1 - $discount)"/>
- Parameters: Accept external values for templates or stylesheets.
<xsl:template name="discounted-price">
<xsl:param name="price"/>
<xsl:value-of select="$price * 0.9"/>
</xsl:template>
Modes in Templates
Modes enable multiple processing styles on the same nodes:
<xsl:template match="book" mode="summary">
<summary><xsl:value-of select="title"/></summary>
</xsl:template>
<xsl:template match="book" mode="detailed">
<detailed>
<title><xsl:value-of select="title"/></title>
<author><xsl:value-of select="author"/></author>
</detailed>
</xsl:template>
Apply templates with mode:
<xsl:apply-templates select="book" mode="summary"/>
<xsl:apply-templates select="book" mode="detailed"/>
Excluding Nodes from Processing
- Empty template to ignore nodes:
<xsl:template match="unwantedNode"/>
- Filtering in XPath:
<xsl:for-each select="catalog/book[not(@status='discontinued')]">
<xsl:value-of select="title"/>
</xsl:for-each>
Namespace Handling
- Declare namespaces in XSLT:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com/ns"
version="1.0"
exclude-result-prefixes="ns">
- Match namespaced elements:
<xsl:template match="ns:elementName">
<xsl:value-of select="."/>
</xsl:template>
- Remove namespaces in output:
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
Advanced XPath Techniques
- Axes: self::, parent::, ancestor::, following-sibling::
<xsl:value-of select="self::book/title"/>
- not() negates a condition:
<xsl:if test="not(contains(description, 'deprecated'))">Valid</xsl:if>
- self:: refers to the current node explicitly, useful in complex XPath.
Concept of Leaf Node
- A leaf node is an XML element with no child elements, only text or empty.
Example:
<book>
<title>XML Guide</title> <!-- leaf node -->
<author>John</author> <!-- leaf node -->
<details>
<pages>200</pages> <!-- leaf node -->
</details> <!-- NOT leaf node -->
</book>
Extracting Values from Name-Value Pairs
Given this structure:
<PersonalDetails>
<name>PROFESSION</name>
<value>SoftwareEngineer</value>
</PersonalDetails >
Extract value for a given name:
<xsl:value-of select="/root/PersonalDetails [name= ‘PROFESSION’]/value"/>
Or in template:
<xsl:template match=" PersonalDetails [name= ‘PROFESSION’]">
<xsl:value-of select="value"/>
</xsl:template>
Use of Logical Operators and Special XPath Axes
- not() operator: Negates a boolean expression.
<xsl:if test="not(active)">
<xsl:text>Inactive</xsl:text>
</xsl:if>
- self:: operator: Refers explicitly to the current node.
- self:: is used in XPath for clarity or complex expressions to refer to the node itself.
Maximum Number of Templates in XSLT
- XSLT allows unlimited <xsl:template> blocks.
- Use as many as needed to modularly handle different XML parts.
- Templates are matched by XPath or name for flexible processing.
Example:
<xsl:template match="/">
<html>...</html>
</xsl:template>
<xsl:template match="book">
<div class="book">...</div>
</xsl:template>
<xsl:template match="author">
<span class="author">...</span>
</xsl:template>
Discover more from Let's Simplify
Subscribe to get the latest posts sent to your email.