Subject: Re: [xsl] Grouping and Sorting on value inside group From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Wed, 12 Jun 2002 19:33:57 +0100 |
Hi Peter, I'm new to the thread, so I'm sorry if this has been mentioned before, but I think that you can do: <!-- index the data by local name --> <xsl:key name="names" match="dataset/*/*" use="local-name()" /> <!-- index the data by id --> <xsl:key name="ids" match="dataset/*/*" use="@dataid" /> <!-- index the data by name and id --> <xsl:key name="names-and-ids" match="dataset/*/*/value" use="concat(local-name(), '+', @dataid)" /> and then: <!-- $sortcol holds the name of the column to sort by --> <xsl:variable name="sortcol" select="'data_x'" /> <!-- $data holds the data within the document --> <xsl:variable name="data" select="//dataset/*/*" /> <!-- $uniqueNames holds the first data elements with particular names --> <xsl:variable name="uniqueNames" select="$data[generate-id() = generate-id(key('names', local-name())[1])]" /> <!-- iterate over the data elements with unique ids --> <xsl:for-each select="$data[generate-id() = generate-id(key('ids', @dataid)[1])]"> <!-- sort them based on the value of the data element with the same id and the $sortcol element name --> <xsl:sort select="key('ids', @dataid)[local-name() = $sortcol][1]/value" /> <!-- $id holds the current id --> <xsl:variable name="id" select="@dataid" /> <!-- iterate over the $uniqueNames in alphabetical order --> <xsl:for-each select="$uniqueNames"> <xsl:sort select="local-name()" /> <!-- create an element of that name --> <xsl:element name="{local-name()}"> <!-- add a dataid attribute with the id --> <xsl:attribute name="dataid"> <xsl:value-of select="$id" /> </xsl:attribute> <!-- copy the value from the source data, if there is one --> <xsl:copy-of select="key('names-and-ids', concat(local-name(), '+', $id))" /> </xsl:element> </xsl:for-each> </xsl:for-each> --- In XSLT 2.0, you can do: <xsl:variable name="sortcol" select="'data_x'" /> <xsl:variable name="data" select="//dataset/*/*" /> <xsl:for-each-group select="$data" group-by="@dataid"> <xsl:sort select="current-group()[local-name() = $sortcol]/value" /> <xsl:variable name="id" select="@dataid" /> <xsl:variable name="sameID" select="current-group()" /> <xsl:for-each-group select="$data" group-by="local-name()"> <xsl:sort select="local-name()" /> <xsl:element name="{local-name()}"> <xsl:attribute name="dataid"> <xsl:value-of select="$id" /> </xsl:attribute> <xsl:copy-of select="$sameID[local-name() = local-name(current())]/value" /> </xsl:element> </xsl:for-each-group> </xsl:for-each-group> although it would probably be better to create a set of unique names as above, with something like: <xsl:variable name="sortcol" select="'data_x'" /> <xsl:variable name="data" select="//dataset/*/*" /> <xsl:variable name="uniqueNames" select="distinct-values(for $d in $data return local-name())" /> <xsl:for-each-group select="$data" group-by="@dataid"> <xsl:sort select="current-group()[local-name() = $sortcol]/value" /> <xsl:variable name="id" select="@dataid" /> <xsl:variable name="sameID" select="current-group()" /> <xsl:for-each select="$uniqueNames"> <xsl:sort select="." /> <xsl:element name="{.}"> <xsl:attribute name="dataid"> <xsl:value-of select="$id" /> </xsl:attribute> <xsl:copy-of select="$sameID[local-name() = current()]/value" /> </xsl:element> </xsl:for-each> </xsl:for-each-group> Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Grouping and Sorting on value, Hunsberger, Peter | Thread | Re: [xsl] Grouping and Sorting on v, Wendell Piez |
Re: [xsl] Grouping and Sorting on v, Jeni Tennison | Date | RE: [xsl] Grouping and Sorting on v, Hunsberger, Peter |
Month |