Re: [xsl] Is this a grouping task?

Subject: Re: [xsl] Is this a grouping task?
From: "Terry Badger terry_badger@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 24 Oct 2019 01:47:29 -0000
Rick,
This will solve your problem using xsl version 2 using 2 for-each-groups.

B  B  <?xml version="1.0" encoding="UTF-8"?>
<!-- Terry Badger 2019-10-23 -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema"; exclude-result-prefixes="xs"
B B B B version="2.0">
B B B B <xsl:template match="/root">
B B B B B B B B <xsl:copy>
B B B B B B B B B B B B <xsl:apply-templates/>
B B B B B B B B </xsl:copy>
B B B B </xsl:template>
B B B B <xsl:template match="topic">
B B B B B B B B <xsl:copy>
B B B B B B B B B B B B <xsl:copy-of select="@*"/>
B B B B B B B B B B B B <xsl:for-each-group select="*"
group-starting-with="revst">
B B B B B B B B B B B B B B B B <xsl:for-each-group select="current-group()"
group-ending-with="revend">
B B B B B B B B B B B B B B B B B B B B <xsl:choose>
B B B B B B B B B B B B B B B B B B B B B B B B <xsl:when
test="current-group()/self::*[name() = 'revst']">
B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:for-each
select="current-group()[name() != 'revst'][name() != 'revend']">
B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:copy>
B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:
attribute name="rev" select="'changed'"/>
B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:
value-of select="."/>
B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:copy>
B B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:for-each>
B B B B B B B B B B B B B B B B B B B B B B B B </xsl:when>
B B B B B B B B B B B B B B B B B B B B B B B B <xsl:otherwise>
B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:copy-of
select="current-group()"/>
B B B B B B B B B B B B B B B B B B B B B B B B </xsl:otherwise>
B B B B B B B B B B B B B B B B B B B B </xsl:choose>
B B B B B B B B B B B B B B B B </xsl:for-each-group>
B B B B B B B B B B B B </xsl:for-each-group>
B B B B B B B B </xsl:copy>
B B B B </xsl:template>
</xsl:stylesheet>


Terry






On Wednesday, October 23, 2019, 03:57:18 AM EDT, Martin Honnen
martin.honnen@xxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:





Am 22.10.2019 um 21:10 schrieb Martin Honnen martin.honnen@xxxxxx:
> On 22.10.2019 20:41, Martin Honnen martin.honnen@xxxxxx wrote:
>> On 22.10.2019 20:07, Rick Quatro rick@xxxxxxxxxxxxxx wrote:
>>
>>> I am using XSLT 2 and think this may require a for-each-group solution.
>>> Any advice would be appreciated. Thank you very much.
>>
> Thinking about it again, it seems in XSLT 3 simply using an accumulator
> makes it even more easy and compact:
>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> B B B  xmlns:xs="http://www.w3.org/2001/XMLSchema";
> B B B  exclude-result-prefixes="#all"
> B B B  version="3.0">
>
> B B B  <xsl:mode on-no-match="shallow-copy" streamable="yes"
> use-accumulators="rev-change"/>
>
> B B B  <xsl:accumulator name="rev-change" as="xs:boolean"
> initial-value="false()" streamable="yes">
> B B B B B B B  <xsl:accumulator-rule match="topic" select="false()"/>
> B B B B B B B  <xsl:accumulator-rule match="topic/revst" select="true()"/>
> B B B B B B B  <xsl:accumulator-rule match="topic/revend"
select="false()"/>
> B B B  </xsl:accumulator>
>
> B B B  <xsl:template match="topic/*[accumulator-before('rev-change')]">
> B B B B B B B  <xsl:copy>
> B B B B B B B B B B B  <xsl:attribute name="rev">changed</xsl:attribute>
> B B B B B B B B B B B  <xsl:apply-templates select="@*"/>
> B B B B B B B B B B B  <xsl:apply-templates/>
> B B B B B B B  </xsl:copy>
> B B B  </xsl:template>
>
> B B B  <xsl:template match="revst | revend" priority="2"/>
>
> </xsl:stylesheet>
>
> Saxon EE however doesn't like it for streaming and crashes


Michael Kay has already identified the problem with streaming in above
code, using

B B  <xsl:template
match="topic/*[boolean(accumulator-before('rev-change'))]">


fixes it.

Current Thread