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 |