Kevin
Kevin

Reputation: 345

XSL Not passing parameter through

The Problem

My parameters are coming up empty when passing through from a wildcarded templte match.

My xml Source :

<c:control name="table" flags="all-txt-align-top all-txt-unbold">
    <div xmlns="http://www.w3.org/1999/xhtml">
       <thead>
          <tr>
             <th></th>
          </tr>
       </thead>
       <tbody>
          <tr>
             <td> </td>
          </tr>
       </tbody>
</c:control>

My XSL :

The initial c:control[@name='table'] match is to do with a wider piece of XSL architecture, and splitting out calls from a main template

<xsl:template match="c:control[@name='table']">
    <xsl:call-template name="table" />
</xsl:template>

It then calls a named template in another file, which shouldn't change my starting reference - I should still be able to reference c:control[@name='table'] as if I was in the matched template.

<xsl:template name="table">
        <xsl:variable name="all-txt-top">
            <xsl:if test="contains(@flags,'all-txt-align-top')">true</xsl:if>
        </xsl:variable>
        <xsl:variable name="all-txt-unbold" select="contains(@flags,'all-txt-unbold')" />

        <div xmlns="http://www.w3.org/1999/xhtml">
            <table>
                <xsl:apply-templates select="xhtml:*" mode="table">
                    <xsl:with-param name="all-txt-top" select="$all-txt-top" />
                    <xsl:with-param name="all-txt-unbold" select="$all-txt-unbold" />
                </xsl:apply-templates>
            </table>
        </div>
    </xsl:template>

If I get the value of all-txt-top in the above template, it works as expected. However, trying to passing it through to the template below is failing - I'm not getting anything.

    <xsl:template match="xhtml:thead|xhtml:tbody" mode="table">
        <xsl:param name="all-txt-top" />
        <xsl:param name="all-txt-unbold" />

        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="*" mode="table" />
        </xsl:element>
    </xsl:template>

Even if i try passing a simple string through as a parameter - it doesn't make it to the xhtml:thead template.

Not sure where I'm going wrong... Any help would be much appreciated.

Upvotes: 0

Views: 149

Answers (1)

Tim C
Tim C

Reputation: 70648

In the sample code you have shown us, you call the named table template after the c:control element is matched

<xsl:template match="c:control[@name='table']">
  <xsl:call-template name="table" />
</xsl:template> 

This means within the table template, the current context element is c:control. However in your sample XML, the only child of the c:control is a div element. Therefore, when you do your apply-templates....

<xsl:apply-templates select="xhtml:*" mode="table">

... it will will look for a template that matches xhtml:div at this point. If you have no such template, the default template match will kick in, which will just ignore the element and process its children. This will not pass on any parameters though, and so you template that matches xhtml:thead will not have any parameters values.

One solution would be to have a template to specifically match the xhtml:div element, and pass on the attributes

<xsl:template match="xhtml:div" mode="table">
    <xsl:param name="all-txt-top"/>
    <xsl:param name="all-txt-unbold"/>
    <xsl:apply-templates select="xhtml:*" mode="table">
        <xsl:with-param name="all-txt-top" select="$all-txt-top"/>
        <xsl:with-param name="all-txt-unbold" select="$all-txt-unbold"/>
    </xsl:apply-templates>
</xsl:template>

In fact, you could change the template match here to just "xhtml:*" to make it more generic if you want to cope with more elements.

Upvotes: 2

Related Questions