XSLT Reference
snapshot()
Returns a snapshot copy of the sequence, making streamed nodes available for multiple use.
snapshot(sequence?)Description
snapshot() returns a deep copy of its argument sequence, detached from the original document. Its primary purpose is in streaming mode: when a template is processing a streamed document, nodes are typically available only once and cannot be re-read. Calling snapshot() materializes those nodes into a persistent in-memory copy that can be used multiple times, stored in a variable, or passed to a function that requires grounded (non-streamed) nodes.
Outside of streaming mode, snapshot() behaves identically to copy-of() and produces deep copies of all node items. Atomic values in the sequence are returned unchanged.
When called without arguments in XSLT 3.0, the function snapshots the context item.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sequence | item()* | No | The sequence to snapshot. Defaults to the context item if omitted. |
Return value
item()* — a deep copy of the node items in the sequence; atomic values returned unchanged.
Examples
Capturing streamed nodes for reuse
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order id="1" amount="100"/>
<order id="2" amount="200"/>
<order id="3" amount="150"/>
</orders>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/orders">
<!-- snapshot() lets us use the orders node-set twice -->
<xsl:variable name="snap" select="snapshot(order)"/>
<report>
<count><xsl:value-of select="count($snap)"/></count>
<total><xsl:value-of select="sum($snap/@amount)"/></total>
</report>
</xsl:template>
</xsl:stylesheet>
Output:
<report>
<count>3</count>
<total>450</total>
</report>
Snapshot of the context item
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="order">
<xsl:variable name="copy" select="snapshot()"/>
<!-- $copy can be used multiple times -->
<saved id="{$copy/@id}" amount="{$copy/@amount}"/>
</xsl:template>
<xsl:template match="/orders">
<saved-orders>
<xsl:apply-templates select="order"/>
</saved-orders>
</xsl:template>
</xsl:stylesheet>
Output:
<saved-orders>
<saved id="1" amount="100"/>
<saved id="2" amount="200"/>
<saved id="3" amount="150"/>
</saved-orders>
Notes
snapshot()is a no-op on atomic values; they are returned unchanged.- In non-streaming mode,
snapshot()andcopy-of()produce equivalent results. - Use
snapshot()rather thancopy-of()when the intent is specifically to escape the streaming constraint, as this communicates the purpose more clearly to readers. - The function was added in XPath 3.0 specifically to support the XSLT 3.0 streaming model.