This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Ann: Generic Templates -- min(), max(), binSearch(), sort()


Dimitre Novatchev wrote:
> I have submitted to the EXSL list a number of generic templates
> implementing generic functions as specified in the subject.

One of the neat ideas in these implementations is a possible answer to
the frequently asked question "how do I call templates dynamically?" -
how to choose the name of the template that you want to call based on
a variable.

One answer is to add a match pattern to the template that matches a
(single) node that acts as a proxy or UID for the template.  Dimitre's
examples use a specially-defined node at the top level of the
stylesheet.  For named templates, another approach would be to use the
xsl:template elements themselves, e.g.:

<xsl:template name="my:named-template"
              match="xsl:template[@name = 'my:namedTemplate']">
   ...
</xsl:template>

You can then apply templates to the relevant xsl:template element to
have the same kind of effect as calling the template.  I would
probably set up a global variable to hold the template elements:

<xsl:variable name="templates" select="document('')/xsl:template" />

[Note: this only gets the templates in the current physical
stylesheet, not any that have been imported/included, which could be a
big drawback - is this something that could be addressed with the
closure() function that Christian Nentwich suggested?]

And then filter that to get the relevant one:

  <xsl:apply-templates select="$templates[@name = $template-name]" />

[Note: you could use the template elements as nodes with Dimitre's
generic templates, but they'd be passed as a parameter rather than
have templates applied to them.]
  
The big difference between applying templates in this way and calling
the template is that the current node and position() within the
template body will be the xsl:template element and 1 respectively.
You can get around this problem by passing in parameters holding these
values in the context in which the template is called/applied:

  <xsl:apply-templates select="$templates[@name = $template-name]">
     <xsl:with-param name="current" select="." />
     <xsl:with-param name="position" select="position()" />
  </xsl:apply-templates>
  
I'm not sure if this is new, but it's not something that we've been
giving as an answer to the 'dynamically calling templates' FAQ, so I
thought it would be worth describing.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]