Re: [xsl] variable question

Subject: Re: [xsl] variable question
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sun, 29 Aug 2004 21:32:34 +0100
Hi Bruce,

> OK. So a good solution might be to define a simple template and then
> call it, so that my titleInfo template becomes something like the
> following?

Yes, something like that should work, except that it seems from your
description that the <mods:relatedItem> elements are *parents* of your
<mods:titleInfo> elements, so you want to use the path:

  parent::mods:relatedItem

rather than:

  ../mods:relatedItem

(which gets the sibling <mods:relatedItem> elements).

Usually, when I want a template whose content uses information about
the current node (as yours does -- the result depends on which
<mods:titleInfo> element is being processed), I use a template with a
particular mode rather than a named template. So, in XSLT 1.0 I'd do:

<xsl:template match="mods:titleInfo[not(@type='abbreviated')]"
              mode="bibliography">
  <span>
    <xsl:attribute name="class">
      <xsl:text>title</xsl:text>
      <xsl:if test="not(parent::mods:relatedItem[@type = 'host'])">
        <xsl:text> italic</xsl:text>
      </xsl:if>
    </xsl:attribute>
    <xsl:apply-templates select="." mode="title-before"/>
    <xsl:apply-templates select="mods:title"/>
    <xsl:apply-templates select="mods:subTitle"/>
    <xsl:apply-templates select="." mode="title-after"/>
  </span>
</xsl:template>

<xsl:template match="mods:titleInfo" mode="title-before">
  <xsl:variable name="reftype">
    <xsl:apply-templates select="parent::mods:relatedItem"
                         mode="reftype" />
  </xsl:variable>
  <xsl:if test="$reftype='chapter'">"</xsl:if>
</xsl:variable>

<xsl:template match="mods:relatedItem" mode="reftype">
  <xsl:choose>
    <xsl:when test="@type = 'host'">
      <xsl:variable name="issuance"
                    select="mods:originInfo/mods:issuance" />
      <xsl:choose>
        <xsl:when test="$issuance = 'continuing'">article</xsl:when>
        <xsl:when test="$issuance = 'monographic'">chapter</xsl:when>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>book</xsl:otherwise>
  </xsl:choose>
</xsl:template>

Note that I've rewritten your code in places to bring out the logic a
bit more clearly. For example, the only thing that seems to change if
the mods:relatedItem's type is 'host' is the value of the class on the
span, so in the above code, that test is localised to the value of the
class attribute. This saves you from repeating the same code (and
having to update all the instances when you need to change it).

For XSLT 2.0, I think I'd turn the reftype template into a function
instead, since it just returns a string. I'd keep the title-before
template as a template since it might return some XML when you revise
it in the future. So it would look more like:

<xsl:template match="mods:titleInfo[not(@type='abbreviated')]"
              mode="bibliography">
  <span class="{if (../mods:relatedItem[@type = 'host'])
                then 'title'
                else 'title italic'}">
    <xsl:apply-templates select="." mode="title-before"/>
   	<xsl:apply-templates select="mods:title"/>
   	<xsl:apply-templates select="mods:subTitle"/>
   	<xsl:apply-templates select="." mode="title-after"/>
  </span>
</xsl:template>

<xsl:template match="mods:titleInfo" mode="title-before">
  <xsl:if test="mods:reftype(parent::mods:relatedItem) = 'chapter'">
    <xsl:text>"</xsl:text>
  </xsl:if>
</xsl:template>

<xsl:function name="mods:reftype" as="xs:string">
  <xsl:param name="relatedItem" as="element(mods:relatedItem)" />
  <xsl:choose>
    <xsl:when test="$relatedItem/@type = 'host'">
      <xsl:variable name="issuance" as="xs:string"
        select="$relatedItem/mods:originInfo/mods:issuance" />
      <xsl:choose>
        <xsl:when test="$issuance = 'continuing'">article</xsl:when>
        <xsl:when test="$issuance = 'monographic'">chapter</xsl:when>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>book</xsl:otherwise>
  </xsl:choose>
</xsl:function>

Cheers,

Jeni

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

Current Thread