htmlxmlxsltxslt-1.0

Why does my XSLT `xsl:attribute` disappear when placed after `xsl:text` in `xsl:element`?


I'm working on an XSLT transformation to create an HTML <button> element with an onclick attribute. When I define the onclick attribute before the button's text content, everything works as expected. Here’s the code that works:

<xsl:element name="button">
    <xsl:attribute name="onclick">
        console.log(600);
    </xsl:attribute>
    
    <xsl:text>Click Me</xsl:text>
</xsl:element>

Output:

<button onclick="console.log(600);">Click Me</button>

However, if I place the xsl:attribute after the xsl:text content, like this:

<xsl:element name="button">
    <xsl:text>Click Me</xsl:text>

    <xsl:attribute name="onclick">
        console.log(600);
    </xsl:attribute>
</xsl:element>

The attribute is ignored, and the output only contains the text:

<button>Click Me</button>

Why does placing xsl:attribute after xsl:text cause the attribute to disappear? Is there a rule in XSLT that requires attributes to be defined before content, and if so, what’s the reasoning behind it? And why does it behave this way?


Solution

  • The rules are in https://www.w3.org/TR/xslt-10/#creating-attributes:

    The following are all errors:

    Adding an attribute to an element after children have been added to it; implementations may either signal the error or ignore the attribute.

    So yes, you need to output attributes before any child nodes (like a text node), otherwise you might get an error or your XSLT processor ignores the attribute.