What Is node() vs text() in XSLT Pattern Matching?
In XSLT and XPath, node() and text() are
both node test functions used to select or match components of an XML
document tree, but they target different structural scopes. While
text() matches only textual character data within elements,
node() matches any node type including elements, text
nodes, comments, and processing instructions, excluding only attributes
and the root document node itself unless explicitly targeted.
The Scope of node()
The node() test is a broad selector that matches any
child node of the current context regardless of its specific type. In an
XML tree structure, child nodes include:
- Element nodes (
<item>...</item>) - Text nodes (raw strings between element tags or whitespace)
- Comment nodes (
<!-- comment -->) - Processing instructions (
<?target data?>)
When used in template matching,
<xsl:template match="node()"> applies to every child
node type encountered during traversal. It is frequently employed in
identity transforms to match and copy all structural elements and their
contents. Notably, node() does not match attribute nodes
(@*) or namespace nodes, as attributes are not considered
child nodes in the XPath data model.
The Scope of text()
The text() test is a specialized node test designed
exclusively to match text nodes. Text nodes represent the character data
enclosed by elements, including meaningful string content, whitespace,
newlines, and entity references evaluated into plain text.
When written as <xsl:template match="text()">, the
template triggers only when processing raw character data. It ignores
surrounding wrapper elements, child elements, comments, and processing
instructions.
Key Behavioral Differences
The primary distinction between node() and
text() lies in specificity and structural granularity:
- Element Handling:
node()matches both container elements and their internal text, whereastext()bypasses element containers and targets only the inner string data. - Whitespace Sensitivity: Both tests will capture
whitespace-only text nodes between tags unless stripped via
<xsl:strip-space>or stylesheet rules. However,text()isolates these strings directly, whilenode()processes them alongside accompanying markup. - Identity Transforms: Applying
<xsl:apply-templates select="node()"/>ensures that child elements, comments, and text are all passed along the processing pipeline. Applying<xsl:apply-templates select="text()"/>discards nested tags and comments, processing only immediate text strings. - Template Priority: When multiple templates could
potentially match a text node, a template with
match="text()"has a default priority of0, whereasmatch="node()"carries a default priority of-0.5, allowing more specific text handlers to take precedence automatically.
Choosing between node() and text() depends
on whether the transformation requires preserving structural XML markup
and metadata or extracting and modifying raw text values alone.