I've got a bibliography in xml with an xslt stylesheet. I'm opening it
in Firefox. I'm sorting the bibliography by format (audio, text, etc),
then by topic (history, culture, etc.), then by author, which is where
it gets tricky. I'm sorting by individual author. Then for each
individual author I want works from that author alone, then works by
that author and one other author, then with two other authors, etc. This
last part of getting the works functions fine. The problem is with
getting the individual authors grouped by format and topic, and is
explained in a comment element in the xsl below.
Here's a simplified version of the xml bibliography:
<sources>
<source>
<sourceCode></sourceCode>
<date></date>
<title></title>
<authors>
<author>
<name></name>
</author>
</authors>
<topics>
<topic>
<name></name>
</topic>
</topics>
<formats>
<format></format>
</formats>
</source>
</sources>
Please notice that the <topics> structure allows for multiple values - a
work can be about both culture and history, and should be grouped under
both topics.
Here's a simplified version of the xsl (I don't claim it's optimized!):
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:key name = "topics" match = " contains " use = " . " />
<xsl:key name = "formats" match = " media / format " use = " . " />
<xsl:key name = "authorsByFormatAndTopic" match = " author / name "
use = " concat ( . , .. / .. / .. / media / format , .. / .. / .. /
topics / topic [1] / contains ) " />
<xsl:template match = "/" >
<xsl:for-each select = " sources / source / media / format [
count ( . | key ( 'formats' , . ) [ 1 ] ) = 1 ] " >
<xsl:sort select = " . " />
<xsl:variable name = "currentFormat" select = "." />
<xsl:value-of select = " $currentFormat " />
<xsl:for-each select = " // sources / source [ media /
format = $currentFormat ] / topics / topic / contains [ count ( . | key
( 'topics' , . ) [ 1 ] ) = 1 ] " >
<xsl:sort select = " . " />
<xsl:variable name = "currentTopic" select = "." />
<xsl:value-of select = " $currentTopic " />
<xsl:for-each select = " // authors / author / name [
count ( . | key ( 'authorsByFormatAndTopic' , concat ( . ,
$currentFormat , $currentTopic ) ) [ 1 ] ) = 1 ] " >
<!-- This for-each is where the problem occurs. I want each author name
for sources with a format matching $currentFormat and a topic matching
$currentTopic, but I only get a positive result when the FIRST topic
matches the variable. I can't get a key to check EACH of the topic
elements (and I assume the same would happen with format, if I had
multiple values for a source, which will surely be the case soon). So I
can't get rid of the duplicates when an author has more than one work
with the same format and topic, since it either doesn't find all the
desired results via the authorsByFormatAndTopic key (when the matching
topic happens not to be listed first in every case). -->
<xsl:sort select = " . " />
<xsl:variable name = "currentAuthor" select = "." />
<xsl:for-each select = " // sources / source [ media
/ format = $currentFormat and topics / topic / contains = $currentTopic
] / authors [ author [*] / name = $currentAuthor ] " >
<!-- everything works fine from this for-each on, so I cut its children
out -->
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Any ideas for getting the key to work, or some other way to deal with
this latest of grouping nightmares in xslt 1.0?