How Does XSLT Handle Whitespace Stripping?
In XSLT processing, whitespace handling directly affects the
structure of the input document's tree before templates are applied. The
<xsl:strip-space> and
<xsl:preserve-space> top-level elements control
whether text nodes consisting purely of whitespace characters—such as
spaces, tabs, line feeds, and carriage returns—are retained or stripped
from selected elements in the source document. Managing these nodes is
essential for cleaning up formatting artifacts, ensuring accurate node
indexing, and preventing unwanted whitespace from leaking into output
transformations.
The Default Whitespace Behavior
By default, an XSLT processor preserves all whitespace-only text nodes present in the source XML document unless explicitly instructed otherwise. In standard processing rules:
- All element names effectively default to being preserved,
functioning as if
<xsl:preserve-space elements="*"/>is implicitly declared. - XML parsers construct text nodes for indentation and newlines between child tags.
- Mixed-content elements (elements containing both text and child elements) retain their inline whitespace regardless of stripping rules.
Because an XSLT processor considers whitespace-only text nodes as
full child nodes in the XPath data model, leaving them intact affects
functions like count(*), position(), and axis
navigation like following-sibling::node().
Using
<xsl:strip-space>
The <xsl:strip-space> element instructs the XSLT
processor to remove whitespace-only text nodes from the specified
elements before any template matching occurs.
<xsl:strip-space elements="catalog book author"/>Key aspects of whitespace stripping:
- Targeted Elements: The
elementsattribute accepts a whitespace-separated list of NameTests, such as specific element names, wildcards (*), or qualified names with namespaces. - Whitespace-Only Nodes Only: It removes text nodes that consist entirely of whitespace characters (U+0020, U+0009, U+000D, U+000A). If a text node contains even a single non-whitespace character, it is entirely preserved.
- Tree Modification: The removal occurs during tree construction. Stripped nodes do not exist in the source tree viewed by subsequent XPath expressions and template rules.
Using
<xsl:preserve-space>
The <xsl:preserve-space> element explicitly
specifies which elements must retain their whitespace-only text nodes.
This is primarily used to override broader stripping rules.
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="code pre formatted-text"/>In this pattern, all elements across the source document have their
whitespace-only text nodes stripped, except for
<code/>, <pre/>, and
<formatted-text/>, where exact source formatting must
remain intact.
Conflict Resolution and Priority
When elements match conflicting declarations, XSLT resolves them using conflict resolution rules based on import precedence and pattern priority:
- Import Precedence: Declarations in an importing stylesheet take precedence over declarations in imported stylesheets.
- Pattern Specificity: A specific QName (e.g.,
elements="code") has higher priority than a wildcard match (e.g.,elements="*"orelements="prefix:*"). - Same Precedence and Specificity: If both
<xsl:strip-space>and<xsl:preserve-space>target the exact same element name at the same import level, the XSLT processor treats it as an error or selects the last declaration occurring in the stylesheet.
Impact on XPath Operations
Whitespace manipulation significantly alters XPath evaluations:
- Node Counting: An element
<root>\n <item/>\n</root>contains three child nodes by default (two text nodes and one element node). Applying<xsl:strip-space elements="root"/>reduces the child node count to one (<item/>). - Position Filtering: In unstripped trees,
node()[1]often matches an empty whitespace text node rather than the first element child. - Output Serialization: Removing whitespace nodes prevents accidental whitespace accumulation when transforming XML into compact formats such as JSON, CSV, or minified XML/HTML.