Search code examples
xsltxslt-1.0xslt-2.0

XSLT combine "params" with "match="@*|node()"


GOAL

Output an XML with the exact input names and variables as the XML my XSLT receive + 2 params from external sources

PSEUDOCODE - XSLT(1.0) I'm using variables instead of params so it's easier to test

  <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:variable name="StatusCode" select="'11111111111'">
    </xsl:variable>

    <xsl:variable name="StatusMessage" select="'########'">
    </xsl:variable>

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

<!-- BLOCK 2 -->
    <xsl:template match="/">
        <StatusCode>
            <xsl:value-of select="$StatusCode"/>
        </StatusCode>
        <StatusMessage>
            <xsl:value-of select="$StatusMessage"/>
        </StatusMessage>
    </xsl:template> 
<!-- ------- -->

</xsl:stylesheet>

PROBLEM

If I try "BLOCK 1" or "BLOCK 2" independently, they work, but I couldn't as desired combine them both


Solution

  • Your BLOCK 2 template is applied first, because it matches the root node. This template contains no xsl:apply-templates instructions - so the other template is never executed.

    The question is WHERE do you want the added nodes to appear. You could do:

    <!-- BLOCK 2 -->
        <xsl:template match="/">
            <xsl:apply-templates/>
            <StatusCode>
                <xsl:value-of select="$StatusCode"/>
            </StatusCode>
            <StatusMessage>
                <xsl:value-of select="$StatusMessage"/>
            </StatusMessage>
        </xsl:template> 
    <!-- ------- -->
    

    but this would place the added nodes outside the root element, making the result an XML fragment instead of well-formed XML document.