Subject: Re: [xsl] how to make a group-by multiple attributes motionless From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 25 Sep 2019 22:55:44 -0000 |
This code passes Saxon's streamability tests: <xsl:stylesheet version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:mode streamable="yes"/> <xsl:template match="/"> <out> <xsl:fork> <xsl:for-each-group select="/*/row" group-by="((@* => copy-of() => sort((), function($x){name($x)})) ! (name() || '=' || string(.))) => string-join(' ')"> <xsl:sequence select="current-group()"/> </xsl:for-each-group> </xsl:fork> </out> </xsl:template> </xsl:stylesheet> Note that the sort() function requires XPath 3.1 so its streamability analysis isn't covered in the XSLT 3.0 spec, but Saxon applies similar rules to functions such as fn:filter: if the first argument is grounded then the function is streamable. The key here is the use of copy-of() to copy the attributes before sorting; this enables the compiler to know that the sort function isn't going to do any non-streamable navigation starting at the attribute node. In fact, after sorting you could equally well call a user-defined function that sorts using xsl:perform-sort. Michael Kay Saxonica > On 25 Sep 2019, at 22:44, Geert Bormans geert@xxxxxxxxxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > All, > > I a streaming XSLT 3.0, I have to group a series of elements by their attribute names and values > I have issues making the group-by motionless > > In a simplified example > > <rows> > <row a="val-a-1" b="b-val"/> > <row a="val-a-2" b="b-val"/> > <row a="val-a-1" b="b-val"/> > <row a="val-a-2"/> > </rows> > > I need grouping this way > > <rowgroups> > <rowgroup hash="|a=val-a-1|b=b-val"/> > <rowgroup hash="|a=val-a-2|b=b-val"/> > <rowgroup hash="|a=val-a-2"/> > </rowgroups> > > easily achieved this way > > <xsl:fork> > <xsl:for-each-group select="*" group-by="string-join(@*/concat('|', name(), '=', .), '')"> > <rowgroup hash="{current-grouping-key()}"/> > </xsl:for-each-group> > </xsl:fork> > > but, I could have data like this (third line attribute order swapped) > > <rows> > <row a="val-a-1" b="b-val"/> > <row a="val-a-2" b="b-val"/> > <row b="b-val" a="val-a-1"/> > <row a="val-a-2"/> > </rows> > > and this basically gives me a fourth group using the code above > > So I want to make sure that the attributes order can be controlled when I prepare the group-by, but any sorting attempt I make, leads to the group-by no longer being motionless > > I would welcome your suggestions > > Thanks > > Met vriendelijke groeten, > Best regards, > > Geert Bormans > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/293509> (by email <>)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] how to make a group-by multip, Geert Bormans geert@ | Thread | Re: [xsl] how to make a group-by mu, Geert Bormans geert@ |
Aw: [xsl] how to make a group-by mu, Martin Honnen martin | Date | Re: [xsl] how to make a group-by mu, Geert Bormans geert@ |
Month |