Re: [xsl] xsl:key, multiple conditions on sub elements

Subject: Re: [xsl] xsl:key, multiple conditions on sub elements
From: Patrick Warren <warr0120@xxxxxxx>
Date: Fri, 28 Oct 2005 18:37:12 -0500
Alright, I'm posting some dummy xml data with an xsl stylesheet. I've tested it in firefox 1.07, and reproduced my problem. I apologize for not doing so earlier. It would have been much simpler, and avoided my errors, if I had tested and posted a small sample like this.

I found another error in the very key I am asking about. Please notice in my previous posting that the 'contains' child of topic in the authorsByFormatAndTopic key should have been 'name'. The new stylesheet gets rid of that child altogether, but the same problem of accessing all children exists.

To see the problem I'm having, play with the 'authorsByFormatTopicAndAuthor' key.

If you have:

use = " concat ( .. / .. / .. / formats / format , .. / .. / .. / topics / topic , . ) "

or you have:

use = " concat ( .. / .. / .. / formats / format , .. / .. / .. / topics / topic [ 1 ] , . ) "

you get the same result - duplicate authors are eliminated only when the first topic in a source equals currentTopic. If instead you have:

use = " concat ( .. / .. / .. / formats / format , .. / .. / .. / topics / topic [ 2 ] , . ) "

you eliminate duplicates only if the second topic equals currentTopic.

This should be easily visible under the audio - culture and audio - texts headings right at the top in the ouput.

I can't see anyway to get this to work with a key, since you only select each matching node once, and I want it for each topic (which could be any number of times), but I have no idea how to get rid of all duplicates!


Here's the xml data:


<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="identify.xsl"?>

<sources>
<source>
<sourceCode>riggs_dictionary_1992</sourceCode>
<date>1992</date>
<title>Dakota-english dictionary, a</title>
<authors>
<author>
<name>Riggs, Stephen R.</name>
</author>
</authors> <topics>
<topic>words</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>ingham_dictionary_2001</sourceCode>
<date>2001</date>
<title>English-lakota dictionary</title>
<authors>
<author>
<name>Ingham, Bruce</name>
</author>
</authors> <topics>
<topic>words</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>x_iapiOaye_1871</sourceCode>
<date>1871-1939</date>
<title>Iapi oaye</title>
<authors>
<author>
<name>[various authors]</name>
</author>
</authors> <topics>
<topic>literature</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>riggs_wowapiWakan_1866</sourceCode>
<date>1866</date>
<title>Dakota wowapi wakan kin</title>
<authors>
<author>
<name>Riggs, Stephen R.</name>
</author>
</authors> <topics>
<topic>religion</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>riggs_wowapiWakan_1887</sourceCode>
<date>1887</date>
<title>Dakota wowapi wakan</title>
<authors>
<author>
<name>Riggs, Stephen R.</name>
</author>
<author>
<name>Williamson, Thomas S.</name>
</author>
</authors> <topics>
<topic>religion</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>laviolette_dakota_1991</sourceCode>
<date>1991</date>
<title>Dakota sioux in canada, the</title>
<authors>
<author>
<name>Laviolette, Gontran</name>
</author>
</authors> <topics>
<topic>history</topic>
<topic>culture</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>deloria_buffaloPeople_1994</sourceCode>
<date>1994</date>
<title>Ella Deloria's The Buffalo People</title>
<authors>
<author>
<name>Deloria, Ella C.</name>
</author>
<author>
<name>Rice, Julian</name>
</author>
</authors> <topics>
<topic>texts</topic>
<topic>culture</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>deloria_deerWomen_1992</sourceCode>
<date>1992</date>
<title>Deer women and elk men</title>
<authors>
<author>
<name>Deloria, Ella C.</name>
</author>
<author>
<name>Rice, Julian</name>
</author>
</authors> <topics>
<topic>texts</topic>
<topic>culture</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>deloria_ironHawk_1993</sourceCode>
<date>1993</date>
<title>Ella Deloria's Iron Hawk</title>
<authors>
<author>
<name>Deloria, Ella C.</name>
</author>
<author>
<name>Rice, Julian</name>
</author>
</authors> <topics>
<topic>texts</topic>
<topic>culture</topic>
</topics>
<formats>
<format>text</format>
</formats>
</source>
<source>
<sourceCode>deloria_ironHawk_1993</sourceCode>
<date>1993</date>
<title>Ella Deloria's Iron Hawk</title>
<authors>
<author>
<name>Deloria, Ella C.</name>
</author>
<author>
<name>Rice, Julian</name>
</author>
</authors> <topics>
<topic>texts</topic>
<topic>culture</topic>
</topics>
<formats>
<format>audio</format>
</formats>
</source>
<source>
<sourceCode>deloria_ironHawk_1993</sourceCode>
<date>1993</date>
<title>Ella Deloria's Iron Hawk on CD</title>
<authors>
<author>
<name>Deloria, Ella C.</name>
</author>
<author>
<name>Rice, Julian</name>
</author>
</authors> <topics>
<topic>texts</topic>
<topic>culture</topic>
</topics>
<formats>
<format>audio</format>
</formats>
</source>


</sources>


And here's the xsl stylesheet:


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; >


   <xsl:key
           name = "formats"
           match = " format "
           use = " . "

/>

   <xsl:key
           name = "topicsByFormatAndTopic"
           match = " topic "
           use = " concat (  .. / .. / formats / format , . ) "

/>

<xsl:key
name = "authorsByFormatTopicAndAuthor"
match = " author / name "
use = " concat ( .. / .. / .. / formats / format , .. / .. / .. / topics / topic , . ) "


/>

<xsl:template match = "/" >

<html>

<xsl:for-each select = " sources / source / formats / format [ count ( . | key ( 'formats' , . ) [ 1 ] ) = 1 ] " >

               <xsl:sort select = " . " />
               <xsl:variable name = "currentFormat" select = " . " />

               <xsl:value-of select = " $currentFormat " />
               <xsl:text>&#x00BB;</xsl:text>
               <br />

<xsl:for-each select = "// sources / source [ formats / format = $currentFormat ] / topics / topic [ count ( . | key ( 'topicsByFormatAndTopic' , concat ( $currentFormat , . ) ) [ 1 ] ) = 1 ] " >

                   <xsl:sort select = " . " />
                   <xsl:variable name = "currentTopic" select = " . " />

                   <xsl:text>-----</xsl:text>
                   <xsl:value-of select = " $currentTopic " />
                   <xsl:text>&#x00BB;</xsl:text>
                   <br />

<xsl:for-each select = " // sources / source [ formats / format = $currentFormat and topics / topic = $currentTopic ] / authors / author / name [ count ( . | key ( 'authorsByFormatTopicAndAuthor' , concat ( $currentFormat, $currentTopic , . ) ) [ 1 ] ) = 1 ] " >
<xsl:sort select = " . " />
<xsl:variable name = "currentAuthor" select = "." />
<xsl:text>----------</xsl:text>
<xsl:value-of select = " $currentAuthor " />
<xsl:text>&#x00BB;</xsl:text>
<br />


<xsl:for-each select = " // sources / source [ formats / format = $currentFormat and topics / topic = $currentTopic and authors / author / name = $currentAuthor ] " >

<xsl:text>---------------</xsl:text>
<xsl:value-of select = " date " />
<xsl:text>_____</xsl:text>
<xsl:if test = " count ( authors / author [ name != $currentAuthor ] ) &gt; 0 " >
<xsl:text>with </xsl:text>
<xsl:value-of select = " authors / author / name [. != $currentAuthor ] " />
</xsl:if>
<xsl:text>_____</xsl:text>
<xsl:value-of select = " title " />
<xsl:text>.</xsl:text>
<br />


</xsl:for-each>

</xsl:for-each>

</xsl:for-each>

</xsl:for-each>

</html>

</xsl:template>

</xsl:stylesheet>

Current Thread