xsl-list
[Top] [All Lists]

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

2004-08-17 13:01:51

On Aug 17, 2004, at 10:26 AM, Jeni Tennison wrote:

Since the current element is a <mods:mods> element,
the test is guaranteed to be true.

What you want is simply:

  <xsl:if test="position() = 1">
    ...
  </xsl:if>

This tests whether the current <mods:mods> element is the first within
the group of <mods:mods> elements that you're looking at.

For whatever reason, this doesn't work for me. I originally had that statement, but couldn't get it to work. That's why I ended up with the one I posted. Here's the template again (the key is declared at the top of the stylesheet, and also used in the bibliography mode):

<xsl:template match="db:biblioref">
  <xsl:variable name="idref" select="@linkend"/>
  <xsl:variable name="bibref" select="key('bibref', $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="position() = 1">
            <xsl:apply-templates select="mods:name" mode="citation"/>
            <xsl:text>, </xsl:text>
            <xsl:value-of select="mods:year"/>
          </xsl:if>
          <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>

Declare it like:

<xsl:key name="mods" match="mods:mods" use="@ID" />

and use it like:

  <xsl:variable name="bibref" select="key('mods', $idref)" />

Keys are much faster and neater than searching through the entire
document using a predicate.

I was wondering about using keys. Do you think it'd be better to do this the other way around, though, and have a key for all the biblioref/@linkend values (the actual docbook citations), and when I process the mods:mods records, call those? Wouldn't that ensure that only those records that contain a biblioref element with their ID linkend actually get processed? Of course, I may have multiple linkends for the same record ID.

A related question: is there anywhere else obvious I ought to be drawing on keys? For example, this business of creating conditional formatting using grouping (the Doe, 1999a, b stuff) is quite processing intensive (at least as I have it in my stylesheet). For both the bibliography and the citations, I have to group and sort (often multiple times), and then figure out how to format based on position in the group. Is there some smarter, less processing-intensive, way to do this using keys?

Bruce