[xsl] getting "Cannot create an attribute node (...) whose parent is a document node" when copying attribute nodes through an XSLT function

Subject: [xsl] getting "Cannot create an attribute node (...) whose parent is a document node" when copying attribute nodes through an XSLT function
From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 30 Jun 2020 16:10:15 -0000
Hello! Language is XSLT 2.0, processor is Saxon-PE 9.9.1.7 in Oxygen XML
Editor v22.1.

I'm trying to pass attribute nodes from an element template to a function,
make a modified copy of the attributes inside the function, then return them
for inclusion in the element. But when I attempt this, I get

Cannot create an attribute node (class) whose parent is a document node.

I researched the message but don't understand how it applies here. Michael
Kay's book indicates that sequences of attributes can be manipulated and
subsequently applied to an element, and that the attributes can be parentless,
although the example in the book doesn't pass them through a function like
this.

An example input document is

====
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <p class="foo " outputclass="BAR"/>
</root>
====

and the XSLT is

====
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
    xmlns:mine="mine:local"
    exclude-result-prefixes="xs"
    version="2.0">

    <!-- baseline identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- copy 'p' elements, but pass attributes through the mine:recopy()
function -->
    <xsl:template match="p[@*]">
        <xsl:copy>
            <xsl:sequence select="mine:recopy(@*)"/>  <!-- apply a copy of the
attributes from mine:recopy() - BROKEN -->
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- make a copy of the attributes (a proxy for processing) and return
them -->
    <xsl:function name="mine:recopy">
        <!-- get input parameter attributes -->
        <xsl:param name="orig_atts"/>

        <!-- make a copy of the attributes in a variable -->
        <xsl:variable name="new_atts">
            <xsl:sequence select="$orig_atts"/>
        </xsl:variable>

        <!-- return the copied attributes -->
        <xsl:sequence select="$new_atts"/>
    </xsl:function>
</xsl:stylesheet>
====

The attributes aren't children of the document node at any point, and I didn't
find any existing discussions that explained this behavior.

Thanks in advance!

- Chris

P.S. This is a basic machinery issue I'm hitting while trying to solve the
larger problem described here:

https://stackoverflow.com/questions/62597965/whats-the-best-way-to-move-space
-delimited-tokens-from-one-attribute-to-another

-----
Chris Papademetrious
Tech Writer, Implementation Group
(610) 628-9718 home office
(570) 460-6078 cell

Current Thread