Chapter 61: XSLT
1. What does <xsl:value-of> really do?
<xsl:value-of> is the most frequently used instruction in XSLT.
Its only job is:
Take the result of an XPath expression Convert it to a string Output that string into the result document
In other words:
|
0 1 2 3 4 5 6 7 8 |
<xsl:value-of select="something" /> = "please evaluate this XPath expression and write the result as text right here" |
It is the XSLT equivalent of:
- print() in Python
- echo or <?= in PHP
- console.log() (but writing to output instead of console)
2. The simplest possible usage
|
0 1 2 3 4 5 6 |
<xsl:value-of select="title" /> |
What happens inside the processor?
- It looks at the current context node (the node the current template is processing)
- It evaluates the XPath expression title
- It finds the child element named <title>
- It takes all text content inside that element (including descendants)
- It writes that text to the output
So if the current node is:
|
0 1 2 3 4 5 6 7 8 |
<book> <title>Atomic Habits</title> </book> |
then
|
0 1 2 3 4 5 6 |
<xsl:value-of select="title" /> |
outputs exactly:
|
0 1 2 3 4 5 6 |
Atomic Habits |
3. The most important attribute: select
Almost every <xsl:value-of> has exactly one important attribute:
|
0 1 2 3 4 5 6 |
<xsl:value-of select="expression" /> |
The select attribute contains an XPath expression that is evaluated against the current context node.
Very common examples
| Current context node is | XPath expression | What is outputted | Explanation |
|---|---|---|---|
| <book> | title | Atomic Habits | child element text |
| <book> | author | James Clear | child element text |
| <book> | price | 499.00 | child element text |
| <price> | @currency | INR | attribute value |
| <book> | @id | b1 | attribute value |
| <book> | price/@currency | INR | attribute of child |
| <book> | concat(title, ” by “, author) | Atomic Habits by James Clear | calculated string |
| <book> | price * 1.18 | 588.82 (if price is 499) | arithmetic result |
4. Very common real-life patterns
Pattern 1 – Output element text + attribute
|
0 1 2 3 4 5 6 7 8 9 10 11 |
<p> Price: <strong><xsl:value-of select="price"/></strong> <xsl:text> </xsl:text> <xsl:value-of select="price/@currency"/> </p> |
→ Price: 499.00 INR
Pattern 2 – Conditional value
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<td> <xsl:choose> <xsl:when test="stock = 0"> <span style="color:red">Out of stock</span> </xsl:when> <xsl:otherwise> <xsl:value-of select="stock"/> </xsl:otherwise> </xsl:choose> </td> |
Pattern 3 – Format numbers nicely
|
0 1 2 3 4 5 6 |
<xsl:value-of select="format-number(price, '#,##0.00')"/> |
→ 1,499.00 (if price was 1499)
Pattern 4 – Output current date/time
|
0 1 2 3 4 5 6 |
<p>Generated on: <xsl:value-of select="current-dateTime()"/></p> |
→ Generated on: 2025-07-28T14:35:22.123+05:30
Pattern 5 – Safe output (avoid missing elements)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
<xsl:value-of select="name" /> <!-- is the same as --> <xsl:value-of select="name" /> <!-- missing element = empty string --> <!-- Safer version --> <xsl:value-of select="name" /> <xsl:if test="not(name)">No name available</xsl:if> |
5. Important attributes of <xsl:value-of>
| Attribute | Purpose | Default value | Common values / examples |
|---|---|---|---|
| select | XPath expression to evaluate | — (required) | title, price/@currency, count(product) |
| disable-output-escaping | Allow < > & to be output literally | no | yes (rare, dangerous – XSS risk in HTML) |
| separator | String to put between multiple items | (space) | , or ` |
Example with separator
|
0 1 2 3 4 5 6 |
<xsl:value-of select="author" separator=", " /> |
If there are multiple authors:
|
0 1 2 3 4 5 6 7 |
<author>James Clear</author> <author>Co-author</author> |
→ James Clear, Co-author
6. Common beginner mistakes & how to avoid them
Mistake 1 Using select with wrong context
|
0 1 2 3 4 5 6 7 8 |
<xsl:template match="price"> <xsl:value-of select="price"/> <!-- WRONG – price has no child price --> </xsl:template> |
Fix
|
0 1 2 3 4 5 6 7 8 |
<xsl:value-of select="."/> <!-- current node --> <!-- or --> <xsl:value-of select="text()"/> <!-- direct text children --> |
Mistake 2 Forgetting that textContent includes all descendants
|
0 1 2 3 4 5 6 |
<xsl:value-of select="book"/> |
→ outputs all text inside the book (titles + authors + prices concatenated)
Fix Use more specific XPath: book/title
Mistake 3 Trying to output markup with value-of
|
0 1 2 3 4 5 6 |
<xsl:value-of select="'<strong>Important</strong>'"/> |
→ outputs literal <strong>Important</strong> (text, not HTML)
Fix Use literal result elements:
|
0 1 2 3 4 5 6 |
<strong>Important</strong> |
or <xsl:element name=”strong”>
7. Try yourself exercises (do these!)
- Output product name followed by price in parentheses
- Show price with currency symbol before the number (₹1499.00)
- If stock = 0, output “Out of stock” instead of the number
- Output “Low stock!” in red if stock < 20
- Create a list item <li> for each product with name and price
- Show “Free shipping” message if price > 2000
Lesson 8 – Real-world context (where <xsl:value-of> is used every day)
- e-Invoice / GST → output invoice number, GSTIN, total amount
- Bank statements → format dates, amounts with currency symbol
- Product feeds → output name, price, availability
- Technical documentation → insert section titles, version numbers
- SOAP response → extract fault codes, error messages
- Report generation → insert page numbers, current date/time
Would you like to continue with one of these next?
- Difference between textContent, nodeValue, innerText
- How to output formatted numbers / dates (format-number, format-date)
- Safe handling of missing elements / attributes
- Combining multiple <xsl:value-of> with text and attributes
- Real-world patterns — invoice number + date, price + currency pair, status messages
- Debugging when <xsl:value-of> outputs nothing or wrong text
Just tell me which direction you want to go next! 😊
