RE: [xsl] sort to categories

Subject: RE: [xsl] sort to categories
From: "Markus Hanel" <markus.hanel@xxxxxx>
Date: Fri, 14 Jan 2005 11:31:32 +0100 (MET)
Hallo,
my recursive template to sort does not work fine. There is one problem to
test if there are following pers_data nodes which have some attribute in a
nodeset.
Is there a possiblity to ask with xpath: are there following-sibling nodes
named pers_data in a variable ?

<xsl:if
test="not(following-sibling::pers_data[document(./url/@path)/pers_data/*[name()=
$category] = $element])">

I would be happy if someone can give me help. The solution must be in xslt1.
Many thanks
Markus

<xsl:template match="node[attribute::type='interviewee']">
  <xsl:call-template name="take_category">
    <xsl:with-param name="pos_category" select="1" />
    <xsl:with-param name="nodeset" select="pers_data" />
  </xsl:call-template>
</xsl:template>

<xsl:template name="take_category">
<xsl:param name="pos_category" />
<xsl:param name="nodeset" />
<!-- how many categories are given -->
<xsl:param name="total_category" select="count(...)" />
<!-- take the first, second,.. category -->
<xsl:variable name="category" select="document(...)" />

  <xsl:if test="$pos_category &lt;= $total_category">
    <xsl:for-each select="$nodeset">
      <xsl:sort select="document(./url/@path)/pers_data/*[name()=$category]"
/>
<!-- take a element of the category -->
      <xsl:variable name="element"
select="document(./url/@path)/pers_data/*[name()=$category]" />

<!-- this if test does not work fine -->
      <xsl:if
test="not(following-sibling::pers_data[document(./url/@path)/pers_data/*[name()=$category]
= $element])">
<!-- #### -->

        <xsl:choose>
          <xsl:when test="$pos_category = $total_category">
            <xsl:call-template name="take_element">
              <xsl:with-param name="nodes"
select="$nodeset[document(./url/@path)/pers_data/*[name()=$category] =
$element]" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$element" /><br />
          </xsl:otherwise>
        </xsl:choose>
        <xsl:call-template name="take_category">
          <xsl:with-param name="pos_category" select="$pos_category + 1" />
          <xsl:with-param name="nodeset"
select="$nodeset[document(./url/@path)/pers_data/*[name()=$category] =
$element]" />
        </xsl:call-template>
      </xsl:if>
    </xsl:for-each>
  </xsl:if>
</xsl:template>

<xsl:template name="take_element">
<xsl:param name="nodes" />
  <xsl:for-each select="$nodes">
    <xsl:sort select="document(./url/@path)/pers_data/lastname" />
    <xsl:sort select="document(./url/@path)/pers_data/surname" />
    <i><xsl:value-of select="document(./url/@path)/pers_data/lastname"
/></i><br />
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

> 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>
> 

-- 
-----------------------------
Mag. Markus Hanel
Rottweilerstra_e 29
A-6460 IMST
0650 - 7847941
markus.hanel@xxxxxx
----------------------------

Current Thread