Subject: Re: [xsl] xslt style From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 10 Jan 2003 12:18:00 +0000 |
Hi Dave, > Jeni wrote: >> .... personally, I think that the only time you should use named >> templates is when the context node, position and size has no >> influence on the result of the template -- in other words when it's >> a pure function that computes its results based purely on the >> parameters that are passed to it. Otherwise, my preference is to >> use moded matching templates. > > I'm rather curious about the logic behind this Jeni. I can see the > advantage of this class of use, in that it could then be used > anywhere, in any stylesheet. Is that the rationale? > > Your option of using moded matching templates I'm less clear on. > Lets say I have a named template that performs some function, > then uses the parent of the current node for something; is this > the use-case for the moded template? Well, here is an example of what I think is a bad design: <xsl:template match="person"> <xsl:call-template name="getName" /> </xsl:template> <xsl:template name="getName"> <xsl:value-of select="givenName" /> <xsl:text> </xsl:text> <xsl:value-of select="familyName" /> </xsl:template> The getName template uses the context node at the point the template was called in order to resolve the two paths ("firstName" and "surname"). I think that this is bad design because there is no indication in the getName template about what kind of node the context node is. If I'm debugging the getName code I have to look at every call to the template to work out what the context node is in order to work out what the expressions within the template should be. I think it is much better to use: <xsl:template match="person"> <xsl:apply-templates select="." mode="name" /> </xsl:template> <xsl:template match="person" mode="name"> <xsl:value-of select="givenName" /> <xsl:text> </xsl:text> <xsl:value-of select="familyName" /> </xsl:template> Looking at the latter template tells me all I need to know about what the template creates. Nothing from outside the template (such as the context in which it is called) has any influence on the result. This makes it easy to debug. It also makes the code more modular, both because you can copy the same template into other stylesheets and it will standalone, as you point out, and because it's easier for other people to import and adapt. If <person> elements with a location attribute of "Japan" should display the family and given names the other way round it's easy to add a separate template to do this: <xsl:template match="person[@location = 'Japan']" mode="name"> <xsl:value-of select="familyName" /> <xsl:text> </xsl:text> <xsl:value-of select="givenName" /> </xsl:template> I can see the arguments that for some templates, for example one that creates an XPath to a node, the identity of the context node doesn't really matter, but is just being used as a kind of built-in parameter to the template. Even in these circumstances, I think that the modularity argument makes me lean towards a moded template, but if that's not an issue then I think the template should include a parameter that defaults to the context node rather than using it implicitly. In other words, rather than: <xsl:template name="createPath"> <xsl:for-each select="ancestor-or-self::node()"> <xsl:value-of select="name()" /> ... <xsl:if test="position() != last()">/</xsl:if> </xsl:for-each> </xsl:template> I prefer: <xsl:template name="createPath"> <xsl:param name="node" select="." /> <xsl:for-each select="$node/ancestor-or-self::node()"> <xsl:value-of select="name()" /> ... <xsl:if test="position() != last()">/</xsl:if> </xsl:for-each> </xsl:template> I prefer this because it makes the template more flexible in that it can be passed a particular node to use, which means that rather than having to change the context node with an xsl:for-each: <xsl:for-each select=".."> <xsl:call-template name="createPath" /> </xsl:for-each> you can pass a parameter: <xsl:call-template name="createPath"> <xsl:with-param name="node" select=".." /> </xsl:call-template> which I find more approachable. I also prefer the explicit parameter because when I come back to the template I can immediately tell that the context node is used in the template and therefore the results will depend on where the template is called, something that isn't immediately apparent otherwise. Does that make sense? Anyone think I'm missing something? 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 -> |
---|---|---|
RE: [xsl] xslt style, David . Pawson | Thread | RE: [xsl] xslt style, Michael Kay |
Re: [xsl] Translating the contents , Phil Carty | Date | Re: [xsl] Translating the contents , Jeni Tennison |
Month |