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

Re: [xsl] XSLT2: Clustering, or Grouping the groups


Subject: Re: [xsl] XSLT2: Clustering, or Grouping the groups
From: "A. Pagaltzis" <pagaltzis@xxxxxx>
Date: Tue, 25 May 2004 13:56:46 +0200

Hello Michael,

thanks for your help!

* Michael Kay <mhk@xxxxxxxxx> [2004-05-25 10:57]:
> I think that when you need to do two levels of grouping like
> this, it is usually easier to do it top-down: that is, do the
> outer level first. Doing it bottom-up as you are attempting
> also works, but it requires two passes over the data.
> 
> The top-down solution (untested) looks something like this:
> 
> <xsl:for-each-group select="bar" group-adjacent="exists(@baz)">

I did even think of that, but unfortunately my real grouping
condition for the inner lever is a @group-starting-with, and I
can't see a way to fold it into a @group-adjacent condition the
way you did here.

>   <xsl:choose>
>   <xsl:when test="exists(@baz)">
>     <list>
>       <xsl:for-each-group select="current-group() group-adjacent="@baz">
>          <list-item>
>             <xsl:copy-of select="current-group()" />
>          </list-item>
>       </xsl:for-each-group>
>     </list>
>   </xsl:when>
>   <xsl:otherwise>
>       <xsl:copy-of select="current-group()"/>
>   </xsl:otherwise>
>   </xsl:choose>
> </xsl:for-each-group>

> > I'd like to do this in a single step. I tried assigning the
> > output to a variable and processing it afterwards using
> > something like
> > 
> >     <xsl:variable name="list">
> >         <xsl:for-each-group select="bar" group-adjacent="@baz">
> >             <xsl:choose>
> >                 <xsl:when test="@baz">
> >                     <list-item>
> >                         <xsl:copy-of select="current-group()" />
> >                     </list-item>
> >                 </xsl:when>
> >                 <xsl:otherwise>
> >                     <xsl:copy-of select="current-group()" />
> >                 </xsl:otherwise>
> >             </xsl:choose>
> >         </xsl:for-each-group>
> >     </xsl:variable>
> >     <xsl:for-each-group select="$list" 
> 
> Your mistake here is that $list is a document node at the root
> of a temporary tree: it is a sequence of length one, so using
> it as the grouping population is not going to do much good.

Ah! So *that*'s what happened. I could see some pattern in what
current-group() returned, but I couldn't understand how it came
about.

Looks like I need to do a lot more reading before I get closer to
something like understanding what I'm doing, rather than my
current fumbling about blindly.

> You
> should either select the children of $list (which will include
> <list-item> and <baz> elements), or you should declare the
> variable as a sequence of elements, by writing <xsl:variable
> name="list" as="element()*">, in which case the document node
> will not be constructed.

Thanks, I'll give these a spin. Do you have any comment on which
one would be the better solution in the general case, or what
criteria I'd use to decide? Does it matter at all?

-- 
Regards,
Aristotle
 
"If you can't laugh at yourself, you don't take life seriously enough."


Current Thread