xsl-list
[Top] [All Lists]

xsl:key only checks first child, need to check all

2005-10-27 18:05:59
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?

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--