SyntaxStudy
Sign Up
XML XSLT Identity Transform and Modes
XML Beginner 1 min read

XSLT Identity Transform and Modes

The identity transform is a foundational XSLT pattern. It consists of a single template that matches any node or attribute (@*|node()) and copies it to the output, then recursively applies templates to all children and attributes. The result is an exact copy of the source document. By overriding one specific template in the same stylesheet, you can perform targeted modifications while leaving the rest of the document intact — this is far more maintainable than writing transforms that explicitly reconstruct every element. Modes () allow multiple template rules to match the same node for different purposes. When specifies a mode, only templates with that mode attribute are considered. This enables two passes over the same data within one stylesheet — for example, one mode generates a table of contents and another mode generates the full body. Modes also prevent ambiguity when the same node type needs different output in different contexts. The instruction copies the current node without its attributes or children. performs a deep copy including all descendants. These instructions are essential building blocks of the identity transform. XSLT 2.0 added for emitting atomic values and nodes directly, and functions like xsl:function that provide true named functions with parameters, making complex stylesheet logic cleaner than the recursive-template workarounds required in XSLT 1.0.
Example
<?xml version="1.0" encoding="UTF-8"?>
<!--
    Identity transform with targeted override:
    Copy all nodes unchanged except <price> —
    multiply each price by 1.1 (10% price increase).
-->
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <!-- IDENTITY TRANSFORM: copy everything -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Override: modify <price> elements only -->
    <xsl:template match="price">
        <price>
            <xsl:copy-of select="@*"/>
            <xsl:value-of select="format-number(. * 1.1, '0.00')"/>
        </price>
    </xsl:template>

    <!-- Override: add a generated attribute to each <book> -->
    <xsl:template match="book">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="priceIncreased">true</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- MODE EXAMPLE: generate a plain-text index in 'index' mode -->
    <xsl:template match="book" mode="index">
        <xsl:value-of select="position()"/>
        <xsl:text>. </xsl:text>
        <xsl:value-of select="title"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>