Hi Martin,
Thanks you for theses feedbacks.
You are right, the function could be more generic with any sequence of nodes
as param. I'm use to always perform adjacent grouping within a XML document
tree in a specific context, in document order. But it's true there might be
other usecases.
I set a new issue here :
https://github.com/ELSGestion/els-sie-xsl-lib/issues/17
Yes <xsl:copy select="$wrapper"> is quite more readable instead of this dummy
loop to change the context. I commited this refacto.
Liebe Gr|_e
Matthieu
-----Message d'origine-----
De : Martin Honnen martin.honnen@xxxxxx
[mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx]
Envoyi : mercredi 8 juillet 2020 11:36
@ : xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Objet : Re: XSLT3 generic grouping functions
Am 08.07.2020 um 11:24 schrieb Matthieu RICAUD-DUSSARGET
m.ricaud-dussarget@xxxxxxxxxxxxxxxxxx:
> Hi all,
>
> While teaching XSLT, someone ask if it was possible to have a kind of
> generic function to group XML elements.
>
> I first answer the only way to do it was to use (eventually nested)
> <xsl:for-each-group> instruction with specific conditions according to
> the data.
>
> Later, as I was discovering XSLT3, I realize the grouping condition
> might be sent as an higher-order-function parameter, which lead me to
> write some generic grouping functions to wrap XML elements (see
> example below).
>
> The original code can be found on github at
> https://github.com/ELSGestion/els-sie-xsl-lib/blob/master/src/main/xsl
> /els-common_xml.xsl
>
>
> There's also some generic xsl to nest titles
> (https://github.com/ELSGestion/els-sie-xsl-lib/blob/master/src/main/xs
> l/nest-titles.xsl) and a specific implementation of it to nest HTML
> titles
> (https://github.com/ELSGestion/els-sie-xsl-lib/blob/master/src/main/xs
> l/nest-html-titles.xsl)
>
> Working examples can be found in the test folder
> https://github.com/ELSGestion/els-sie-xsl-lib/tree/master/src/test, as
> xspec unit test or xspec driven integration tests.
>
> I actually have a bug with Saxon 9.9
> (https://saxonica.plan.io/issues/4636) on the generic starting-with
> grouping function, but this is an occasion to share theses grouping
> libraries J
>
> Any comments, feedbacks or similar code implementation are welcome !
>
> Cheers
>
> Matthieu Ricaud-Dussarget
>
> Example of generic adjacent grouping function used to define a
> specific "by-name grouping" implementation (there's a similar set of
> functions for starting-with) :
>
> <xd:doc>
>
> <xd:desc>
>
> <xd:p>Wrap adjacent elements into a new "wrapper" element</xd:p>
>
> <xd:p>CAUTION : any text, pi, comments within context will be
> loose</xd:p>
>
> </xd:desc>
>
> <xd:param name="context">Parent of the adjacent elements to
> wrap</xd:param>
>
> <xd:param name="adjacent.function">Xpath function to set the
> adjacency condition</xd:param>
>
> <xd:param name="wrapper">Element wrapper</xd:param>
>
> <xd:param name="keep-context">Say if the context should be kept or
> not in the result</xd:param>
>
> <xd:return>context (or its content) with wrapped adjacent
> element</xd:return>
>
> </xd:doc>
>
> <xsl:function name="els:wrap-elements-adjacent" as="node()*">
>
> <xsl:param name="context" as="element()"/>
>
> <xsl:param name="adjacent.function"/> <!--as="xs:string"-->
>
> <xsl:param name="wrapper" as="element()"/>
>
> <xsl:param name="keep-context" as="xs:boolean"/>
>
> <xsl:variable name="content" as="item()*">
>
> <xsl:for-each-group select="$context/*"
> group-adjacent="$adjacent.function(.)">
I would certainly prefer to write a "generic" function that expects a
parameter with the grouping population as a sequence of nodes and then use
<xsl:for-each-group select="$population" ...
I don't think for-each-group adjacent is meant to be used only for child
elements of a parent, if you want to use it in a generic way then provide a
population sequence you want to group.
>
> <xsl:choose>
>
> <xsl:when test="current-grouping-key()">
>
> <xsl:for-each select="$wrapper">
>
> <xsl:copy>
>
> <xsl:copy-of select="@*"/>
Doesn't
<xsl:copy select="$wrapper">
suffice in XSLT 3?
Why the xsl:for-each?
|