Subject: Re: [xsl] XSL nodes evaluation on the fly From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Mon, 25 Feb 2002 16:35:47 +0000 |
Hi Maros, > Is XSL nodes evaluation on the fly possible? I would like to create > set of "standard" templates which have only different body > (something like FUNCALL in LISP or function template in C++). You can't do it in the way that you've tried, but you can do it using Dimitre Novatchev's 'generic templates' technique. You can find out more about the technique in general in Dimitre's article on functional programming in XSLT at: http://www.topxml.com/xsl/articles/fp Dimitre has implemented a large number of generic templates using this technique, so you'd be well advised to check those out before you start creating your own: http://www.topxml.com/downloads/default.asp?id=v20021156554 To illustrate the approach with your example, you could create a set of templates that contain the XSLT code that you want to act as the functions. For example: <xsl:template name="createRow"> <xsl:param name="i" /> <TR> <TD height="$i"/> </TR> </xsl:template> As well as naming these templates, you should make these templates match themselves, as follows: <xsl:template name="createRow" match="xsl:template[@name = 'createRow']"> <xsl:param name="i" /> <TR> <TD height="{$i}"/> </TR> </xsl:template> Then, in your generic for.loop template, rather than the $body parameter holding the code itself, you can make it hold a reference node that identifies the template that you want to use (in this case, the xsl:template element for the relevant template). The code for the for.loop template should apply templates to this reference node, passing any required parameters using xsl:with-param, as follows: <xsl:template name="for.loop"> <xsl:param name="i"/> <xsl:param name="count"/> <xsl:param name="body"/> <xsl:if test="$i <= $count"> <!-- apply templates to the $body parameter, passing the $i parameter --> <xsl:apply-templates select="$body"> <xsl:with-param name="i" select="$i" /> </xsl:apply-templates> <xsl:if test="$i < $count"> <xsl:call-template name="for.loop"> <xsl:with-param name="i" select="$i + 1"/> <xsl:with-param name="count" select="$count"/> <xsl:with-param name="body" select="$body" /> </xsl:call-template> </xsl:if> </xsl:if> </xsl:template> When you call the for.loop template, the $body parameter is set to the reference node. In this case, it's the xsl:template element in the current stylesheet whose name attribute is equal to 'createRow'. The call is therefore as follows: <xsl:call-template name="for.loop"> <xsl:with-param name="i" select="1"/> <xsl:with-param name="count" select="count(BODY/ROW)"/> <xsl:with-param name="body" select="document('')/*/xsl:template[@name = 'createRow']" /> </xsl:call-template> This example uses a slightly different technique from Dimitre's standard method for identifying the template that you want to use. Dimitre generally adds a separate data element at the top level of the stylesheet, which is matched by the relevant template and acts as the reference node, whereas in the above I've used the xsl:template element itself as the reference node. But the fundamentals are the same; the only reason I've done this is because it keeps the explanation shorter - using a node other than the xsl:template element is more flexible in general. By the way, you used xsl:eval in your example, which makes me think that you might be using WD-xsl rather than XSLT. Check out the MSXML FAQ at http://www.netcrucible.com/ if you don't know the difference. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] XSL nodes evaluation on the f, Ivanco Maros | Thread | [xsl] import href vaule set using X, Aedemar Cooke |
Re: Re: [xsl] creating sequence dia, Saverio Perugini | Date | Re: [xsl] creating sequence diagram, Jeni Tennison |
Month |