[xsl] Re: Grouping headers revisted

Subject: [xsl] Re: Grouping headers revisted
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 31 Aug 2001 08:12:20 -0700 (PDT)
Jeroen Janssen wrote:

> Unfortunately my problem has turned out to be a bit more complex
> than I previously thought. I've tried to work out a solution myself, but
> it's a bit too complicated for my (limited) knowledge of xsl.
> 
> I have two parameters in my xsl 'discipline' and 'subdiscipline' and I have
> the following xml:
> 
> <country name="The Netherlands">
>     <institutions>
>         <institution>
>             <name>School of pretentious art</name>
>             <city>Amsterdam</city>
>             <disciplines>
>                 <discipline name="music">
>                     <subdiscipline name="rock"/>
>                     <subdiscipline name="free jazz"/>
>                 </discipline>
>             </disciplines>
>         </institution>
>         
>         <institution>
>             <name>Dendermalsen School of things</name>
>             <city>Dendermalsen</city>
>             <disciplines>
>                 <discipline name="theatre" shortname="theatre">
>                     <subdiscipline name="mime"/>
>                 </discipline>
>             
>                 <discipline name="music">
>                     <subdiscipline name="rock"/>
>                     <subdiscipline name="free jazz"/>
>                 </discipline>
>             </disciplines>
>         </institution>
>         
>         <institution>
>             <name>School of music</name>
>             <city>Amsterdam</city>
>             <disciplines>
>                 <discipline name="music">
>                     <subdiscipline name="rock"/>
>                     <subdiscipline name="free jazz"/>
>                 </discipline>
>             </disciplines>
>         </institution>
>         
>         
>         <institution>
>             <name>School van artistieke dingen</name>
>             <city>Amsterdam</city>
>             
>             <disciplines>
>                 <discipline name="music">
>                     <subdiscipline name="rock"/>
>                 </discipline>
>                 
>                 <discipline name="theatre">
>                     <subdiscipline name="mime"/>
>                     <subdiscipline name="drama"/>
>                 </discipline>
>             </disciplines>
>         </institution>
>     </institutions>
> </country>
> 
> I want to generate a list based on the parameters, so if I have param
> 'discipline' = music and param 'subsdiscipline' = free jazz I want to show
> only the institutions that offer not only music, but only free jazz music,
> so in this particular case 3 institutions will be shown. These parameters
> are optional by the way, so one could also select just 'music'.
> 
> The thing that makes it more complicated is that I also want to group the
> resulting institutions by city, so the previous example would result in:
> 
> Amsterdam
>     School of pretentious art
>     School of music
>     
> Dendermalsen
>     Dendermalsen School of things


Actually, it is not so complicated as it seems -- here's the stylesheet, which when
applied on the source xml document as specified above, produces exactly the desired
result:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output method="text"/>
  
  <xsl:key name="kCity" 
           match="city" use="."/>

  <xsl:key name="kSubDiscipline" match="subdiscipline" 
           use="concat(../@name, ':', @name)" />
                       
  <xsl:param name="pDiscipline" select="'music'"/>
  <xsl:param name="pSubDiscipline" select="'free jazz'"/>
  
  <xsl:variable name="resultInstitutions" 
                select="key('kSubDiscipline',
                             concat($pDiscipline, 
                                    ':', 
                                    $pSubDiscipline
                                    )
                              )/../../.."/>
  
  <xsl:template match="/">
    <xsl:for-each select="$resultInstitutions/city
                        [ generate-id() 
                        = generate-id(key('kCity', .)[1])
                        ]">
    <xsl:value-of select="concat(., '&#xA;')"/>
      <xsl:for-each select="$resultInstitutions[city = current()]">
        <xsl:value-of select="concat('   ', name, '&#xA;')"/>
      </xsl:for-each>
    </xsl:for-each>

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

Hope this helped.

Cheers,
Dimitre Novatchev.

__________________________________________________
Do You Yahoo!?
Get email alerts & NEW webcam video instant messaging with Yahoo! Messenger
http://im.yahoo.com

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


Current Thread