1
0
mirror of https://github.com/alexandrev/xslt-lab.git synced 2026-09-20 04:23:16 +00:00

feat(blog): XSLT/XPath function reference section (Phase 2)

- 19 reference pages under /xslt/functions/ covering:
  xsl:value-of, xsl:for-each, xsl:for-each-group, xsl:function,
  xsl:iterate, last(), position(), count(), concat(), contains(),
  substring(), sum(), key(), current(), string-join(), tokenize(),
  matches(), replace(), format-date()
- Each page: description, parameters table, return value, 2 runnable
  examples (input XML + stylesheet + output), notes, cross-links
- New Hugo section with reference-specific layout (version badges,
  syntax block, "Try in Playground" CTA, parameters table styles)
- Menu entry "Reference" → /xslt/functions/
- CSS: .ref-badge, .ref-syntax, .ref-index-list, .ref-try + table styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-04-18 14:38:55 +02:00
parent c31e3b27f8
commit b9d58ff7e0
26 changed files with 2414 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
---
title: "xsl:for-each"
description: "Iterates over a node-set or sequence, applying the contained template body to each item in document order."
date: 2026-04-18T00:00:00Z
version: "1.0"
versionLabel: "XSLT 1.0"
category: "element"
syntax: "<xsl:for-each select=\"node-set\">"
tags: ["xslt", "reference", "xslt1"]
---
## Description
`xsl:for-each` selects a set of nodes (or, in XSLT 2.0+, a sequence of items) and processes each one in turn. Within the loop body, the **context node** changes to the current item, so XPath expressions are evaluated relative to it.
It is the standard way to iterate over child elements or any repeated node structure when you do not want to use recursive template matching. The loop body can contain any sequence of XSLT instructions: output elements, `xsl:value-of`, nested `xsl:for-each` calls, conditionals, and so on.
An optional `xsl:sort` child element placed immediately inside `xsl:for-each` (before any other content) changes the processing order without altering the source document.
## Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `select` | XPath expression | Yes | Node-set or sequence to iterate over. |
### Child element: `xsl:sort`
Place one or more `xsl:sort` elements as the first children to sort the selected set before processing.
| Attribute | Description |
|-----------|-------------|
| `select` | XPath expression used as the sort key. |
| `order` | `"ascending"` (default) or `"descending"`. |
| `data-type` | `"text"` (default) or `"number"`. |
## Examples
### Iterate over child elements
**Input XML:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<item id="1"><name>Widget</name><price>9.99</price></item>
<item id="2"><name>Gadget</name><price>24.99</price></item>
<item id="3"><name>Doohickey</name><price>4.49</price></item>
</catalog>
```
**Stylesheet:**
```xml
<?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"/>
<xsl:template match="/catalog">
<ul>
<xsl:for-each select="item">
<li>
<xsl:value-of select="name"/>
<xsl:text> — $</xsl:text>
<xsl:value-of select="price"/>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
```
**Output:**
```xml
<ul>
<li>Widget — $9.99</li>
<li>Gadget — $24.99</li>
<li>Doohickey — $4.49</li>
</ul>
```
### Sorted iteration
**Stylesheet (sort by price descending):**
```xml
<?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"/>
<xsl:template match="/catalog">
<ul>
<xsl:for-each select="item">
<xsl:sort select="price" data-type="number" order="descending"/>
<li>
<xsl:value-of select="concat(name, ' — $', price)"/>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
```
**Output:**
```xml
<ul>
<li>Gadget — $24.99</li>
<li>Widget — $9.99</li>
<li>Doohickey — $4.49</li>
</ul>
```
## Notes
- `position()` and `last()` inside the loop refer to the position within the selected set, not the original document position.
- `current()` inside the loop returns the same node as `.` (the context node). It becomes useful when `current()` is called inside a predicate.
- For grouping scenarios (e.g., group items by category) prefer `xsl:for-each-group` (XSLT 2.0+) over the Muenchian method with `xsl:for-each`.
- Template rules (`xsl:apply-templates`) are generally more flexible and reusable than `xsl:for-each`; use `xsl:for-each` when the transformation logic is short and self-contained.
## See also
- [xsl:for-each-group](../xsl-for-each-group)
- [position()](../xpath-position)
- [last()](../xpath-last)