Skip to content


Causes the current XML node in the source document to be copied to the output. The actual effect depends on whether the node is an element, an attribute, or a text node.

Available in XSLT 1.0 and later versions. Available in all Saxon editions.

  • Category: instruction
  • Content: sequence-constructor
  • Permitted parent elements: any XSLT element whose content model is sequence-constructor; any literal result element


New in XSLT 3.0. Allows a node other than the context node to be copied. This is useful when the instruction appears inside xsl:function.
Used only when copying element nodes. If the value is yes (the default), then all namespace nodes of the source element are copied as namespace nodes for the newly constructed element. If the value is no, then the namespace nodes are not copied.
Used only when copying element nodes. If the value is yes (the default), then the namespace nodes created for the newly constructed element are copied to its children and descendants. If the value is no, then these namespace nodes are not automatically copied.
Used only when copying element nodes. Attributes of a generated element can be defined by reference to named attribute sets, provided as a whitespace-separated list. They are applied in the order given: if the same attribute is generated more than once, the later value always takes precedence.
"strict" | "lax" | "preserve" | "strip"

Notes on the Saxon implementation

Motivated by streaming, the on-empty attribute was introduced in an early Working Draft for XSLT 3.0, but later removed and replaced by the new xsl:on-empty, xsl:on-non-empty and xsl:where-populated instructions. The on-empty attribute was implemented in Saxon 9.5, but removed in 9.7.


When xsl:copy is applied to an element node, the start and end element tags are copied; the attributes, character content and child elements are copied only if xsl:apply-templates is used within xsl:copy.


A template that copies the input element to the output, together with all its child elements, character content, and attributes:

<xsl:template match="*|text()|@*">
        <xsl:apply-templates select="@*"/>

See also