[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] sort to categories


Subject: RE: [xsl] sort to categories
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 16 Dec 2004 10:06:45 -0000

I solved exactly this same problem for a client recently (in a real
application involving financial reporting up an organization hierarchy).
It's a tricky one, but the final solution is remarkably concise, at least in
XSLT 2.0.

To give you a sketch of the solution: there is a recursive named template
that takes as input a set of elements and a level number: the template calls
xsl:for-each-group to do one level of grouping, calling a function to
calculate the grouping key for level N; within the for-each-group it then
makes a recursive call-template to group the elements in current-group() at
level N+1. The function that calculates the grouping key for level N reads
the Nth XPath expression from a configuration file, and calls
saxon:evaluate() to evaluate it.

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Markus Hanel [mailto:markus.hanel@xxxxxx] 
> Sent: 16 December 2004 08:57
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] sort to categories
> 
> hello,
> 
> can anyone give my an idea to solve the following problem:
> I want to sort some students to the categories: division and 
> group; but the
> categories should be flexible and expandable;
> at an other time for example school, division and group; they 
> should be
> given in a separat xml file;
> the output should be in the following way:
> division1
>   group1
>     hauser monika
>     wilhelm arno
>   group2
>     maier martin
> 
> division2
>   group1
>     jonak gert
>     walch stefan
>   ...
> 
> I have managed it with one fixed category, but now i have no ideas!
> many thanks,
> markus
> 
> xml file
> <node label="interviewees" status="active" type="interviewee">
>   <pers_data id="2" status="active" task="interviewee">
>     <url path="/quirxi/qpers_data/2.xml" proto="file"/>
>   </pers_data>
>   <pers_data id="3" status="active" task="interviewee">
>     <url path="/quirxi/qpers_data/3.xml" proto="file"/>
>   </pers_data>
>   <pers_data id="4" status="active" task="interviewee">
>     <url path="/quirxi/qpers_data/4.xml" proto="file"/>
>   </pers_data>
>   ...
> </node>
> 
> the pers_data files look like
> <pers_data task="interviewee" id="4" status="active">
> <surname>Martin</surname>
> <lastname>Maierunteregger</lastname>
> <group>group1</group>
> <division>Innenausbau</division>
> <school>htl imst</school>
> <userid>c</userid>
> <pass>c</pass>
> <sex>m</sex>
> </pers_data>
> 
> stylesheet
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:variable name="mod_admin"
> select="document('../qxml/a_format_default.xml')/format/modul[
> attribute::label
> = 'interviewer']/files/file[attribute::name = 
> 'qier_group_take_iees']" />
> 
> <xsl:template match="/">
> <html>
> <head><title></title>
> </head>
> <body>
>   <xsl:apply-templates
> select="./node[attribute::type='interviewee']/pers_data[attrib
> ute::status =
> 'active']" />
> </body>
> </html>
> </xsl:template>
> 
> <xsl:template match="pers_data">
> <xsl:variable name="take_category" 
> select="$mod_admin/param[attribute::label
> = 'body']/shows/show[position() = last()]" />
> <xsl:variable name="select_category"
> select="document(./url/@path)/pers_data/*[name()=$take_category]" />
>   <xsl:if
> test="not(following-sibling::pers_data[document(./url/@path)/p
> ers_data/*[name()=$take_category]
> = $select_category)">
>         <xsl:apply-templates
> select="../descendant::pers_data[document(./url/@path)/pers_da
> ta/group =
> $select_category]" mode="take">
>           <xsl:sort 
> select="document(./url/@path)/pers_data/lastname" />
>           <xsl:sort 
> select="document(./url/@path)/pers_data/surname" />
>         </xsl:apply-templates>
>     </xsl:if>
> </xsl:choose>
> </xsl:template>
> 
> <xsl:template match="pers_data" mode="take">
> <div>
>   &#160;&#160;&#160;&#160;&#160;
>   <xsl:value-of select="document(./url/@path)/pers_data/lastname" />
> </div>
> </xsl:template>
> </xsl:stylesheet>


Current Thread
Keywords