Subject: Generic templates (Was: RE: [xsl] using call-template to call template from another xsl) From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Fri, 4 May 2001 22:14:14 -0700 (PDT) |
Michael Kay wrote: > > i was using call-template as i need to pass a parameter.How do i use > > apply-templates in this situation.Also i need to be able to > > apply-template/call-template different templates based on the value of > > $reqtype variable. > > You can pass parameters with xsl:apply-templates just as easily as with > xsl:call-template. > > With xsl:apply-templates you can also use different modes, which might solve > the problem of calling different templates based on the value of $reqtype. > In both cases you'll need an xsl:choose. > > Mike Kay > Software AG If a template must be instantiated (based on the value of $someVar) using xsl:choose, this means that the names/modes of all such templates must be known in advance. Every time we add a new template to be called, the calling template's xsl:choose must be updated to incorporate the new case. Obviously this static invocation scheme is hardly convenient. Actually there is a method for building generic templates so that they can cause different templates to be istantiated dynamically and without using xsl:choose. It is not necessary to know anything in advance about the templates to be istantiated, and in fact they may be written long after the generic template. The idea is to pass to the generic template a separate parameter, which uniquely and ***dynamically*** identifies the template that will be instantiated. This parameter is of type node-set (single node), that has a unique namespace-uri. The caller of the generic template may define many different "action templates" that match only specific unique types of nodes. During the execution of a stylesheet a generic template may be called many times with different "action template types" to perform similar processing. Below is an example of a generic template that finds and returns the "maximum" node in a node-set. The meaning of "maximum" is determined completely by an external template, which implements the relation "greater". A "template type" parameter is passed to the generic template, so that it can dynamically invoke the necessary "greater"-action template. In this example there are two "greater"-action templates implemented -- one that uses the traditional ">" relation for numbers, and another that compares their reciprocal values. There could be potentially unlimited number of different "greater"-action templates -- e.g. comparing distance, space, perimeter,... etc. They can all be passed to a single generic "maximum" template and it will always find the correct maximum node. The same method can be used for a generic sort template and in the implementation of many other useful generic algorithms. This method does't have the problem of "the last overrides override all" (described a few months ago by Jeni) when there are several templates overriding some templates of an imported stylesheet. Genericity is an extremely useful feature -- at present it is missing from both the EXSLT site and the Standard XSLT Library site. In my opinion in order for a standard template library to be really useful, it must contain ***generic*** templates. Thus it will have an unlimited number of applicationsas opposed to a fixed, very small number of applications. In the near future I will provide some initial set of useful generic templates -- min, max, sort, partial sort, binary search,... etc. Here's the example: XML source document: ------------------- <numbers> <num>1</num> <num>3</num> <num>2</num> <num>9</num> <num>4</num> <num>6</num> <num>5</num> <num>7</num> <num>8</num> </numbers> Stylesheet: ---------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:num="num" xmlns:num2="num2" > <num:node/> <num2:node/> <xsl:output omit-xml-declaration="yes" /> <xsl:variable name="gtNum-node" select="document('')//num:*"/> <xsl:variable name="gtNum2-node" select="document('')//num2:*"/> <xsl:template match="/"> <xsl:call-template name="get-max"> <xsl:with-param name="greaterSelector" select="$gtNum-node" /> <xsl:with-param name="nodes" select="/numbers/num" /> </xsl:call-template> <xsl:text>
</xsl:text> <xsl:call-template name="get-max"> <xsl:with-param name="greaterSelector" select="$gtNum2-node" /> <xsl:with-param name="nodes" select="/numbers/num" /> </xsl:call-template> </xsl:template> <xsl:template name="get-max"> <xsl:param name="greaterSelector" select="/*"/> <xsl:param name="nodes" /> <xsl:choose> <xsl:when test="$nodes"> <xsl:variable name="max-of-rest"> <xsl:call-template name="get-max"> <xsl:with-param name="greaterSelector" select="$greaterSelector" /> <xsl:with-param name="nodes" select="$nodes[position()!=1]" /> </xsl:call-template> </xsl:variable> <xsl:variable name="isGreater"> <xsl:apply-templates select="$greaterSelector" > <xsl:with-param name="n1" select="$nodes[1]"/> <xsl:with-param name="n2" select="$max-of-rest"/> </xsl:apply-templates> </xsl:variable> <xsl:choose> <xsl:when test="$isGreater = 'true'"> <xsl:value-of select="$nodes[1]" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$max-of-rest" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="-999999999" /> <!-- minus infinity --> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="isGreaterNum" match="node()[namespace-uri()='num']"> <xsl:param name="n1"/> <xsl:param name="n2"/> <xsl:value-of select="$n1 > $n2"/> </xsl:template> <xsl:template name="isGreaterNum2" match="node()[namespace-uri()='num2']"> <xsl:param name="n1"/> <xsl:param name="n2"/> <xsl:value-of select="1 div $n1 > 1 div $n2"/> </xsl:template> </xsl:stylesheet> The result produced is the two correct maximums: ----------------------------------------------- 9 1 Cheers, Dimitre Novatchev. __________________________________________________ Do You Yahoo!? Yahoo! Auctions - buy the things you want at great prices http://auctions.yahoo.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Re: XSL-List Digest V3 #7, Chris Bayes | Thread | Re: Generic templates (Was: RE: [xs, Christoph Kliemt |
[xsl] Re: XSL-List Digest V3 #731, Carlton Noles | Date | RE: [xsl] attribute nodes, Michael Fitzgerald |
Month |