|
Subject: RE: [xsl] XSLT2: Clustering, or Grouping the groups From: "Michael Kay" <mhk@xxxxxxxxx> Date: Tue, 25 May 2004 08:16:29 +0100 |
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)">
<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>
> -----Original Message-----
> From: A. Pagaltzis [mailto:pagaltzis@xxxxxx]
> Sent: 24 May 2004 22:52
> To: XSLT-List
> Subject: [xsl] XSLT2: Clustering, or Grouping the groups
>
> Hi all,
>
> I am using XSLT2 as implemented by Saxon 7.9.1 to group a flat
> structure. What I start out with is something like
>
> <foo>
> <bar baz="1" />
> <bar baz="2" />
> <bar baz="2" />
> <bar />
> <bar baz="1" />
> <bar baz="1" />
> <bar />
> </foo>
>
> Now I need to put these bars in a list. The first step is easy
> enough (I'm only paraphrasing; excuse any syntax errors please):
>
> <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>
>
> Now what I get looks like this:
>
> <foo>
> <list-item>
> <bar baz="1" />
> </list-item>
> <list-item>
> <bar baz="2" />
> <bar baz="2" />
> </list-item>
> <bar />
> <list-item>
> <bar baz="1" />
> <bar baz="1" />
> </list-item>
> <bar />
> </foo>
>
> This is all well and good, but now I need to get to
>
> <foo>
> <list>
> <list-item>
> <bar baz="1" />
> </list-item>
> <list-item>
> <bar baz="2" />
> <bar baz="2" />
> </list-item>
> </list>
> <bar />
> <list>
> <list-item>
> <bar baz="1" />
> <bar baz="1" />
> </list-item>
> </list>
> <bar />
> </foo>
>
> The only way I've succeeded in doing this was by two separate
> stylesheets (where the second is pretty much a copy of the first,
> except for different conditions and element names), which is
> suboptimal.
>
> 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. 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.
Michael Kay
> group-adjacent="boolean(self::list-item)">
> <xsl:choose>
> <xsl:when test=" SOME-TEST-HERE() "> <!-- KEY BIT -->
> <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>
>
> Unfortunately, both what the context node is as well as the value
> of current-group() at the point of SOME-TEST-HERE() seem to defy
> all reason or reasonable expectation in such a way that I can't
> figure out how to get the desired result.
>
> Uh.. help?
>
> --
> Thanks muchly in advance,
> Aristotle
>
> "If you can't laugh at yourself, you don't take life
> seriously enough."
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] XSLT2: Clustering, or Groupin, A. Pagaltzis | Thread | Re: [xsl] XSLT2: Clustering, or Gro, A. Pagaltzis |
| RE: [xsl] Grouping into a table (fo, Daniel Joshua | Date | [xsl] Name of current XML doc..., Niclas Hedhman |
| Month |