[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

XSL macros stronger then XSLT


Subject: XSL macros stronger then XSLT
From: "Oren Ben-Kiki" <oren@xxxxxxxxxxxxx>
Date: Thu, 29 Apr 1999 13:46:26 +0200

I've started converting my XSL stylesheets to XSLT and encountered the
following problem. It seems as though <xsl:macro> can not be (in general)
converted to a named template. The missing feature is an equivalent to
<xsl:contents/>.

Consider the following simplified (old) XSL sheet fragment:

<xsl:macro name="InnerWrapper">
    <xsl:macro-arg name="Element"/>
    <xsl:element name="{arg(Element)}">
        <xsl:attribute name="A">a value</xsl:attribute>
        <xsl:contents/>
    </xsl:element>
</xsl:macro>

<xsl:macro name="OuterWrapper">
    <xsl:macro-arg name="Element"/>
    <xsl:choose>
        <xsl:when test="... complex test ...">
            <xsl:element name="WRAP">
                <xsl:invoke-macro name="InnerWrapper">
                    <xsl:arg name="Element" value="{arg(Element)}"/>
                    <xsl:contents/>
                </xsl:invoke-macro>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:invoke-macro name="InnerWrapper">
                    <xsl:arg name="Element" value="{arg(Element)}"/>
                    <xsl:contents/>
            </xsl:invoke-macro>
    </xsl:choose>
</xsl:macro>

<xsl:template match="C">
    <xsl:invoke-macro name="OuterWrapper">
        <xsl:arg name="Element">E</xsl:param>
        <xsl:attribute name="B">b value</xsl:attribute>
        <xsl:apply-templates/>
    </xsl:call-template>
</xsl:template>

Trying to convert it to (new) XSLT yields:

<xsl:template name="InnerWrapper">
    <xsl:param-variable name="Element"/>
    <xsl:element name="{$Element}">
        <xsl:attribute name="A">a value</xsl:attribute>
        ??? here's the problem ???
    </xsl:element>
</xsl:template>

<xsl:template name="OuterWrapper">
    <xsl:param-variable name="Element"/>
    <xsl:choose>
        <xsl:when test="complex test">
            <xsl:element name="WRAP">
                <xsl:call-template name="InnerWrapper">
                    <xsl:param name="Element">
                        <xsl:value-of select="$Element"/>
                    </xsl:param>
                    ??? and here ???
                </xsl:call-template>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="InnerWrapper">
                <xsl:param name="Element">
                    <xsl:value-of select="$Element"/>
                </xsl:param>
                ??? and here ???
            </xsl:call-template>
    </xsl:choose>
</xsl:macro>

<xsl:template match="C">
    <xsl:call-template name="OuterWrapper">
        <xsl:param name="Element">E</xsl:param>
        ??? <xsl:attribute name="B">b value</xsl:attribute> ???
        ??? <xsl:apply-templates/> ???
    </xsl:call-template>
</xsl:template>

Note that this is simplified; in reality the macros assign more attributes
to the elements, invoke other templates, and so on. Repeating the code for
the inner wrapper is barely tolerable; repeating the code for the outer
wrapper definitely isn't.

What's worse, I don't see any way to work around this limitation in the XSLT
draft. I started considering alternatives as to how to re-provide this
feature:

1. Retreat: to <xsl:macro> and <xsl:contents>, but keeping the new
<xsl:param> tags instead of the old <xsl:arg> tags.

2. Advance: allow variables to have a node-set/node-list value instead of
just a string value. This has far-reaching consequences.

3. Patch: allow <xsl:contents> in named templates. It would have to be given
a value when the template is invoked by matching instead of by calling; I'm
not certain what this value should be - maybe the list of all children of
the matched element? This could be tied to calling <xsl:apply-templates/>
(with no select) - both could mean the same thing. Hmmm....  maybe we could
give up on the <xsl:contents/> syntax altogether, in that case.

4. Something else?

If I had to choose, I'd probably go for (3) or (1). (2) is also nice but it
has to be properly thought out first. Of course, if someone comes up with a
good value for (4), that would be nice. Either way, I hate to think that
this feature is gone. I think I'll delay switching to the new syntax until I
absolutely have to, or I find some workaround for this.

Share & Enjoy,

    Oren Ben-Kiki


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords