|
Subject: Re: [xsl] Problem with grouping multi level nodes From: "James A. Robinson" <jimr@xxxxxxxxxxxxxxxxxxxxx> Date: Tue, 16 Mar 2004 22:29:49 -0800 |
> <name>Student 1</name>
> <classes>
> <class>
> <title>soccer</title>
> <category>sport</category>
> </class>
> <class>
> <title>football</title>
> <category>sport</category>
> </class>
So Student 1 has two class elements under classes, each of which
falls under category sport.
> <p>Student group by Category</p>
> <xsl:for-each select="/category[not(. = preceding::category)]">
> <p><xsl:value-of select="."/></p>
>
> <xsl:for-each select="key('categories',.)">
> <p><xsl:value-of select="../../name"/></p>
> </xsl:for-each>
>
> </xsl:for-each>
The inner for-each you specify selects all categories matching the current
category and then outputs the name. That means when category is 'sport',
Student 1 matches twice.
To solve the problem you posted, I found the techniques discussed in
http://www.jenitennison.com/xslt/grouping/index.html to be useful.
If you use the Muenchian technique discussed under that URL, you can
select the first occurance of each unique title, category, and class
with a unique title-category combination, and then apply templates to
the student/name element for each match:
<?xml version='1.0' encoding='ISO-8859-1'?>
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
version='1.0'>
<xsl:key name='title' match='title' use='.'/>
<xsl:key name='category' match='category' use='.'/>
<xsl:key name='class' match='class' use='concat(./title, " - ", ./category)'/>
<xsl:key name='by_title' match='student' use='./classes/class/title'/>
<xsl:key name='by_category' match='student' use='./classes/class/category'/>
<xsl:output method='text' indent='no'/>
<xsl:template match="students">
<xsl:text> Student group by title </xsl:text>
<xsl:apply-templates select='./student/classes/class/title
[generate-id(.)=generate-id(key("title", .))]'>
<xsl:sort select="."/>
</xsl:apply-templates>
<xsl:text> Student group by category </xsl:text>
<xsl:apply-templates select='./student/classes/class/category
[generate-id(.)=generate-id(key("category", .))]'>
<xsl:sort select="."/>
</xsl:apply-templates>
<xsl:text> Student group by title and category </xsl:text>
<xsl:apply-templates select='./student/classes/class
[generate-id(.)=generate-id(key("class", concat(./title, " - ", ./category)))]'>
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="title">
<xsl:value-of select='.'/>
<xsl:text> </xsl:text>
<xsl:apply-templates select='key("by_title", .)/name'>
<xsl:sort select='.'/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="category">
<xsl:value-of select='.'/>
<xsl:text> </xsl:text>
<xsl:apply-templates select='key("by_category", .)/name'>
<xsl:sort select='.'/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="class">
<xsl:variable name='title_category' select='concat(./title, " - ", ./category)'/>
<xsl:value-of select='$title_category'/>
<xsl:text> </xsl:text>
<xsl:apply-templates select='key("class", $title_category)/../../name'>
<xsl:sort select='.'/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match='name'>
<xsl:text>	</xsl:text>
<xsl:value-of select='.'/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Problem with grouping multi l, Nguyen, Mike (Contra | Thread | [xsl] Extracting CSS Class from STY, David Carver |
| Re: [xsl] XML -> RTF via XSL, Paul Tremblay | Date | RE: [xsl] xsl search engine, Jarno . Elovirta |
| Month |