What Is xsl:analyze-string in XSLT 2.0?
The <xsl:analyze-string> instruction in XSLT 2.0
provides native regular expression processing to parse, tokenize, and
transform unstructured text into structured XML markup. Prior to XSLT
2.0, string parsing required verbose, recursive named templates using
basic functions like substring-before and
substring-after. With
<xsl:analyze-string>, developers can evaluate regular
expressions against any string expression and cleanly separate matching
segments from non-matching segments to apply targeted
transformations.
Core Structure and Syntax
The instruction operates on an input string defined by the
select attribute and applies a standard regular expression
defined by the regex attribute. It contains two optional
child elements that determine how matched and unmatched substrings are
processed:
<xsl:matching-substring>: Executes its sequence constructor for every portion of the input string that matches the regular expression.<xsl:non-matching-substring>: Executes its sequence constructor for text segments between matches.
<xsl:analyze-string select="description" regex="[A-Z]{3}-\d{4}">
<xsl:matching-substring>
<product-code><xsl:value-of select="."/></product-code>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>Within both child blocks, the context item (.) evaluates
to the string representing the current matched or non-matched
fragment.
Accessing Capturing Groups with regex-group()
A major advantage of <xsl:analyze-string> over
simple regex boolean functions is the ability to extract sub-matches
using parentheses in the pattern. Inside
<xsl:matching-substring>, the
regex-group($n) function retrieves the substring captured
by the \(n\)-th parenthesized
group.
For example, when parsing dates formatted as
YYYY-MM-DD:
<xsl:analyze-string select="raw-date" regex="^(\d{4})-(\d{2})-(\d{2})$">
<xsl:matching-substring>
<date>
<year><xsl:value-of select="regex-group(1)"/></year>
<month><xsl:value-of select="regex-group(2)"/></month>
<day><xsl:value-of select="regex-group(3)"/></day>
</date>
</xsl:matching-substring>
</xsl:analyze-string>Calling regex-group(0) returns the entire matched
substring, identical to evaluating the context item ..
Regex Flags and Modifiers
The optional flags attribute allows configuration of the
regex evaluation engine using single-character flags:
s(dot-all mode): Allows the.wildcard to match any character, including newline characters (\nand\r).m(multi-line mode): Treats^and$as anchors for the start and end of individual lines rather than the entire input string.i(case-insensitive mode): Matches alphabetic characters regardless of case.x(extended mode): Ignores whitespace within the regex string, allowing patterns to be formatted with comments for readability.
Practical Applications in XML Pipelines
Converting Plain Text to Semantic Markup
When importing legacy documents or plain text blocks,
<xsl:analyze-string> can identify URLs, email
addresses, or specific code identifiers and wrap them in proper XML tags
without affecting surrounding prose.
Splitting Delimited Content
While tokenize() is suitable for splitting strings into
atomic items, <xsl:analyze-string> is essential when
the delimiter itself contains metadata or when variable delimiters
require distinct markup wrappers.
Normalizing Mixed-Format Data
In data migration scenarios where data fields contain mixed alphanumeric codes, regular expressions can separate prefix codes, sequence numbers, and suffixes into discrete XML attributes or child nodes in a single pass.