Subject: Re: [xsl] modular xslt design question From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 1 Mar 2001 10:33:13 +0000 |
Hi Dave, > Now, I have some items that should be handled in the same way, > regardless of the mode. > > <xsl:template match="D" mode="foo bar wow">...</xsl:template> > > Of course, the above isn't legal, because mode only holds a QName, > not a list of them. I would like to avoid cut-and-pasting the common > template n times (where n is the number of styles I have -- it will > be more than three!). I also don't see a way to apply-templates > (back in A, B, and C) in document order such that the child elements > can be matching in different modes. You could have another template (perhaps another mode, 'common', or non-moded) that contains the logic for each, and then apply templates to the current node in that mode within each of the templates, i.e.: <xsl:template match="D" mode="foo"> <xsl:apply-templates select="." mode="common" /> </xsl:template> <xsl:template match="D" mode="bar"> <xsl:apply-templates select="." mode="common" /> </xsl:template> <xsl:template match="D" mode="wow"> <xsl:apply-templates select="." mode="common" /> </xsl:template> <xsl:template match="D" mode="common"> <!-- do your stuff --> </xsl:template> > My intended workaround was to use templates without modes to manage > the general flow, with a parameter being passed through all(!) of > them to indicate the intended mode/style. Templates with behaviour > common to all modes can be implemented directly; others can be > implemented by dispatching to mode-specific named templates, e.g. The only way to do this kind of dispatching is unfortunately: <xsl:template match="A"> <xsl:param name="mode" /> <xsl:choose> <xsl:when test="$mode = 'foo'"> <xsl:apply-templates select="." mode="foo" /> </xsl:when> <xsl:when test="$mode = 'bar'"> <xsl:apply-templates select="." mode="bar" /> </xsl:when> <xsl:when test="$mode = 'wow'"> <xsl:apply-templates select="." mode="wow" /> </xsl:when> </xsl:choose> </xsl:template> Of course you don't have to do this for every single element, you could make it match on any number of elements, or all of them. In fact, you could make a reasonable general dispatching template with: <xsl:template match="*"> <xsl:param name="mode" /> <xsl:variable name="result"> <xsl:choose> <xsl:when test="$mode = 'foo'"> <xsl:apply-templates select="." mode="foo" /> </xsl:when> <xsl:when test="$mode = 'bar'"> <xsl:apply-templates select="." mode="bar" /> </xsl:when> <xsl:when test="$mode = 'wow'"> <xsl:apply-templates select="." mode="wow" /> </xsl:when> </xsl:choose> </xsl:variable> <xsl:choose> <xsl:when test="string($result)"> <xsl:copy-of select="$result" /> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="." mode="general" /> </xsl:otherwise> </xsl:choose> </xsl:template> So if applying templates in the specific mode doesn't work (you don't get any result from it) then you apply templates in 'general' mode. It means that you can create a template in 'general' mode for modes that are very similar for particular elements. You have to watch the test, though. string($result) will only be true() if there is some textual content in the result, which there might not be. It'd be better if you could tested with: saxon:node-set($result)/node() or the equivalent in your processor. The other danger is if some of the templates in foo, bar or wow mode purposefully produce nothing. Then you need a general mode template that also produces nothing. You could pass the proper $mode into the general-mode template as a parameter to get around that. I hope that gives you some ideas, 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] modular xslt design question, Dave Gomboc | Thread | Re: [xsl] modular xslt design quest, RSuiter |
[xsl] Reference Orientation, rabi shanker | Date | Re: [xsl] ANNOUNCE: Petition to wit, Jeni Tennison |
Month |