xsl-list
[Top] [All Lists]

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

2004-08-17 06:57:49
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[(_at_)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="#{(_at_)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