Re: [xsl] modes and temp trees (was Re: [xsl] grouping + global variable (?))

Subject: Re: [xsl] modes and temp trees (was Re: [xsl] grouping + global variable (?))
From: Bruce D'Arcus <bdarcus@xxxxxxxxxxxxx>
Date: Tue, 17 Aug 2004 09:57:49 -0400
On Aug 14, 2004, at 4:49 PM, Bruce D'Arcus wrote:

I took Wendell's suggestion and reworked the modes, and changed the previous "phase-2" mode and made it default. The bibliography generation now works beautifully and I've gotten things much better modularized. But I can't get the citation mode to work. Much of the time, I'm sending Saxon into an infinite loop trying to figure it out!

It nearly drove me insane, but I finally got this to work.


Here's what I did, for the archives, or in case anyone has any better suggestions.

1) Create temporary tree, and apply-templates in a "modified" mode:

<xsl:template match="/">
  <xsl:variable name="temp">
    <xsl:apply-templates mode="processed-bibrefs"/>
  </xsl:variable>
  <xsl:apply-templates select="$temp" mode="modified"/>
</xsl:template>

Because I needed to modify the document in the intermediate stage, and thus could not just rely on copy-of, I had templates like:

<xsl:template match="db:article" mode="processed-bibrefs">
  <article xmlns="http://docbook.org/docbook-ng";>
    <xsl:copy>
      <xsl:apply-templates mode="processed-bibrefs"/>
    </xsl:copy>
  </article>
</xsl:template>

<xsl:template match="db:section" mode="processed-bibrefs">
  <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="db:bibliography" mode="processed-bibrefs">
<bibliography xmlns="http://docbook.org/docbook-ng";>
<xsl:apply-templates select="mods:modsCollection" mode="processed-bibrefs"/>
</bibliography>
</xsl:template>


2) The "modified" mode is applied only once to create the entire modified document tree, like so:

<xsl:template match="db:article" mode="modified">
<html xmlns="http://www.w3.org/1999/xhtml";>
<head>
<style type="text/css">
body { font-family: georgia, sans; font-size: 11px; line-height: 15px;}
#content { width: 500px; position: center; margin: auto; margin-top: 40px; }
a { text-decoration: none; color: black; }
a:hover { background: #F3FCC0; }
</style>
</head>
<body>
<div id="content">
<xsl:apply-templates/>
</div>
</body>
</html>
</xsl:template>


3) Finally, I use a "bibliography" mode:

<xsl:template match="db:bibliography">
<div id="bibliography" xmlns="http://www.w3.org/1999/xhtml";>
<h3>References</h3>
<xsl:apply-templates select="mods:modsCollection" mode="bibliography"/>
</div>
</xsl:template>


4) The namespace issue: I just added declarations everywhere!

One remaining problem is how to collapse (Doe, 1999a; Doe, 1999c) into (Doe, 1999a, c). Remindr, in DocBook NG, citations now look like:

<citation>
   <biblioref linkend="one"/>
   <biblioref linkend="two"/>
</citation>

Clearly the problem is something about the if test flagged below. I would have thought the position in the current group would get me what I want, but it doesn't. If I remove the [...] on the bibref variable select statement, however, I can get the collapsing to work, but I get all of the document citations.

<xsl:template match="db:biblioref">
<xsl:variable name="idref" select="@linkend"/>
<xsl:variable name="bibref" select="//mods:mods[@ID=$idref]"/>
<xsl:for-each-group select="$bibref" group-by="bib:grouping-key(.)">
<xsl:sort select="current-grouping-key()"/>
<xsl:for-each-group select="current-group()"
group-by="xs:integer(mods:year)">
<xsl:sort select="current-grouping-key()"/>
<xsl:for-each select="current-group()">
<a href="#{@ID}" xmlns="http://www.w3.org/1999/xhtml";>
<!-- |||||||||| -->
<!-- PROBLEM: need to collapse like (Doe, 1999a, c), but this won't work. -->
<xsl:if test="../mods:mods[position() = 1]">
<!-- |||||||||| -->
<xsl:apply-templates select="mods:name" mode="citation"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="mods:year"/>
</xsl:if>
<!-- mods:key is the suffix -->
<xsl:apply-templates select="mods:key"/>
<xsl:if test="position() != last()">, </xsl:if>
</a>
</xsl:for-each>
</xsl:for-each-group>
</xsl:for-each-group>
<xsl:if test="position() != last()">; </xsl:if>
</xsl:template>


Anyway, I posted an archive here in case anyone's further interested:

http://www.users.muohio.edu/darcusb/files/cite.tar.gz

Bruce

Current Thread