[xsl] Sorting and Grouping Alphabetically: Two Levels

Subject: [xsl] Sorting and Grouping Alphabetically: Two Levels
From: <Trish@xxxxxxxxxxxxxx>
Date: Tue, 8 Jan 2008 10:37:27 -0500
Hi:

I want to sort first by Festival (descending years) and then by Artist
(ascending alpha) and then I want to group the sorted artists by letter
of the alphabet with a blank line between each group.

It will look like this:

2006
	alpha1
	alpha2

	beta1
	beta2

2005
	delta1
	delta2

	gamma


Here is my XML (the ID is the year):

<Events>
	<Festival id="2005">
		<Artist name="beta1">
			<Date></Date>
			<Stage></Stage>
		</Artist>
		<Artist name="alpha1">
			<Date></Date>
			<Stage></Stage>
		</Artist>
		<Artist name="beta2">
			<Date></Date>
			<Stage></Stage>
		</Artist>
		<Artist name="alpha2">
			<Date></Date>
			<Stage></Stage>
		</Artist>
	</Festival>
	<Festival id="2006">
		<Artist name="gamma">
			<Date></Date>
			<Stage></Stage>
		</Artist>
		<Artist name="delta2">
			<Date></Date>
			<Stage></Stage>
		</Artist>
		<Artist name="delta1">
			<Date></Date>
			<Stage></Stage>
		</Artist>
	</Festival>
</Events>

I've spent time reviewing sorting/grouping examples on the web
(particularly at this page):
http://www.dpawson.co.uk/xsl/sect2/N6280.html

I tried using Example 12 (Mukul Gandhi) which is something like what I
want to do, but it doesn't employ sorting. I've been trying to create a
unique ID based on a combination of the Festival id (year) and first
character of the Artist name, which is probably the wrong way to do
this. I've changed this about a million times so this is a bit sloppy:

<xsl:key name="Artists" match="Artist" use="concat(substring(@name,1,1),
../@id)" />
<xsl:template match="/">
<xsl:for-each select="Document/Events/Festival">
	<xsl:sort select="@id" data-type="number" order="descending" />
	<xsl:value-of select="@id" /><br />
	<xsl:for-each select="Artist">
		<xsl:if test="generate-id(.) =
generate-id(key('Artists',concat(substring(@name,1,1), ../@id))[1])">
			<xsl:for-each select="key('Artists',
concat(substring(@name,1,1), ../@id))">
				<xsl:sort select="@name"
data-type="text" order="ascending" />
				<xsl:value-of select="@name" /><br />
				<xsl:value-of select="Date" /><br />
				<xsl:value-of select="Stage" /><br />
				<xsl:if
test="generate-id(key('Artists',concat(substring(following-sibling::Arti
st[1]/@name, 1, 1), ../@id))[1]) !=
generate-id(key('Artists',concat(substring(@name,1,1), ../@id))[1])">
					<br />
				</xsl:if>
			</xsl:for-each>
		</xsl:if>
	</xsl:for-each>
</xsl:for-each>
</xsl:template>

Can someone recommend a really good tutorial on this? Thank you so much
for your help!
Trish

Current Thread