How Do xsl:try and xsl:catch Work in XSLT 3.0?
Error handling in modern XSLT workflows relies on the
<xsl:try> and <xsl:catch>
instructions introduced in XSLT 3.0 to intercept dynamic runtime
failures without halting stylesheet execution. This article examines how
these elements operate, how to filter specific error codes, how to
access diagnostic error variables, and how to implement graceful
fallbacks for fragile data transformations.
The Need for Robust Error Handling in XSLT
Prior to XSLT 3.0, dynamic errors—such as division by zero, invalid data type casting, or missing external documents—invariably caused the transformation engine to abort the entire process. Stylesheet authors often had to write complex defensive logic using conditional statements or rely on proprietary extension functions to check data validity before evaluation.
The introduction of <xsl:try> and
<xsl:catch> brings structured exception handling to
declarative XML processing, allowing stylesheets to attempt potentially
volatile operations, recover from expected edge cases, and continue
producing output.
Core Syntax and Mechanics
The <xsl:try> element encloses the sequence
constructor that might throw a dynamic error. If the evaluation
completes successfully, the resulting sequence is delivered to the
output. If an error occurs within the <xsl:try>
block, execution immediately halts, the partial results of that block
are discarded, and control transfers to the matching
<xsl:catch> branch.
<xsl:try>
<!-- Attempt a risky transformation -->
<xsl:value-of select="xs:decimal(price) * xs:integer(quantity)" />
<xsl:catch>
<!-- Provide fallback content -->
<span class="error">Invalid numeric data</span>
</xsl:catch>
</xsl:try>An <xsl:try> element must contain at least one
<xsl:catch> block. Multiple
<xsl:catch> elements can be declared sequentially to
handle different failure modes with tailored responses.
Filtering Errors
with the errors Attribute
By default, an unqualified <xsl:catch> block
catches any dynamic error. When finer control is required, the
errors attribute specifies a list of NameTests matching
error QNames:
<xsl:try>
<xsl:value-of select="unparsed-text(@href)" />
<xsl:catch errors="err:FOUT1170">
<xsl:text>Resource not found at target URI.</xsl:text>
</xsl:catch>
<xsl:catch errors="err:FOUT1190">
<xsl:text>Resource encoding cannot be decoded.</xsl:text>
</xsl:catch>
<xsl:catch errors="*">
<xsl:text>An unexpected dynamic error occurred.</xsl:text>
</xsl:catch>
</xsl:try>The processor checks <xsl:catch> blocks in the
order they appear and executes the first one matching the raised error
code.
Standard Error Variables
Within the scope of an <xsl:catch> block, XSLT 3.0
provides several implicitly declared variables in the standard error
namespace
([http://www.w3.org/2005/xqt-errors](http://www.w3.org/2005/xqt-errors),
typically bound to prefix err):
$err:code: Anxs:QNamerepresenting the specific error code.$err:description: Anxs:stringproviding a human-readable explanation of the failure.$err:value: An item or sequence containing error-specific payload data passed byfn:error().$err:module: The URI of the stylesheet module where the error originated.- **
$err:line-numberand$err:column-number**: Integers identifying the location of the failing instruction.
These variables allow detailed logging or contextual error reporting:
<xsl:catch>
<error-log code="{$err:code}" line="{$err:line-number}">
<xsl:value-of select="$err:description" />
</error-log>
</xsl:catch>Common Applications
Structured error handling is particularly valuable in modern data pipelines that handle external or loosely structured inputs:
- Parsing External Resources: Safeguarding calls to
fn:doc(),fn:unparsed-text(), orfn:json-doc()against network latency, missing files, or corrupt payloads. - Dynamic JSON Parsing: Intercepting syntax errors
when converting raw strings using
fn:parse-json(). - Data Type Casting: Converting legacy string formats
into strict XML Schema types (
xs:dateTime,xs:decimal) without crashing when non-conformant input is encountered. - Regular Expression Evaluation: Catching invalid
dynamic regex patterns compiled at runtime via
fn:matches()orfn:tokenize().
By wrapping volatile operations in <xsl:try> and
supplying defensive strategies in <xsl:catch>,
stylesheets maintain operational resilience across unpredictable input
sources.