Subject: Re: [xsl] Group and sort nodes by attribut in child node From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx> Date: Fri, 14 Oct 2011 15:22:49 -0400 |
Here's a version of Martin's approach that works in XSLT 1.0. However, is this really a match for your requirements? I got the impression from your initial post that the goal was more like "group the records by their 'Group' value, putting each record with a null 'Group' in its own group, then sort the records by date within their group and sort the groups by the earliest date in the group". <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:key name="records" match="record" use="generate-id(.)"/> <xsl:template match="records"> <xsl:call-template name="group-records"> <xsl:with-param name="id-list"> <xsl:for-each select="record"> <xsl:sort select="concat(substring-after(substring-after(column[@field='Start_Date']/@v alue, '.'), '.'), substring-before(substring-after(column[@field='Start_Date']/@value, '.'), '.'), substring-before(column[@field='Start_Date']/@value, '.'))"/> <xsl:value-of select="generate-id(.)"/><xsl:text> </xsl:text> </xsl:for-each> </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template name="group-records"> <xsl:param name="id-list" select="''"/> <xsl:param name="last" select="''"/> <xsl:if test="$id-list"> <xsl:variable name="record" select="key('records', substring-before($id-list, ' '))"/> <xsl:variable name="group" select="string($record/column[@field='Group']/@value)"/> <xsl:if test="$group and $group != $last"> <xsl:value-of select="concat($group, ' ')"/> </xsl:if> <xsl:if test="$group"><xsl:text> </xsl:text></xsl:if> <xsl:value-of select="concat($record/column[@field='keyword']/@value, ' - ', $record/column[@field='Start_Date']/@value, ' ')"/> <xsl:call-template name="group-records"> <xsl:with-param name="id-list" select="substring-after($id-list, ' ')"/> <xsl:with-param name="last" select="$group"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> -Brandon :) On Fri, Oct 14, 2011 at 11:21 AM, Jens Burkhardt <JensBurkhardt@xxxxxx> wrote: > Wow. Thanks for the quick reply. First of all, sorry for not telling that i have to use XSLT 1.0. I knew i forgot something. The result your style sheet produces meets my requirement > perfectly but i need it, as I said for XSLT 1.0. > Nodes where the group value is empty should not be in the same group so what you did is perfect. Is there any way to do this for xslt 1.0? > > Thank you. > > Jens > >>Martin Honnen wrote: >>> Jens Burkhardt wrote: >>> >>>> The result should be like this: >>>> A - 23.10.2010 >>>> X_Group >>>> C - 23.10.2010 >>>> B - 24.12.2010 >>>> D - 25.10.2010 >>>> Y_Group >>>> D - 25.12.2010 >>>> E - 26.12.2010 >>>> >>>> I want to group by the value of the group field in the column node and >>>> everything should be sorted by start_date. The name of the group (e.g. >>>> X_Group) should start a group-block, followed by the record nodes >>>> which belong to the group value. >>>> Another problem is that i don4t know the group value in advance, >>>> because they can be set to whatever the user want. >>> >>> Do you use XSLT 2.0 or 1.0? >>> And what about the record with keyword value "A" and the one with >>> keyword value "D" where the group value is an empty string? Shouldn't >>> they be in the same group? >> >>Here is an XSLT 2.0 stylesheet that sorts first and the groups adjacent >>records in the sorted sequence: >> >><xsl:stylesheet >> xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >> xmlns:xs="http://www.w3.org/2001/XMLSchema" >> exclude-result-prefixes="xs" >> version="2.0"> >> >> <xsl:output method="text"/> >> >> <xsl:template match="records"> >> <xsl:variable name="sorted" as="element(record)*"> >> <xsl:perform-sort select="record"> >> <xsl:sort select="xs:date(concat(substring(column[@field = >>'Start_Date']/@value, 7), '-', >> substring(column[@field = >>'Start_Date']/@value, 4, 2), '-', >> substring(column[@field = >>'Start_Date']/@value, 1, 2)))"/> >> </xsl:perform-sort> >> </xsl:variable> >> <xsl:for-each-group select="$sorted" group-adjacent="column[@field >>= 'Group']/@value"> >> <xsl:choose> >> <xsl:when test="current-grouping-key()"> >> <xsl:value-of select="current-grouping-key()"/> >> <xsl:text> </xsl:text> >> <xsl:value-of select="current-group()/concat(' ', >>column[@field = 'keyword']/@value, ' - ', column[@field = >>'Start_Date']/@value)" >> separator=" "/> >> <xsl:text> </xsl:text> >> </xsl:when> >> <xsl:otherwise> >> <xsl:value-of select="current-group()/concat(column[@field = >>'keyword']/@value, ' - ', column[@field = 'Start_Date']/@value)"/> >> <xsl:text> </xsl:text> >> </xsl:otherwise> >> </xsl:choose> >> </xsl:for-each-group> >> </xsl:template> >> >></xsl:stylesheet> >> >>With that stylesheet Saxon 9.3 HE, when applying it to the input >> >><records> >><record> >> <column field="keyword" value="A"></column> >> <column field="Start_Date" value="23.12.2010"></column> >> <column field="Group" value=""></column> >></record> >><record> >> <column field="keyword" value="B"></column> >> <column field="Start_Date" value="24.12.2010"></column> >> <column field="Group" value="X_Group"></column> >></record> >><record> >> <column field="keyword" value="D"></column> >> <column field="Start_Date" value="25.12.2010"></column> >> <column field="Group" value=""></column> >></record> >><record> >> <column field="keyword" value="C"></column> >> <column field="Start_Date" value="23.12.2010"></column> >> <column field="Group" value="X_Group"></column> >></record> >><record> >> <column field="keyword" value="D"></column> >> <column field="Start_Date" value="25.12.2010"></column> >> <column field="Group" value="Y_Group"></column> >></record> >><record> >> <column field="keyword" value="E"></column> >> <column field="Start_Date" value="26.12.2010"></column> >> <column field="Group" value="Y_Group"></column> >></record> >></records> >> >>outputs >> >>A - 23.12.2010 >>X_Group >> C - 23.12.2010 >> B - 24.12.2010 >>D - 25.12.2010 >>Y_Group >> D - 25.12.2010 >> E - 26.12.2010 >> >> >>Does that solution meet your requirement? > > > > ___________________________________________________________ > SMS schreiben mit WEB.DE FreeMail - einfach, schnell und > kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Group and sort nodes by a, Martin Honnen | Thread | Re: [xsl] Group and sort nodes by a, Jens Burkhardt |
Re: [xsl] Group and sort nodes by a, Martin Honnen | Date | [no subject], Unknown |
Month |