mirror of
https://github.com/alexandrev/xslt-lab.git
synced 2026-09-16 18:23:16 +00:00
SEO phase 2: Saxon error reference (17 pages) + 2 answer-first posts
Devs search literal error messages ("XPST0017", "Content is not allowed in
prolog") with almost no competition. New /xslt/errors/ section mirrors the
function-reference pattern that already ranks:
- 17 error pages: XPST0017/0081/0008, XPTY0004, XPDY0002, XTSE0630/0010,
XTDE1490, XTMM9000, XTRE0540, FORX0002, FODC0002, FORG0001, SXXP0003 and
the three big XML parser messages — each with meaning, causes and
before/after fixes
- Pillar post "XSLT error messages explained" (triage table by error-code
prefix, links all 17)
- Post "XSLT vs DataWeave" targeting the enterprise/MuleSoft audience
- Cross-links: functions hub ↔ errors hub; FirstUpper for category headings
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgybX3QbAWVzb9ZnroCA79
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: "XSLT error messages explained: the 17 most common Saxon errors and how to fix each one"
|
||||
description: "A practical triage guide to XSLT and Saxon errors — XPST0017, XPTY0004, XPDY0002, 'Content is not allowed in prolog' and more: what each means and the fastest fix."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
tags: ["xslt", "saxon", "errors", "debugging"]
|
||||
---
|
||||
|
||||
**Quick answer:** most XSLT failures fall into three buckets. If the error code starts with **XP/XT + "S"** (XPST, XTSE) the *stylesheet itself* is invalid and nothing ran. If it starts with **XP/XT + "D"** (XPDY, XTDE) the stylesheet compiled but hit a problem *at runtime with your data*. If the message mentions the **XML parser** (SAXParseException, SXXP0003), your *input document* is not well-formed XML — the stylesheet never even got a chance. Find your exact error below.
|
||||
|
||||
## Triage: read the code before the message
|
||||
|
||||
| Prefix | Layer | Meaning |
|
||||
|---|---|---|
|
||||
| `XPST…` | XPath, static | Expression invalid — typo, unknown function/variable/prefix |
|
||||
| `XPTY…` | XPath, type | Value has wrong type or cardinality (2.0+ strictness) |
|
||||
| `XPDY…` | XPath, dynamic | Expression valid but failed on your data/context |
|
||||
| `XTSE…` | XSLT, static | Stylesheet structure invalid |
|
||||
| `XTDE…` / `XTRE…` | XSLT, dynamic | Runtime failure / recoverable condition |
|
||||
| `FO…` | Function library | A standard function rejected its input |
|
||||
| `SXXP0003` / SAXParseException | XML parser | Input is not well-formed XML |
|
||||
|
||||
## Stylesheet won't compile (static errors)
|
||||
|
||||
- **[XPST0017 — Cannot find a matching N-argument function](/xslt/errors/xpst0017/)** — unknown function or wrong arity; very often a 2.0/3.0 function running as XSLT 1.0.
|
||||
- **[XPST0081 — Namespace prefix has not been declared](/xslt/errors/xpst0081/)** — the prefix must be declared in the *stylesheet*, not just the source.
|
||||
- **[XPST0008 — Variable has not been declared](/xslt/errors/xpst0008/)** — usually a scope problem: the variable died with its enclosing block.
|
||||
- **[XTSE0630 — Variable is multiply defined](/xslt/errors/xtse0630/)** — duplicate declaration, or the same module included twice.
|
||||
- **[XTSE0010 — Element not allowed at this location](/xslt/errors/xtse0010/)** — wrong nesting: output markup at top level, xsl:otherwise before xsl:when, late xsl:param.
|
||||
|
||||
## Runs but fails on your data (dynamic & type errors)
|
||||
|
||||
- **[XPTY0004 — A sequence of more than one item is not allowed](/xslt/errors/xpty0004/)** — the #1 migration error from 1.0 to 2.0+: strict typing refuses multi-node sequences and mixed-type comparisons.
|
||||
- **[XPDY0002 — The context item is absent](/xslt/errors/xpdy0002/)** — relative paths inside xsl:function or with no source document.
|
||||
- **[XTDE1490 — Cannot write more than one result document to the same URI](/xslt/errors/xtde1490/)** — static href inside a loop; make it dynamic.
|
||||
- **[XTMM9000 — Processing terminated by xsl:message](/xslt/errors/xtmm9000/)** — an intentional assertion fired; read the message text, not the code.
|
||||
- **[XTRE0540 — Ambiguous rule match](/xslt/errors/xtre0540/)** — two templates match with equal priority; add priority or modes.
|
||||
|
||||
## Function library complaints
|
||||
|
||||
- **[FORX0002 — Invalid regular expression](/xslt/errors/forx0002/)** — XPath regex ≠ PCRE: no lookarounds, and double your braces inside xsl:analyze-string.
|
||||
- **[FODC0002 — Error retrieving resource](/xslt/errors/fodc0002/)** — doc()/document() URI resolution; guard with doc-available().
|
||||
- **[FORG0001 — Invalid value for cast](/xslt/errors/forg0001/)** — dirty data meeting xs:integer()/xs:date(); guard with castable as.
|
||||
|
||||
## Your input XML is broken (parser errors)
|
||||
|
||||
- **[SXXP0003 — Error reported by XML parser](/xslt/errors/sxxp0003/)** — Saxon's wrapper; the wrapped message is the real diagnosis.
|
||||
- **[Content is not allowed in prolog](/xslt/errors/content-not-allowed-in-prolog/)** — BOM, stray bytes, or an HTML error page fed to the parser.
|
||||
- **[The entity name must immediately follow the '&'](/xslt/errors/entity-name-must-immediately-follow/)** — a bare `&`; write `&` (only 5 named entities exist in XML).
|
||||
- **[Markup following the root element must be well-formed](/xslt/errors/markup-following-root-element/)** — two root elements; wrap the fragments.
|
||||
|
||||
## A 3-step debugging workflow
|
||||
|
||||
1. **Reproduce small.** Paste stylesheet + input into [XSLT Playground](https://xsltplayground.com/) and cut the input down to the smallest fragment that still fails — Saxon errors carry exact line numbers, so shrinking the case pinpoints the culprit.
|
||||
2. **Check the layer** with the table above: fix stylesheet, data, or input well-formedness — they need different tools.
|
||||
3. **Trace it.** For logic errors that don't raise codes at all (wrong output, empty output), enable the execution trace to see which templates fired and with what context. The [debugging patterns guide](/posts/xslt-debugging-patterns/) covers this in depth.
|
||||
|
||||
Browse the full **[XSLT & Saxon Error Reference](/xslt/errors/)** for every error above, each with before/after fixes you can run.
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: "XSLT vs DataWeave: which transformation language should integration teams use?"
|
||||
description: "An honest comparison of XSLT and MuleSoft DataWeave for XML (and JSON) transformations: portability, tooling, learning curve, performance — and when each one wins."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
tags: ["xslt", "dataweave", "mulesoft", "integration", "comparison"]
|
||||
---
|
||||
|
||||
**Quick answer:** if your transformation lives **inside MuleSoft**, use DataWeave — it is the native language, the tooling assumes it, and fighting that assumption costs more than any XSLT advantage returns. If your transformation must be **portable across platforms** (SAP PO/CPI, TIBCO, IBM, Oracle, Java services, standalone pipelines), is **XML-centric**, or must outlive your current middleware, XSLT is the safer bet: it is a W3C standard with 25 years of guaranteed behaviour and processors on every stack.
|
||||
|
||||
## What each language is
|
||||
|
||||
**XSLT** is a W3C-standard, declarative, template-driven language (1.0 → 1999, 2.0 → 2007, 3.0 → 2017) designed for XML transformation. It runs anywhere a processor exists: Java (Saxon), .NET, C, browsers, and inside virtually every enterprise middleware — SAP, TIBCO BusinessWorks, IBM Integration Bus, Oracle SOA, Software AG.
|
||||
|
||||
**DataWeave** is MuleSoft's proprietary, functional, expression-based language (2.0 since Mule 4) designed for *any-to-any* transformation — JSON, XML, CSV, Java objects — with JSON as its most natural habitat.
|
||||
|
||||
## Head-to-head
|
||||
|
||||
| Dimension | XSLT | DataWeave |
|
||||
|---|---|---|
|
||||
| Standard | W3C, vendor-neutral | Proprietary (MuleSoft/Salesforce) |
|
||||
| Runs on | Any platform with a processor | Mule runtime (plus a limited CLI) |
|
||||
| Native shape | XML documents | JSON/Java structures |
|
||||
| XML namespaces, mixed content | First-class | Supported but noticeably clumsier |
|
||||
| JSON | Good in 3.0 (maps, xml-to-json) | Excellent, native |
|
||||
| Skills market | Deep but aging pool | Growing, Mule-centric |
|
||||
| Longevity risk | Very low — 25 years of stability | Tied to the MuleSoft platform |
|
||||
|
||||
## The same transformation, side by side
|
||||
|
||||
Group orders by region and total the amounts.
|
||||
|
||||
**XSLT 2.0:**
|
||||
|
||||
```xml
|
||||
<xsl:template match="/orders">
|
||||
<totals>
|
||||
<xsl:for-each-group select="order" group-by="@region">
|
||||
<region name="{current-grouping-key()}"
|
||||
total="{sum(current-group()/@amount)}"/>
|
||||
</xsl:for-each-group>
|
||||
</totals>
|
||||
</xsl:template>
|
||||
```
|
||||
|
||||
**DataWeave 2.0:**
|
||||
|
||||
```
|
||||
%dw 2.0
|
||||
output application/xml
|
||||
---
|
||||
totals: {
|
||||
(payload.orders.*order groupBy $.@region mapObject (orders, region) -> {
|
||||
region @(name: region, total: sum(orders.@amount)): null
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Both are compact. Notice the asymmetry, though: producing *XML attributes and nested elements* is where DataWeave needs its most awkward syntax (`@(...)`, `mapObject`), while XSLT emits them naturally — and the reverse is true for deeply JSON-shaped output.
|
||||
|
||||
## When XSLT wins
|
||||
|
||||
- **Cross-platform mandates.** The same stylesheet runs in SAP, TIBCO, IBM, a Java microservice or a batch pipeline. No rewrite when the middleware changes — this is the big one for enterprises that migrate platforms every 5–8 years.
|
||||
- **XML-heavy domains**: SOAP services, industry standards (HL7, UBL, FpML, ISO 20022), document publishing, mixed content.
|
||||
- **Complex recursive structures** — template matching handles recursion declaratively where DataWeave needs explicit recursive functions.
|
||||
- **Auditability**: XSLT 1.0/2.0 behaviour is frozen by spec; transformations written in 2005 still run bit-identical today.
|
||||
|
||||
## When DataWeave wins
|
||||
|
||||
- **You are on MuleSoft.** Full stop — connectors, error handling, streaming and IDE support all assume DataWeave.
|
||||
- **JSON-first APIs** with occasional XML at the edges.
|
||||
- **Any-to-any mapping** (CSV → JSON → Java) in one language.
|
||||
- Your team already lives in Anypoint Studio and has no XSLT background.
|
||||
|
||||
## Can they coexist?
|
||||
|
||||
Yes, and mature integration estates do exactly that: DataWeave for Mule-internal flows, XSLT for the canonical, platform-neutral transformations shared across systems. Mule can invoke XSLT via the XML module when a shared stylesheet is the source of truth.
|
||||
|
||||
## Try the XSLT side in 30 seconds
|
||||
|
||||
You don't need a platform install to evaluate XSLT: paste the grouping example above into [XSLT Playground](https://xsltplayground.com/) — a free online editor running real Saxon (XSLT 1.0/2.0/3.0), with multiple inputs, parameters and an execution trace. The [function reference](https://blog.xsltplayground.com/xslt/functions/) covers everything available in each version.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "XSLT & Saxon Error Reference"
|
||||
description: "Common XSLT and Saxon error codes and XML parser messages explained: what each error means, typical causes, and how to fix it — with examples."
|
||||
---
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: "Content is not allowed in prolog"
|
||||
errorMessage: "org.xml.sax.SAXParseException: Content is not allowed in prolog"
|
||||
description: "The XML parser found characters before the XML declaration or root element: usually a UTF-8 BOM, stray whitespace/text, or a file that is not XML at all (an HTML error page, for instance)."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XML parsing error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "xml", "java"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
The *prolog* is everything before the root element. Only the XML declaration, comments, processing instructions and whitespace may appear there. Any other content — even a single invisible byte — triggers this error.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **UTF-8 BOM (byte order mark).** Files saved as "UTF-8 with BOM" start with the bytes `EF BB BF`. Many Java parsers reject them when the document is served or concatenated carelessly. Save as UTF-8 *without* BOM.
|
||||
2. **Stray text before `<?xml`** — a leftover log line, a shell prompt, an HTML comment from a template engine.
|
||||
3. **The file is not XML at all.** Classic case: your code fetched a URL and got an HTML **error page** (login redirect, 404, proxy error) and then fed it to the XML parser. The parser dies at character 1 of `<!DOCTYPE html>`… or earlier.
|
||||
4. **Encoding mismatch** — the declaration says `encoding="UTF-8"` but the bytes are UTF-16, so the first bytes are unreadable.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Inspect the first bytes with a hex viewer (`xxd file.xml | head -1`) — a BOM shows as `efbb bf`.
|
||||
- If the XML comes over HTTP, log the raw response before parsing: is it actually XML?
|
||||
- Re-save the file as UTF-8 without BOM and make sure nothing writes to the stream before the XML declaration.
|
||||
- Paste the content into [XSLT Playground](https://xsltplayground.com/) — invisible junk becomes obvious when the parser points at line 1, column 1.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "The entity name must immediately follow the '&'"
|
||||
errorMessage: "org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference."
|
||||
description: "A raw ampersand appears in the XML. In XML, & always starts an entity reference — literal ampersands must be written as &, and only 5 named entities exist."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XML parsing error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "xml"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
In XML, `&` **always** begins an entity reference like `&` or ` `. A bare `&` followed by a space, `=` or anything that is not a valid entity name breaks parsing immediately.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **URLs with query strings** — `<link>https://x.com/?a=1&b=2</link>`. The `&b` is read as the start of an entity.
|
||||
2. **Company names and free text** — `<name>Johnson & Johnson</name>`.
|
||||
3. **HTML named entities that XML does not define.** XML predefines only **five**: `&` `<` `>` `'` `"`. Anything else (` `, `é`, `©`…) is an error unless declared in a DTD.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Escape literal ampersands: `a=1&b=2`, `Johnson & Johnson`.
|
||||
- Replace HTML entities with numeric character references: ` ` → ` `, `©` → `©`, `é` → `é`.
|
||||
- For blocks full of special characters, wrap them in CDATA: `<![CDATA[a=1&b=2 <raw>]]>`.
|
||||
- Remember the fix belongs in the **producer** of the XML: whatever generated the file failed to escape output. Verify the corrected input in [XSLT Playground](https://xsltplayground.com/).
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "FODC0002"
|
||||
errorMessage: "Error retrieving resource / I/O error reported by XML parser processing file:/…"
|
||||
description: "doc() or document() could not load the requested document: wrong relative URI, missing file, or an environment (like an online tool) with no filesystem access."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "function error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
A call to `doc()`, `document()` or `unparsed-text()` failed to retrieve the resource — the URI did not resolve, the file does not exist, or its content is not well-formed XML.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Relative URI resolved against the wrong base.** `document('lookup.xml')` resolves relative to the **stylesheet** location (for `doc()` in some contexts, the static base URI) — not your shell's working directory.
|
||||
2. **The file simply is not there** (typo, wrong folder, not deployed with the stylesheet).
|
||||
3. **Sandboxed environments.** Online tools have no access to your local filesystem — `doc('file:/C:/data.xml')` cannot work in a browser-based tester.
|
||||
4. **The resource exists but is not well-formed XML** — the parse failure surfaces as a retrieval error.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Guard the lookup with `doc-available()` before calling `doc()`.
|
||||
- Verify the base URI with `base-uri(/)` and `static-base-uri()` — print them with `xsl:message`.
|
||||
- In [XSLT Playground](https://xsltplayground.com/), don't use `doc()` for secondary inputs: pass extra documents as **named parameters** in the Input panel instead — see [working with parameters and multiple inputs](https://blog.xsltplayground.com/posts/xslt-parameters-and-multiple-inputs/).
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: "FORG0001"
|
||||
errorMessage: "Invalid value for cast/constructor: xs:integer(\"abc\")"
|
||||
description: "A cast or constructor function received a value it cannot convert — casting text to a number or date is the usual suspect. Guard with 'castable as' or use number()."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "function error"
|
||||
versionLabel: "XSLT 2.0+"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "types", "xslt2"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
A constructor like `xs:integer(...)`, `xs:date(...)` or an implicit cast received a lexical value that is not valid for the target type: `xs:integer('abc')`, `xs:date('2026-13-45')`, or an empty string.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Dirty or empty data** — casting `@qty` when some elements have `qty=""`.
|
||||
2. **Format mismatch** — `xs:date('02/07/2026')`: XSD dates must be `2026-07-02`.
|
||||
3. **Locale-style numbers** — `xs:decimal('1.234,56')` fails; XSD uses `.` as decimal separator only.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Guard the cast:
|
||||
|
||||
```xml
|
||||
<xsl:value-of select="if (@qty castable as xs:integer)
|
||||
then xs:integer(@qty) else 0"/>
|
||||
```
|
||||
|
||||
- Or use `number()` when NaN is acceptable: `number('abc')` returns `NaN` instead of raising an error — handy for optional numeric fields.
|
||||
- Normalize the lexical form first (`translate()`, `replace()`, [format-date patterns](/xslt/functions/)) before casting dates and decimals.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: "FORX0002"
|
||||
errorMessage: "Invalid regular expression / Error at character N in regular expression"
|
||||
description: "The pattern given to matches(), replace(), tokenize() or xsl:analyze-string is not a valid XPath regular expression — watch out for curly braces in attributes and unsupported constructs."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "function error"
|
||||
versionLabel: "XSLT 2.0+"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "regex", "xslt2"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
XPath regular expressions are based on XML Schema regex with a few additions — they are **not** PCRE/JavaScript regex. FORX0002 means the pattern itself failed to parse.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Curly braces inside `xsl:analyze-string`'s `regex` attribute.** That attribute is an *attribute value template*, so `{` and `}` are AVT delimiters and must be doubled:
|
||||
|
||||
```xml
|
||||
<!-- Before: FORX0002 — { interpreted as AVT -->
|
||||
<xsl:analyze-string select="." regex="\d{3}">
|
||||
|
||||
<!-- After: double the braces -->
|
||||
<xsl:analyze-string select="." regex="\d{{3}}">
|
||||
```
|
||||
|
||||
2. **Unsupported constructs.** XPath regex has no lookahead/lookbehind (`(?=`, `(?<=`), no backreferences in `matches()` patterns' character classes, no `\b` word boundary. Rework the pattern (often with `tokenize()` + predicates).
|
||||
3. **A lone `\` or trailing escape** — `replace($s, '\', '/')` is invalid; escape it: `'\\'`.
|
||||
4. **Invalid flags** — only `s`, `m`, `i`, `x` (and `q` in 3.0) are allowed.
|
||||
|
||||
## How to fix it
|
||||
|
||||
Test the expression interactively: paste a minimal `matches()` call in [XSLT Playground](https://xsltplayground.com/) and iterate until the pattern parses. See [replace()](/xslt/functions/xpath-replace/), [tokenize()](/xslt/functions/xpath-tokenize/) and [matches()](/xslt/functions/xpath-matches/) for the supported syntax.
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "Markup in the document following the root element must be well-formed"
|
||||
errorMessage: "org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed."
|
||||
description: "There is content after the closing tag of the root element — usually two XML documents concatenated, or a fragment list without a wrapper element."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XML parsing error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "xml"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
An XML document has exactly **one** root element. Once the parser sees the root close, only comments, PIs and whitespace may follow. Any further element or text raises this error.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Concatenated documents.** Log pipelines and batch exports often append documents into one file:
|
||||
|
||||
```xml
|
||||
<order id="1">…</order>
|
||||
<order id="2">…</order> <!-- error: second root -->
|
||||
```
|
||||
|
||||
2. **A fragment list** returned by an API or built by string concatenation, with no enclosing element.
|
||||
3. **Leftover text/markup** after the root when hand-editing a file.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Wrap the fragments in a single container element:
|
||||
|
||||
```xml
|
||||
<orders>
|
||||
<order id="1">…</order>
|
||||
<order id="2">…</order>
|
||||
</orders>
|
||||
```
|
||||
|
||||
- If you cannot change the producer, wrap at read time (`concat('<wrap>', $raw, '</wrap>')` before parsing with `parse-xml()` in XSLT 3.0, or wrap in your ingestion code).
|
||||
- In [XSLT Playground](https://xsltplayground.com/), paste the wrapped version and your stylesheet can iterate `wrap/order` normally.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "SXXP0003"
|
||||
errorMessage: "Error reported by XML parser: <underlying message>"
|
||||
description: "A Saxon wrapper code: the source document failed to parse as XML. The real diagnosis is in the underlying parser message that follows the code."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XML parsing error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "xml"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
SXXP0003 is Saxon-specific and simply means: **your input XML is not well-formed**. The interesting part is the parser message wrapped inside — that tells you what is actually broken and at which line/column.
|
||||
|
||||
## The usual wrapped messages
|
||||
|
||||
| Wrapped parser message | Meaning |
|
||||
|---|---|
|
||||
| [Content is not allowed in prolog](/xslt/errors/content-not-allowed-in-prolog/) | Junk (BOM, text, whitespace) before `<?xml … ?>` or the root element |
|
||||
| [The entity name must immediately follow the '&'](/xslt/errors/entity-name-must-immediately-follow/) | A bare `&` — should be `&` |
|
||||
| [Markup following the root element must be well-formed](/xslt/errors/markup-following-root-element/) | More than one root element |
|
||||
| The element type "X" must be terminated by "</X>" | Unclosed or mis-nested tag |
|
||||
| Open quote is expected for attribute | Attribute value missing quotes |
|
||||
|
||||
## How to fix it
|
||||
|
||||
1. Read the **line:column** in the message and inspect that exact spot in the input.
|
||||
2. Fix the well-formedness issue in the source (it is a data problem, not a stylesheet problem).
|
||||
3. Validate quickly by pasting the XML into [XSLT Playground](https://xsltplayground.com/) with an identity transform — the parser flags the precise position of the first problem.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "XPDY0002"
|
||||
errorMessage: "The context item for axis step ./foo is absent"
|
||||
description: "An expression uses a relative path (./foo, foo/bar) in a place where there is no context node — typically inside xsl:function or a stylesheet-level variable."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XPath dynamic error"
|
||||
versionLabel: "XSLT 2.0+"
|
||||
tags: ["xslt", "reference", "errors", "saxon"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
Relative XPath expressions need a **context item** ("where am I?"). In some places — notably inside `xsl:function` bodies — no context item exists, so any relative path fails at runtime with XPDY0002.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Relative paths inside `xsl:function`.** Functions are called with arguments only; they have no context node.
|
||||
2. **Global `xsl:variable` using a relative path** when the processor is invoked without a source document (e.g. starting at a named template with `xsl:initial-template`).
|
||||
3. **Calling a named template that assumes a context** established elsewhere.
|
||||
|
||||
## How to fix it
|
||||
|
||||
Pass the nodes you need as parameters instead of relying on context:
|
||||
|
||||
```xml
|
||||
<!-- Before: XPDY0002 — ./price has no context inside the function -->
|
||||
<xsl:function name="my:total">
|
||||
<xsl:sequence select="sum(./item/price)"/>
|
||||
</xsl:function>
|
||||
|
||||
<!-- After: receive the nodes explicitly -->
|
||||
<xsl:function name="my:total">
|
||||
<xsl:param name="order" as="element()"/>
|
||||
<xsl:sequence select="sum($order/item/price)"/>
|
||||
</xsl:function>
|
||||
```
|
||||
|
||||
If you run a stylesheet with no source document, make global variables absolute or lazy — or supply an input document. In [XSLT Playground](https://xsltplayground.com/) add the XML input in the Input panel so the context item exists.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: "XPST0008"
|
||||
errorMessage: "Variable $x has not been declared (or its declaration is not in scope)"
|
||||
description: "An XPath expression references a variable that does not exist at that point: a typo, or a variable declared inside a block and used outside its scope."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XPath static error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "variables"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
The expression uses `$x` but no `xsl:variable` or `xsl:param` named `x` is **visible from that point**. In XSLT, a variable's scope is its parent element, from the point of declaration onward.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Scope confusion — the #1 cause.** A variable declared inside `xsl:if`, `xsl:when` or `xsl:for-each` disappears when that element ends:
|
||||
|
||||
```xml
|
||||
<!-- Before: $discount is out of scope at the value-of -->
|
||||
<xsl:if test="@vip = 'true'">
|
||||
<xsl:variable name="discount" select="0.2"/>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="$discount"/> <!-- XPST0008 -->
|
||||
|
||||
<!-- After: declare the variable once, decide the value inside it -->
|
||||
<xsl:variable name="discount"
|
||||
select="if (@vip = 'true') then 0.2 else 0"/>
|
||||
<xsl:value-of select="$discount"/>
|
||||
```
|
||||
|
||||
2. **Typo** in the variable name (`$totlaPrice`).
|
||||
3. **Template parameters not declared.** Using `$foo` in a template that never declares `<xsl:param name="foo"/>` — declare the param even if the caller sends it with `xsl:with-param`.
|
||||
|
||||
## How to fix it
|
||||
|
||||
Move the declaration up to a scope that encloses every use, or compute conditional values *inside* the variable (as above). Remember stylesheet-level (global) variables are visible everywhere.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "XPST0017"
|
||||
errorMessage: "Cannot find a matching 2-argument function named {namespace}name()"
|
||||
description: "Saxon cannot resolve a function call: the function name is unknown, the number of arguments is wrong, or the function belongs to a newer XSLT/XPath version than the one you selected."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XPath static error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
The processor found a function call it cannot match against any known function — either the name does not exist, or no version of that function accepts the number of arguments you passed (the *arity*).
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **The function belongs to a newer XSLT version.** Calling `tokenize()`, `replace()`, `matches()` or `current-group()` while running as **XSLT 1.0** fails — they were introduced in 2.0. Calling `xml-to-json()` or map/array functions under 2.0 fails — they are 3.0.
|
||||
2. **Wrong number of arguments.** `substring-after('a')` raises XPST0017 because `substring-after()` needs 2 arguments.
|
||||
3. **Typo in the function name.** `string-lenght()` instead of `string-length()`.
|
||||
4. **Missing namespace for user/extension functions.** A function defined with `<xsl:function name="my:double">` can only be called if the prefix `my` is bound to the same namespace URI at the call site.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Check the required version in the [function reference](/xslt/functions/) and switch the processor version accordingly — in [XSLT Playground](https://xsltplayground.com/) use the version dropdown (1.0 / 2.0 / 3.0).
|
||||
- Verify the arity: the message tells you how many arguments you passed (`a matching 2-argument function`).
|
||||
- For user-defined functions, make sure the prefix is declared:
|
||||
|
||||
```xml
|
||||
<xsl:stylesheet version="2.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:my="urn:my-functions">
|
||||
<xsl:function name="my:double">
|
||||
<xsl:param name="n"/>
|
||||
<xsl:sequence select="$n * 2"/>
|
||||
</xsl:function>
|
||||
<xsl:template match="/">
|
||||
<out><xsl:value-of select="my:double(21)"/></out>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "XPST0081"
|
||||
errorMessage: "Namespace prefix 'x' has not been declared"
|
||||
description: "An XPath expression uses a namespace prefix that is not declared in the stylesheet. Declaring the prefix on xsl:stylesheet fixes it."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XPath static error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "namespaces"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
An XPath expression (in `select`, `match`, `test`…) uses a prefix like `soap:` or `ns0:` that the stylesheet never binds to a namespace URI. Prefixes are resolved **in the stylesheet**, not in the source document — it does not matter that the input XML declares them.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **The prefix is only declared in the source XML.** The stylesheet needs its own `xmlns:soap="…"` declaration even if the input already has one.
|
||||
2. **Typo or renamed prefix** — `select="soapenv:Body"` while the stylesheet declares `xmlns:soap`.
|
||||
3. **Copy-pasted XPath from another stylesheet** that declared different prefixes.
|
||||
|
||||
## How to fix it
|
||||
|
||||
Declare the prefix on the root element of the stylesheet with the **same URI** used in the source document (the prefix text itself may differ; the URI is what matters):
|
||||
|
||||
```xml
|
||||
<xsl:stylesheet version="2.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<xsl:template match="/soap:Envelope/soap:Body">
|
||||
…
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
```
|
||||
|
||||
For elements in a **default namespace** (no prefix in the source), you still need a prefix in XPath 1.0/2.0 — bind any prefix to that URI and use it (`xmlns:d="urn:default-ns"` → `d:root/d:item`). In XSLT 3.0 you can use `xpath-default-namespace="urn:default-ns"` instead.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: "XPTY0004"
|
||||
errorMessage: "A sequence of more than one item is not allowed as the first argument of fn:string() / Cannot compare xs:string to xs:integer"
|
||||
description: "A type error: an expression returned a sequence or type that does not match what the function, operator or comparison expects. The strict type rules of XPath 2.0+ are usually behind it."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XPath type error"
|
||||
versionLabel: "XSLT 2.0+"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "xslt2"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
XPath 2.0 and 3.0 are strongly typed. XPTY0004 fires when a value's type or cardinality (how many items) does not match what the context requires — situations XSLT 1.0 silently tolerated by taking the first node or coercing values.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **A path selects multiple nodes where one is expected.** `string(//item)` fails if there are two `<item>` elements. XSLT 1.0 silently used the first one; 2.0+ refuses.
|
||||
2. **Comparing different atomic types.** `@id = 42` fails when `@id` is untyped in some contexts, or `'5' > 3` — a string cannot be compared with a number.
|
||||
3. **Passing a node where an atomic value is required** (or vice versa) to a typed `xsl:param`/`xsl:function`.
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Select exactly one item: `string(//item[1])`, or process all of them with `for-each`/`string-join()`:
|
||||
|
||||
```xml
|
||||
<!-- Before (XPTY0004 if several items) -->
|
||||
<xsl:value-of select="string(//item)"/>
|
||||
|
||||
<!-- After -->
|
||||
<xsl:value-of select="string-join(//item, ', ')"/>
|
||||
```
|
||||
|
||||
- Make comparisons type-consistent: `number(@qty) > 3`, or cast explicitly with `xs:integer(@qty)`.
|
||||
- When migrating 1.0 stylesheets, run them under 2.0 in [XSLT Playground](https://xsltplayground.com/) — the exact line number in the error tells you which expression needs attention.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "XTDE1490"
|
||||
errorMessage: "Cannot write more than one result document to the same URI"
|
||||
description: "Two xsl:result-document instructions resolved to the same output URI — usually a static href inside a loop. Make the href dynamic."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XSLT dynamic error"
|
||||
versionLabel: "XSLT 2.0+"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "xslt2"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
`xsl:result-document` writes an output file per invocation. If two invocations produce the same `href`, the second would overwrite the first — the spec forbids it and Saxon raises XTDE1490.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Static `href` inside `xsl:for-each`** — every iteration writes to the same name:
|
||||
|
||||
```xml
|
||||
<!-- Before: every customer writes to out.xml → XTDE1490 -->
|
||||
<xsl:for-each select="customer">
|
||||
<xsl:result-document href="out.xml">…</xsl:result-document>
|
||||
</xsl:for-each>
|
||||
|
||||
<!-- After: unique URI per iteration -->
|
||||
<xsl:for-each select="customer">
|
||||
<xsl:result-document href="customer-{@id}.xml">…</xsl:result-document>
|
||||
</xsl:for-each>
|
||||
```
|
||||
|
||||
2. **Duplicate keys in the data** — `href="{@id}.xml"` with two equal `@id` values. Deduplicate first (`xsl:for-each-group group-by="@id"`).
|
||||
3. **Writing to the principal output URI** while also producing normal output.
|
||||
|
||||
## How to fix it
|
||||
|
||||
Build the `href` from something guaranteed unique: a key from the data, `position()`, or `generate-id()`. See [xsl:result-document](/xslt/functions/xsl-result-document/) for the full syntax and a runnable example.
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: "XTMM9000"
|
||||
errorMessage: "Processing terminated by xsl:message at line NN"
|
||||
description: "Not a processor bug: an xsl:message with terminate=\"yes\" fired. The stylesheet stopped itself — read the message text to see why."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XSLT dynamic error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "debugging"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
Someone (possibly you, possibly the author of an imported stylesheet) wrote an assertion:
|
||||
|
||||
```xml
|
||||
<xsl:if test="not(order/@id)">
|
||||
<xsl:message terminate="yes">Order without id — aborting.</xsl:message>
|
||||
</xsl:if>
|
||||
```
|
||||
|
||||
When the condition fires, the transformation stops and Saxon reports XTMM9000 with the line number of the `xsl:message`. **The error code is generic — the real information is the message text printed just before it.**
|
||||
|
||||
## How to fix it
|
||||
|
||||
1. Read the message content: it usually states the violated expectation (missing element, unexpected value, unsupported input variant).
|
||||
2. Fix the **input data** if the assertion is legitimate, or
|
||||
3. Fix the **assertion** if the input is actually valid and the check is too strict.
|
||||
4. To keep the warning but continue processing, change to `terminate="no"` (the default) — the message still prints but the transform completes.
|
||||
|
||||
In [XSLT Playground](https://xsltplayground.com/) the message text appears in the error panel, so you can iterate on input or stylesheet until the assertion passes.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: "XTRE0540"
|
||||
errorMessage: "Ambiguous rule match for /root/item[1]"
|
||||
description: "Two or more templates match the same node with equal priority. Saxon warns (or errors in strict mode) and picks the last one declared — make the intent explicit."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XSLT recoverable error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "templates"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
During `xsl:apply-templates`, a node matched **two templates with the same import precedence and priority**. The spec calls this a *recoverable* error: processors may pick the template that appears **last** in the stylesheet and continue — Saxon does that and prints XTRE0540 as a warning by default.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Overlapping patterns with equal default priority** — e.g. `match="item"` in two included files.
|
||||
2. **Copy-pasted templates** left behind after refactoring.
|
||||
3. **A generic and a specific pattern that compute the same priority** — default priorities are subtle (`item` = 0, `ns:item` = 0, `*` = −0.5, patterns with predicates = 0.5).
|
||||
|
||||
## How to fix it
|
||||
|
||||
Make the choice explicit instead of relying on declaration order:
|
||||
|
||||
- Add an explicit **`priority`**: `<xsl:template match="item" priority="2">`.
|
||||
- Use **modes** to separate concerns: `<xsl:template match="item" mode="summary">`.
|
||||
- Delete the leftover duplicate if it is dead code.
|
||||
- To *find* which templates collide, run with tracing in [XSLT Playground](https://xsltplayground.com/) — the trace shows which template fired for each node. See also [template matching explained](https://blog.xsltplayground.com/posts/xslt-template-matching-explained/).
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "XTSE0010"
|
||||
errorMessage: "Element xsl:otherwise is not allowed at this location / xsl:X must not appear directly within xsl:Y"
|
||||
description: "An XSLT element appears somewhere the language grammar does not allow: wrong nesting, wrong order, or content at the stylesheet top level that must live inside a template."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XSLT static error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
The stylesheet is well-formed XML, but an element sits in a position the XSLT grammar forbids. Saxon names the offending element and its location.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Output markup at the top level.** Literal result elements (your `<html>`, `<result>`…) must be inside an `xsl:template`, never directly under `xsl:stylesheet`.
|
||||
2. **Wrong order inside `xsl:choose`** — every `xsl:when` must come before `xsl:otherwise`; nothing else is allowed inside `xsl:choose`.
|
||||
3. **`xsl:param` after other content.** In a template, all `xsl:param` declarations must be first.
|
||||
4. **`xsl:import` not first.** `xsl:import` must precede every other declaration in the stylesheet.
|
||||
5. **Instructions used as declarations** — e.g. `xsl:value-of` directly under `xsl:stylesheet`.
|
||||
|
||||
## How to fix it
|
||||
|
||||
The message is specific — it tells you which element and where. Typical corrections:
|
||||
|
||||
```xml
|
||||
<!-- Before: literal element at top level → XTSE0010 -->
|
||||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<result/>
|
||||
</xsl:stylesheet>
|
||||
|
||||
<!-- After: wrap it in a template -->
|
||||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:template match="/">
|
||||
<result/>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: "XTSE0630"
|
||||
errorMessage: "Duplicate global variable declaration / Variable 'x' is multiply defined in the same scope"
|
||||
description: "Two xsl:variable or xsl:param declarations with the same name exist at the same level — often caused by a stylesheet being included twice."
|
||||
date: 2026-07-02T00:00:00Z
|
||||
category: "XSLT static error"
|
||||
versionLabel: "All versions"
|
||||
tags: ["xslt", "reference", "errors", "saxon", "variables"]
|
||||
---
|
||||
|
||||
## What it means
|
||||
|
||||
The stylesheet declares the same variable or parameter name twice at the same scope level with the same import precedence. The processor cannot decide which one wins, so compilation stops.
|
||||
|
||||
## Common causes
|
||||
|
||||
1. **Literal duplicate** — two `<xsl:param name="input"/>` or `<xsl:variable name="config"/>` at the top level, often after copy-pasting a block.
|
||||
2. **The same file included twice.** `xsl:include` pulls declarations in verbatim; if A includes B and C, and B also includes C, every global in C is declared twice. This is the sneaky version — each file looks correct on its own.
|
||||
3. **Local duplicate in the same template** — two `xsl:variable` with the same name as siblings (re-assignment does not exist in XSLT; variables are immutable).
|
||||
|
||||
## How to fix it
|
||||
|
||||
- Remove or rename one of the duplicates. If you were trying to *update* a variable: XSLT variables cannot be reassigned — compute the final value in one declaration, or use `xsl:iterate`/recursion for running state.
|
||||
- For diamond includes, switch to **`xsl:import`** (imported declarations get lower precedence, so an override is legal) or restructure so each module is included exactly once.
|
||||
- The error message includes the line number of the *second* declaration — start there.
|
||||
@@ -0,0 +1,30 @@
|
||||
{{ define "title" }}XSLT & Saxon Error Reference — common errors explained with fixes | {{ .Site.Title }}{{ end }}
|
||||
{{ define "main" }}
|
||||
<div class="page-header">
|
||||
<h1>XSLT & Saxon Error Reference</h1>
|
||||
<p class="lead">The most common XSLT and Saxon error codes and parser messages, explained in plain English: what each error means, what typically causes it, and how to fix it — with before/after examples you can verify in the <a href="https://xsltplayground.com/">online XSLT editor</a>.</p>
|
||||
</div>
|
||||
|
||||
<div class="content ref-intro">
|
||||
<p>Saxon error codes follow the W3C convention: <strong>XPST</strong> (XPath static), <strong>XPDY</strong> (XPath dynamic), <strong>XPTY</strong> (XPath type), <strong>XTSE</strong> (XSLT static), <strong>XTDE</strong> (XSLT dynamic), <strong>FO*</strong> (function library). Parser messages such as <em>"Content is not allowed in prolog"</em> come from the underlying XML parser and mean the input is not well-formed XML. Also see the <a href="/xslt/functions/">XSLT & XPath function reference</a>.</p>
|
||||
</div>
|
||||
|
||||
{{ $cats := slice }}
|
||||
{{ range .Pages }}{{ with .Params.category }}{{ $cats = $cats | append . }}{{ end }}{{ end }}
|
||||
{{ $cats = uniq $cats | sort }}
|
||||
|
||||
{{ range $cat := $cats }}
|
||||
<section class="ref-section" id="{{ $cat | urlize }}">
|
||||
<h2>{{ strings.FirstUpper $cat }}s</h2>
|
||||
<ul class="ref-index-list">
|
||||
{{ range where $.Pages "Params.category" $cat }}
|
||||
<li>
|
||||
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
{{ with .Params.versionLabel }}<span class="ref-badge ref-badge--sm">{{ . }}</span>{{ end }}
|
||||
<span class="muted">{{ .Description | truncate 90 }}</span>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,32 @@
|
||||
{{ define "title" }}{{ .Title }} — XSLT error: causes & fixes | {{ .Site.Title }}{{ end }}
|
||||
{{ define "main" }}
|
||||
<article class="post ref-page">
|
||||
<p class="eyebrow">XSLT Error Reference</p>
|
||||
<h1>{{ .Title }}</h1>
|
||||
<div class="ref-meta">
|
||||
{{ with .Params.versionLabel }}<span class="ref-badge">{{ . }}</span>{{ end }}
|
||||
{{ with .Params.category }}<span class="ref-badge ref-badge--cat">{{ . }}</span>{{ end }}
|
||||
</div>
|
||||
{{ with .Params.errorMessage }}
|
||||
<div class="ref-syntax">
|
||||
<span class="ref-syntax-label">Error message</span>
|
||||
<pre><code>{{ . }}</code></pre>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with .Description }}<p class="lead">{{ . }}</p>{{ end }}
|
||||
{{ partial "adsense/in-article.html" . }}
|
||||
<div class="content">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{- if and .Site.Params.ethicalads.publisher (ne hugo.Environment "development") -}}
|
||||
<div class="ad">
|
||||
<div class="ethical-ad" data-ea-publisher="{{ .Site.Params.ethicalads.publisher }}" data-ea-type="text"></div>
|
||||
</div>
|
||||
{{- end }}
|
||||
<div class="ref-try">
|
||||
<a href="https://xsltplayground.com/" class="button" target="_blank" rel="noopener noreferrer">Reproduce & fix it in XSLT Playground →</a>
|
||||
</div>
|
||||
<p class="muted back-link"><a href="{{ .CurrentSection.RelPermalink }}">← Back to XSLT Error Reference</a></p>
|
||||
{{ partial "related-posts.html" . }}
|
||||
</article>
|
||||
{{ end }}
|
||||
@@ -15,12 +15,12 @@
|
||||
<strong>Jump to:</strong>
|
||||
<a href="#xslt-elements">XSLT Elements ({{ len $elements }})</a>
|
||||
{{ range $cats }}
|
||||
<a href="#{{ . | urlize }}">{{ humanize . }}s ({{ len (where $functions "Params.category" .) }})</a>
|
||||
<a href="#{{ . | urlize }}">{{ strings.FirstUpper . }}s ({{ len (where $functions "Params.category" .) }})</a>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<div class="content ref-intro">
|
||||
<p>Looking for how a specific XSLT instruction or XPath function works? This reference covers the <strong>string, numeric, boolean, date, node, sequence, map, array, JSON and higher-order functions</strong> available in each XSLT version, plus every <strong>XSLT element</strong> from <code>xsl:template</code> to <code>xsl:accumulator</code>. Entries marked <em>XSLT 2.0</em> or <em>XSLT 3.0</em> require a processor such as Saxon — exactly what <a href="https://xsltplayground.com/">XSLT Playground</a> runs, so you can verify behaviour before shipping.</p>
|
||||
<p>Looking for how a specific XSLT instruction or XPath function works? This reference covers the <strong>string, numeric, boolean, date, node, sequence, map, array, JSON and higher-order functions</strong> available in each XSLT version, plus every <strong>XSLT element</strong> from <code>xsl:template</code> to <code>xsl:accumulator</code>. Entries marked <em>XSLT 2.0</em> or <em>XSLT 3.0</em> require a processor such as Saxon — exactly what <a href="https://xsltplayground.com/">XSLT Playground</a> runs, so you can verify behaviour before shipping. Hitting an error code instead? See the <a href="/xslt/errors/">XSLT & Saxon error reference</a>.</p>
|
||||
</div>
|
||||
|
||||
{{ if $elements }}
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
{{ range $cat := $cats }}
|
||||
<section class="ref-section" id="{{ $cat | urlize }}">
|
||||
<h2>{{ humanize $cat }}s</h2>
|
||||
<h2>{{ strings.FirstUpper $cat }}s</h2>
|
||||
<ul class="ref-index-list">
|
||||
{{ range where $functions "Params.category" $cat }}
|
||||
<li>
|
||||
|
||||
Reference in New Issue
Block a user