Thanks a lot, Martin, Gerrit, Dimitre, Graydon ! I now need half a day
to understand all your solutions, translate them to my real data
structure, and choose the clearest one !
Thanks again,
Christophe
Le 17/09/2020 à 00:47, Graydon graydon(_at_)marost(_dot_)ca a écrit :
On 16.09.2020 23:19, Christophe Marchand cmarchand(_at_)oxiane(_dot_)com wrote:
[group the blocks]
Here is a sample input :
<blocks>
<block id="i1">content</block>
<block id="i2" width="33">content</block>
<block id="i3" width="67">content</block>
<block id="i4" width="50">content</block>
<block id="i5" width="50">content</block>
<block id="i6" width="25">content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
<block id="i9">content</block>
</blocks>
Here is the expected output :
<blocks>
<block id="i1">content</block>
<block type="composite">
<block id="i2" width="33">content</block>
<block id="i3" width="67">content</block>
</block>
<block type="composite">
<block id="i4" width="50">content</block>
<block id="i5" width="50">content</block>
</block>
<block type="composite">
<block id="i6" width="25">content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
</block>
<block id="i9">content</block>
</blocks>
I have no idea of which form of for-each-group I have to use...
It's not as short as I hoped, but a two-pass approach can avoid an
accumulator:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="xs math xd" version="3.0"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xd:doc scope="stylesheet">
<xd:desc>
<xd:p><xd:b>Created on:</xd:b> Sep 16, 2020</xd:p>
<xd:p><xd:b>Author:</xd:b> graydon</xd:p>
<xd:p />
</xd:desc>
</xd:doc>
<xsl:mode name="numbers" on-no-match="shallow-copy" />
<xsl:mode name="group" on-no-match="shallow-copy" />
<xsl:variable as="element(blocks)" name="input">
<blocks>
<block id="i1">content</block>
<block id="i2" width="33">content</block>
<block id="i3" width="67">content</block>
<block id="i4" width="50">content</block>
<block id="i5" width="50">content</block>
<block id="i6" width="25">content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
<block id="i9">content</block>
</blocks>
</xsl:variable>
<xd:doc>
<xd:desc>main template</xd:desc>
</xd:doc>
<xsl:template name="xsl:initial-template">
<xsl:variable name="pass1">
<xsl:apply-templates mode="numbers" select="$input" />
</xsl:variable>
<xsl:apply-templates mode="group" select="$pass1" />
</xsl:template>
<xd:doc>
<xd:desc>add numbers to the blocks</xd:desc>
</xd:doc>
<xsl:template match="block" mode="numbers">
<xsl:copy>
<xsl:apply-templates mode="numbers" select="@*" />
<xsl:if test="@width">
<xsl:attribute name="count" select="(preceding-sibling::block/@width => sum())
mod 100" />
</xsl:if>
<xsl:apply-templates mode="numbers" select="node()" />
</xsl:copy>
</xsl:template>
<xd:doc>
<xd:desc>do the grouping</xd:desc>
</xd:doc>
<xsl:template match="blocks" mode="group">
<xsl:copy>
<xsl:apply-templates mode="group" select="@*" />
<xsl:for-each-group group-starting-with="block[@count/number() lt
preceding-sibling::block[1]/@count/number()]"
select="*">
<xsl:for-each-group group-adjacent="(self::block[exists(@count)], false())[1]"
select="current-group()">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<block type="composite">
<xsl:apply-templates mode="group" select="current-group()" />
</block>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="group" select="current-group()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xd:doc>
<xd:desc>remove count attributes</xd:desc>
</xd:doc>
<xsl:template match="@count" mode="group">
<!-- thud -->
</xsl:template>
</xsl:stylesheet>
produces:
<?xml version="1.0" encoding="UTF-8"?>
<blocks>
<block id="i1">content</block>
<block type="composite">
<block id="i2" width="33">content</block>
<block id="i3" width="67">content</block>
</block>
<block type="composite">
<block id="i4" width="50">content</block>
<block id="i5" width="50">content</block>
</block>
<block type="composite">
<block id="i6" width="25">content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
</block>
<block id="i9">content</block>
</blocks>
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--