This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: modular xslt design question
- To: "Dave Gomboc" <dave at cs dot ualberta dot ca>
- Subject: Re: [xsl] modular xslt design question
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Thu, 1 Mar 2001 10:33:13 +0000
- CC: "Mulberry XSL" <xsl-list at lists dot mulberrytech dot com>
- Organization: Jeni Tennison Consulting Ltd
- References: <001101c0a221$48a27240$20718081@thorin>
- Reply-To: xsl-list at lists dot mulberrytech dot com
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