<xsl:sequence>
on an atomic value (or sequence of atomic values) is the same as <xsl:copy-of>
both just return a copy of their input. The difference comes when you consider nodes.
If $n is a single element node, eg as defined by something like
<xsl:variable name="n" select="/html"/>
Then
<xsl:copy-of select="$n"/>
Returns a copy of the node, it has the same name and child structure but it is a new node with a new identity (and no parent).
<xsl:sequence select="$n"/>
Returns the node $n, The node returned has the same parent as $n and is equal to it by the is
Xpath operator.
The difference is almost entirely masked in traditional (XSLT 1 style) template usage as you never get access to the result of either operation the result of the constructor is implicitly copied to the output tree so the fact that xsl:sequence
doesn't make a copy is masked.
<xsl:template match="a">
<x>
<xsl:sequence select="$n"/>
</x>
</xsl:template>
is the same as
<xsl:template match="a">
<x>
<xsl:copy-of select="$n"/>
</x>
</xsl:template>
Both make a new element node and copy the result of the content as children of the new node x
.
However the difference is quickly seen if you use functions.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="data:,f">
<xsl:variable name="s">
<x>hello</x>
</xsl:variable>
<xsl:template name="main">
::
:: <xsl:value-of select="$s/x is f:s($s/x)"/>
:: <xsl:value-of select="$s/x is f:c($s/x)"/>
::
:: <xsl:value-of select="count(f:s($s/x)/..)"/>
:: <xsl:value-of select="count(f:c($s/x)/..)"/>
::
</xsl:template>
<xsl:function name="f:s">
<xsl:param name="x"/>
<xsl:sequence select="$x"/>
</xsl:function>
<xsl:function name="f:c">
<xsl:param name="x"/>
<xsl:copy-of select="$x"/>
</xsl:function>
</xsl:stylesheet>
Produces
$ saxon9 -it main seq.xsl
<?xml version="1.0" encoding="UTF-8"?>
::
:: true
:: false
::
:: 1
:: 0
::
Here the results of xsl:sequence
and xsl:copy-of
are radically different.