[xsl] grouping and context (?)

Subject: [xsl] grouping and context (?)
From: Bruce D'Arcus <bdarcus@xxxxxxxxxxxxx>
Date: Fri, 27 Aug 2004 10:45:54 -0400
To be honest, I wasn't even sure what to title this, but I'm stuck on a grouping-related problem. It seems related to the problem that Dave P earlier posted, but sufficiently different that I can't figure out to apply the solution here.

SOURCE:

<citation><biblioref linkend="doe99a" units="page" begin="1" end="2"/></citation>

When I process the citations, I run a multi-level grouping operation on the biblioref elements by using a key to access the records that they point to (mods:mods) to get the author names and years. So, multiple biblioref elements get sorted by author and year.

PROBLEM:

I don't know how to get back to the biblioref elements to process the attributes there, which get appended to the end of the citation, like (Doe, 1999: 1-2). I thought I hit on the clever idea to use a key, but this turns out not to work, as I am not accessing only the specific biblioref element I need (in other words, using the key every reference to doe99a now gets the same begin and end page numbers!).

Here's the template, incorporating the number range solution Jeni proposed (which I'll expand later):

<xsl:key name="citekey" match="db:biblioref" use="@linkend" />
<!-- author-year class processing -->
<xsl:template match="db:citation[$citation-class='author-year']">
  <xsl:variable name="idref" select="db:biblioref/@linkend"/>
<!-- use a key to access mods records based on lindend value -->
  <xsl:variable name="bibref" select="key('bibref', $idref)" />
  <xsl:value-of select="$citation-before"/>
<!-- group and sort by authors-string -->
  <xsl:for-each-group select="$bibref" group-by="bib:grouping-key(.)">
    <xsl:sort select="current-grouping-key()"/>
<!-- within an authors group, sort by year -->
    <xsl:for-each-group select="current-group()"
			group-by="mods:year">
      <xsl:sort select="current-grouping-key()"/>
      <xsl:for-each select="current-group()">
<!-- since we're now working with the mods source, the only way
I can see to get back to the biblioref code is to use a key again;
unfortunately doesn't work correctly ** -->
	<xsl:variable name="citekey" select="key('citekey', @ID)" />
	<a href="#{@ID}">
	  <xsl:if test="position() = 1">
	    <xsl:choose>
	      <xsl:when test="mods:name">
		<xsl:apply-templates select="mods:name" mode="citation"/>
	      </xsl:when>
	      <xsl:otherwise>
		<xsl:value-of select="mods:noname-substitute"/>
	      </xsl:otherwise>
	    </xsl:choose>
	    <xsl:text>, </xsl:text>
	    <xsl:value-of select="mods:year"/>
	  </xsl:if>
<!-- apply suffix if applicable -->
	  <xsl:apply-templates select="mods:key"/>
<!-- render point citation details if present -->
	  <xsl:if test="$citekey/@begin">
	    <xsl:value-of select="$point-cite-before"/>
             <xsl:value-of select="@begin" />
             <xsl:text>-</xsl:text>
             <xsl:choose>
               <xsl:when test="string-length(@begin) = 1">
                 <xsl:value-of select="@end" />
               </xsl:when>
               <xsl:when test="string-length(@begin) = 2">
                 <xsl:value-of select="substring(@end, 2, 1)" />
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="substring(@end, last() - 1)" />
              </xsl:otherwise>
            </xsl:choose>
	  <xsl:if test="position() != last()">, </xsl:if>
	</a>
      </xsl:for-each>
    </xsl:for-each-group>
    <xsl:if test="position() != last()">; </xsl:if>
  </xsl:for-each-group>
  <xsl:value-of select="$citation-after"/>
</xsl:template>

Current Thread