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

Re: Grouping and sorting using an unknown node name

Subject: Re: Grouping and sorting using an unknown node name
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Mon, 7 Oct 2002 22:12:40 -0700 (PDT)
xslt node name example
--- Trem Stamp wrote:
> Hi,
> 
> I have been looking on various sites for ideas on the best way to do
> some
> grouping/sorting, and I'm unsure of the best way to tackle it.
> I've looked at the xsl:key but am not sure that this is appropriate
> for
> what
> I'm doing.  The problem is that I have an unknown number of
> element readings with unknown names (see example below), which means
> I
> don't
> see how I can define an xsl:key.  For example, the readings
> below contain Cond,TP and Turb.  The xml to be styled will vary (ie.
> there
> may be less than these or more with names that cannot be known
> beforehand),
> although all elements will have a child node called <ordinate>.
> 
> What I need to be able to do is group by the reading type (in
> alphabetical
> order), and for each reading type values, they need to be in date
> order.
> 
> So for example the result would be:
> 
> Cond
> 1993-01-11         165
> 1993-02-10         154
> 
> TP
> 1993-01-11         0
> 1993-02-10         465
> 
> Turb
> 1993-01-11         0
> 1993-02-10         23
> 
> I'm thinking along the lines of finding out how many reading types
> there are
> per reading (ie. in this case 3), and then for each reading
> call a template which selects the first node of each reading which
> has
> an
> ordinate value and repeat till n. I don't know whether this is the
> way
> to go
> about this and still not sure of how to group by date in this
> instance.
> 
> Any advice would be much appreciated.
> 
> I'm using a Saxon windows binary processor
> 
> I have the following sample xml:
> 
> <Collection>
>  <Group>
>   <Reading>
>    <Date>1993-02-10</Date>
>    <SiteNumber>991001</SiteNumber>
>    <Cond>
>     <ordinate>154</ordinate>
>    </Cond>
>    <TP>
>     <ordinate>465</ordinate>
>    </TP>
>    <Turb>
>     <ordinate>23</ordinate>
>    </Turb>
>   </Reading>
>  </Group>
>  <Group>
>   <Reading>
>    <Date>1993-01-11</Date>
>    <SiteNumber>991001</SiteNumber>
>    <Cond>
>     <ordinate>165</ordinate>
>    </Cond>
>    <TP>
>     <ordinate>0</ordinate>
>    </TP>
>    <Turb>
>     <ordinate>0</ordinate>
>    </Turb>
>   </Reading>
>  </Group>
>  ................
> </Collection>
> 
> Thanks,
> 
> Trem

Hi Trem,

Here's a solution to this problem:

With your source xml:
--------------------
<Collection>
 <Group>
  <Reading>
   <Date>1993-02-10</Date>
   <SiteNumber>991001</SiteNumber>
   <Cond>
    <ordinate>154</ordinate>
   </Cond>
   <TP>
    <ordinate>465</ordinate>
   </TP>
   <Turb>
    <ordinate>23</ordinate>
   </Turb>
  </Reading>
 </Group>
 <Group>
  <Reading>
   <Date>1993-01-11</Date>
   <SiteNumber>991001</SiteNumber>
   <Cond>
    <ordinate>165</ordinate>
   </Cond>
   <TP>
    <ordinate>0</ordinate>
   </TP>
   <Turb>
    <ordinate>0</ordinate>
   </Turb>
  </Reading>
 </Group>
</Collection>


this tramsformation:
-------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:vendor="urn:schemas-microsoft-com:xslt">
  
  <xsl:output method="text"/>
  
  <xsl:key name="krByName" 
           match="Reading/*[not(self::Date or self::SiteNumber)]"
           use="name()"/>
           
  <xsl:key name="krbyDate" 
           match="Date"
           use="."/>
           
  <xsl:template match="/">
   <xsl:for-each select="/*/*/Reading/*[
                                      generate-id() 
                                     = 
                                      generate-id(key('krByName',
                                                      name()
                                                      )
                                                      [1]
                                                 )
                                      ]">
     <xsl:text>&#xA;</xsl:text>
     <xsl:value-of select="name()"/>
     
     <xsl:for-each 
       select="/*/*/Reading/Date[
                               generate-id() 
                              = 
                               generate-id(key('krbyDate',
                                                .
                                               )
                                                [1]
                                           )
                               ]
                                  /following-sibling::*
                                    [name() = name(current())]">
          <xsl:sort select="preceding-sibling::Date"/>
     
     <xsl:value-of select="concat('&#xA;', 
                                  preceding-sibling::Date, 
                                  '&#9;', 
                                  .)"/>
     
     </xsl:for-each>

     <xsl:text>&#xA;</xsl:text>

   </xsl:for-each>

  </xsl:template>
</xsl:stylesheet>

when applied produces exactly the wanted result:


Cond
1993-01-11	 165 
1993-02-10	 154 

TP
1993-01-11	 0 
1993-02-10	 465 

Turb
1993-01-11	 0 
1993-02-10	 23 


Hope this helped.



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.