Problem with XSLT and call-template

J

Julien Phalip

Hi everyone!

I am doing an XSL transformation from the following XML file:

<foo>
<attribute>a</attribute>
</foo>


The xslt file is:

<xsl:include href="a.xsl"/> <!-- Defines the template 'a' -->
<xsl:include href="b.xsl"/> <!-- Defines the template 'b' -->
<xsl:include href="c.xsl"/> <!-- Defines the template 'c' -->

<xsl:template name="foo">
<xsl:if test="attribute = 'a'">
<xsl:call-template name="a"/>
</xsl:if>
<xsl:if test="attribute = 'b'">
<xsl:call-template name="b"/>
</xsl:if>
<xsl:if test="attribute = 'c'">
<xsl:call-template name="c"/>
</xsl:if>

etc...

</xsl:template>

But now I am starting to have a lot of templates, and it requires to
add another "if" statement every new template I create.
So I would like to make this XSLT file simpler by doing something
like:

<xsl:template name="foo">
<xsl:call-template name="{./attribute}"/>
</xsl:template>

But this doesn't work. I get the error "Could not find template named:
{./attribute}".

Can anybody help me with that?

Thanks a lot,

Julien
 
D

David Carlisle

<xsl:template name="a">
....
<xsl:if test="attribute = 'a'">
<xsl:call-template name="a"/>
</xsl:if>
<xsl:if test="attribute = 'b'">
<xsl:call-template name="b"/>
</xsl:if>
...
But now I am starting to have a lot of templates, and it requires to
add another "if" statement every new template I create.

That isn't the way XSLT is intended to be used, Normally you would just
do


<xsl:template match="attribute[.='a']">
...
<xsl:template match="attribute[.='b']">
...



<xsl:template name="foo">
<xsl:apply-templates select="attribute"/>
</xsl:template>


David
 
R

Robin Johnson

[email protected] (Julien Phalip) wrote in message news: said:
So I would like to make this XSLT file simpler by doing something
like:

<xsl:template name="foo">
<xsl:call-template name="{./attribute}"/>
</xsl:template>

But this doesn't work. I get the error "Could not find template named:
{./attribute}".

Right. xsl:call-template/@name doesn't take an expandable attribute
value template, I'm afraid, just a QName, so there's no way to do that
in vanilla XSLT.

Depending on what implementation you're using, though, there may be an
extension to do it. I know Saxon has a saxon:call-template function
which is identical to xsl:call-template except that it lets you do
what you're asking about.

However, wouldn't it be nicer to use apply-templates with a mode, and
multilple templates in that mode with predicates on the match
expression? e.g.

<xsl:template name="foo">
<xsl:apply-templates mode="foo" select="."/>
</xsl:template>

and your subtemplates
<xsl:template mode="foo" match="*[attribute = 'a']">
<!-- ... -->
</xsl:template>

<xsl:template mode="foo" match="*[attribute = 'b']">
<!-- ... -->
</xsl:template>

<!-- and so on -->

Then one template will be chosen depending on the value of @attribute,
and you didn't need to list all the possible values of @attribute in a
big ugly choose, which is what you wanted.

As a rule, xsl:apply-templates good. xsl:call-template bad.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top