Re: [xsl] Adding another layer of global styling

Subject: Re: [xsl] Adding another layer of global styling
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 29 Jul 2003 11:40:34 +0100
Wendell wrote:
> Discriminate two templates that you will use to handle your titles.
> One will handle their basic output based on their @level or @rend
> (what you already have); the other will provide the extra span
> wrapper around the Sanskrit ones.

For interest, XSLT 2.0 provides a really neat way of dealing with this
kind of problem: using <xsl:next-match>. Basically what
<xsl:next-match> says is "find the next best matching template, apply
that to the current node, and insert the result here".

So in this case, you would have one template with a high priority that
recognised the Sanskrit titles, created the <span> and put the result
of using the next match inside the <span>:

<xsl:template match="title[@lang = 'sa']" priority="4">
  <span style="font-family: 'Titus'">
    <xsl:next-match />
  </span>
</xsl:template>

Then you could have another set of templates, at a lower priority,
that would deal with the formatting based on the level and rend
attributes. Note that because <title> elements without a lang
attribute with the value 'sa' wouldn't match the above template,
they'd fall immediately through to this template instead.

<xsl:template match="title" priority="3">
  <xsl:choose>
    <xsl:when test="@level = ('m', 'j')">
      <span style="font-style:italic"><xsl:next-match /></span>
    </xsl:when>
    <xsl:when test="@level = ('a', 'u')">"<xsl:next-match />"</xsl:when>
    <xsl:when test="@rend = 'bold'">
      <span style="font-weight:bold"><xsl:next-match /></span>
    </xsl:when>
    <xsl:otherwise>
      <span style="font-style:italic"><xsl:next-match /></span>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

and finally have a level that deals with those <title> elements within
<listBibl> elements, which need to have a . put after their values:

<xsl:template match="listBible//title" priority="2">
  <xsl:next-match /><xsl:text>.</xsl:text>
</xsl:template>

When there aren't any matching templates in the stylesheet itself, the
built-in template gets used instead.

You can do the same kind of thing in XSLT 1.0 using
<xsl:apply-imports>, but you have to split the different layers of
processing into different stylesheets (which imports the stylesheet
containing the templates with the next highest priority), which can be
a real pain.

Or the other thing I'd do here in XSLT 1.0 is to use modes:

<xsl:template match="title[@lang = 'sa']">
  <span style="font-family: 'Titus'">
    <xsl:apply-templates select="." mode="style" />
  </span>
</xsl:template>

<xsl:template match="title">
  <xsl:apply-templates select="." mode="style" />
</xsl:template>

<xsl:template match="title" mode="style">
  <xsl:choose>
    <xsl:when test="@level = 'm' or @level = 'j'">
      <span style="font-style:italic">
        <xsl:apply-templates select="." mode="listBibl" />
      </span>
    </xsl:when>
    <xsl:when test="@level = 'a' or @level = 'u'">
      <xsl:text>"</xsl:text>
      <xsl:apply-templates select="." mode="listBibl" />
      <xsl:text>"</xsl:text>
    </xsl:when>
    <xsl:when test="@rend = 'bold'">
      <span style="font-weight:bold">
        <xsl:apply-templates select="." mode="listBibl" />
      </span>
    </xsl:when>
    <xsl:otherwise>
      <span style="font-style:italic">
        <xsl:apply-templates select="." mode="listBibl" />
      </span>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="listBible//title" mode="listBibl">
  <xsl:apply-templates /><xsl:text>.</xsl:text>
</xsl:template>

<xsl:template match="title" mode="listBibl">
  <xsl:apply-templates />
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread