Hello Marshal,
(see comments inline)
Marshal Linfoot wrote:
I've been looking thru this list and searching google for examples of
sorting and grouping in xsl. Just when I thought I had found an example
that worked, on closer examination it is missing one little piece and
now I'm completely baffled. I can't get it to sort on a second and third
element.
I'd appreciate any advice/suggestions/pointers...
xml example----------
<schedule>
<classes type="Basic">
<class>
<name>Class BBB</name>
<day>Sunday</day><dsort>7</dsort><dsort>7</dsort>
<time>2:30pm to 4:00pm</time><tsort>1430</tsort>
</class>
<class>
<name>Class AAA</name>
<day>Monday</day><dsort>1</dsort>
<time>7:30pm to 9:00pm</time><tsort>1930</tsort>
</class>
<class>
<name>Class BBB</name>
<day>Tuesday</day><dsort>2</dsort>
<time>7:30pm to 9:00pm</time><tsort>1930</tsort>
</class>
<class>
<name>Class AAA</name>
<day>Wednesday</day><dsort>3</dsort>
<time>5:00pm to 6:30pm</time><tsort>1700</tsort>
</class>
<class>
<name>Class BBB</name>
<day>Tuesday</day><dsort>2</dsort>
<time>11:00am to 12:30pm</time><tsort>1100</tsort>
</class>
</classes>
<classes type="Advanced">
<class>
<name>Class ZZZ</name>
<day>Sunday</day><dsort>7</dsort><dsort>7</dsort>
<time>2:30pm to 4:00pm</time><tsort>1430</tsort>
</class>
<class>
<name>Class XXX</name>
<day>Thursday</day><dsort>4</dsort>
<time>7:00pm to 9:00pm</time><tsort>1900</tsort>
</class>
<class>
<name>Class XXX</name>
<day>Tuesday</day><dsort>2</dsort>
<time>7:30pm to 9:00pm</time><tsort>1930</tsort>
</class>
</classes>
</schedule>
Desired Output-------------
Basic Classes:
Class AAA Monday 7:30pm to 9:00pm
Wednesday 5:00pm to 6:30pm
Class BBB Tuesday 11:00am to 12:30pm
Tuesday 7:30pm to 9:00pm
Sunday 2:30pm to 4:00pm
Advanced Classes:
Class XXX Tuesday 7:30pm to 9:00pm
Thursday 7:00pm to 9:00pm
Class ZZZ Sunday 2:30pm to 4:00pm
The following XSL groups them okay so I can add space between the groups
and remove the redundant class names, but it doesn't sort by day or time.
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<!--
Define a key for grouping classes by name.
-->
<xsl:key name="kName" match="class" use="name" />
<xsl:template match="schedule">
<xsl:apply-templates />
</xsl:template>
<!--
Match the classes and group by class name.
Sort by class name, day, time
-->
<xsl:template match="classes">
<h3><xsl:value-of select="@type"/></h3>
<xsl:choose>
<xsl:when test="@type = 'Basic'">
<p>
<xsl:text>Basic Classes:</xsl:text>
</p>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:text>Advanced Classes:</xsl:text>
</p>
</xsl:otherwise>
</xsl:choose>
<table>
<xsl:apply-templates select="class [generate-id() =
generate-id(key('kName',name))]" mode="distinct-start">
<xsl:sort select="name"/>
<xsl:sort select="dsort"/> <!-- seems to ignore this -->
<xsl:sort select="tsort"/> <!-- and this -->
these both sorts are in the wrong place. You are sorting the
"distinct-starters" by name. name is distinct, so they *are* sorted. Now
you try to sort (only the distinct-starters) by dsort and tsort, but
they are already sorted - so the last two sorts seem to have no effect.
Remove it from here.
</xsl:apply-templates>
</table>
</xsl:template>
<!--
Match the first class in the group.
Output all columns.
-->
<xsl:template match="class" mode="distinct-start">
<tr>
<td><xsl:apply-templates select="name"/></td>
<td><xsl:apply-templates select="day"/></td>
<td><xsl:apply-templates select="time"/></td>
</tr>
<xsl:apply-templates select="key('kName',name)">
and place them here!! Here you apply templates to all schedule
items/dates of this group.
<xsl:sort select="dsort"/>
<xsl:sort select="tsort"/>
</xsl:apply-templates>
</xsl:template>
<!--
Match the other classes in the group.
Output blank class name and other columns.
-->
<xsl:template match="class">
<xsl:if test="not(generate-id() = generate-id(key('kName',name)))">
<tr>
<td><xsl:text> </xsl:text></td>
<td><xsl:apply-templates select="day"/></td>
<td><xsl:apply-templates select="time"/></td>
</tr>
</xsl:if>
<xsl:if test="position() = last()">
<tr><td><xsl:text> </xsl:text></td></tr>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Thanks in advance for any ideas.
Regards,
Joerg
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list