Subject: Re: [xsl] how to make a group-by multiple attributes motionless From: "Geert Bormans geert@xxxxxxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Thu, 26 Sep 2019 13:35:07 -0000 |
Thank you Michael, the copy-of() used this way makes perfect sense. Works like a charm now, thanks a lot Met vriendelijke groeten, Best regards, Geert Bormans Van: "Abel Braaksma, (Exselt) abel@xxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Aan: "xsl-list" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Verzonden: Donderdag 26 september 2019 00:55:50 Onderwerp: Re: [xsl] how to make a group-by multiple attributes motionless This code passes Saxon's streamability tests: <xsl:stylesheet version = "3.0" xmlns:xs = " [ http://www.w3.org/2001/XMLSchema | http://www.w3.org/2001/XMLSchema ] " xmlns:xsl = " [ http://www.w3.org/1999/XSL/Transform | 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 [ mailto:geert@xxxxxxxxxxxxxxxxxxx | geert@xxxxxxxxxxxxxxxxxxx ] < [ mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx | 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 [ http://www.mulberrytech.com/xsl/xsl-list | XSL-List info and archive ] [ http://lists.mulberrytech.com/unsub/xsl-list/293509 | EasyUnsubscribe ] ( [ https://mail.telenet.be/zimbra/mail?client=advanced | by email ] ) [ http://www.mulberrytech.com/xsl/xsl-list | XSL-List info and archive ] [ http://lists.mulberrytech.com/unsub/xsl-list/554170 | EasyUnsubscribe ] ( [ | by email ] )
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] how to make a group-by mu, Michael Kay mike@xxx | Thread | Aw: [xsl] how to make a group-by mu, Martin Honnen martin |
Re: [xsl] how to make a group-by mu, Michael Kay mike@xxx | Date | [xsl] XSL | index-of(), Janine Lantzsch lode |
Month |