|
Subject: Re: [xsl] Excluding too much in nested for-each From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Wed, 21 Apr 2004 13:09:48 +0100 |
Hi Ragulf,
> I have nothing against key's if that is a solution, I have just
> never worked with key's in XSL, and is therefore not proficient in
> this, but if a solutions with key's is easier, then I will very much
> want to learn.
If I understand what you're doing correctly, the key-based (Muenchian)
method would look something like:
<xsl:key name="ElemsByDate"
match="Elem[@Type = '2' or @Type = '4']"
use="@Date" />
<xsl:key name="ElemsByDateAndID"
match="Elem[@Type = '2' or @Type = '4']"
use="concat(@Date, ':', ElemID)" />
<xsl:template match="/">
<output>
<!-- select unique Elems by Date -->
<xsl:for-each select="/root/Elements/Elem
[generate-id(key('ElemsByDate', @Date)[1]) =
generate-id(.)]">
<!-- sort by Date -->
<xsl:sort select="substring(@Date,$YearPos,4)" order="descending"/>
<xsl:sort select="substring(@Date,$MonthPos,2)" order="descending"/>
<xsl:sort select="substring(@Date,$DayPos,2)" order="descending"/>
<OutputByDate>
<Date><xsl:value-of select="@Date" /></Date>
<!-- select unique Elems by Date and ID -->
<xsl:for-each select="key('ElemsByDate', @Date)
[generate-id(key('ElemsByDateAndID',
concat(@Date, ':', ElemID))[1]) =
generate-id(.)]">
<OutputElem>
<ID><xsl:value-of select="ElemID" /></ID>
<xsl:for-each select="key('ElemsByDateAndID',
concat(@Date, ':', ElemID))">
<OutputElemSub>
<Type><xsl:value-of select="@Type" /></Type>
<Name><xsl:value-of select="Name" /></Name>
</OutputElemSub>
</xsl:for-each>
</OutputElem>
</xsl:for-each>
</OutputByDate>
</xsl:for-each>
</output>
</xsl:template>
Note that the keys do the filtering of the <Elem> elements so that the
groups only contain those whose Type is 2 or 4. You won't get a group
appearing if it only contains <Elem> elements whose Type is 1 or 3.
The XSLT 2.0 version is similar, but of course doesn't require keys,
and it might help you understand the logic of the XSLT 1.0 version
above:
<xsl:template match="/">
<output>
<xsl:for-each-group select="/root/Elements/Elem
[@Type = '2' or @Type = '4']"
group-by="@Date">
<xsl:sort select="substring(@Date,$YearPos,4)" order="descending"/>
<xsl:sort select="substring(@Date,$MonthPos,2)" order="descending"/>
<xsl:sort select="substring(@Date,$DayPos,2)" order="descending"/>
<OutputByDate>
<Date><xsl:value-of select="@Date" /></Date>
<xsl:for-each-group select="current-group()"
group-by="ElemID">
<OutputElem>
<ID><xsl:value-of select="ElemID" /></ID>
<xsl:for-each select="current-group()">
<OutputElemSub>
<Type><xsl:value-of select="@Type" /></Type>
<Name><xsl:value-of select="Name" /></Name>
</OutputElemSub>
</xsl:for-each>
</OutputElem>
</xsl:for-each-group>
</OutputByDate>
</xsl:for-each-group>
</output>
</xsl:template>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Excluding too much in nested , Ragulf Pickaxe | Thread | RE: [xsl] Excluding too much in nes, Ragulf Pickaxe |
| [xsl] xhtml -> docbook, Thomas Richter | Date | [xsl] Passing arrays as parameters, Michael L |
| Month |