[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Group and sort nodes by attribut in child node

Subject: Re: Group and sort nodes by attribut in child node
From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 14 Oct 2011 15:22:49 -0400
Re:  Group and sort nodes by attribut in child node
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, '&#10;')"/>
      </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, '&#10;')"/>
      <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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.