Re: [xsl] xsl:for-each-group help needed !

Subject: Re: [xsl] xsl:for-each-group help needed !
From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Sep 2020 22:19:30 -0000
This seems shorter/simpler:

<xsl:stylesheet version="2.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform";>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[@width and not(preceding-sibling::*/@width)]">
    <xsl:for-each-group select=
         ". | following-sibling::*[not(@width)][1]/preceding-sibling::*
                                                     [. >> current()]"
group-adjacent="name()">
<xsl:variable name="vSegment" select="current-group()"/>
<xsl:for-each-group select="$vSegment"
group-starting-with="*[not(preceding-sibling::*[1]/@width)
                        or
                         sum((preceding-sibling::*
                                 [. >>
$vSegment[1]/preceding-sibling::*[1]])
                                                         /@width/number())
mod 100 eq 0]">
 <block type="composite"><xsl:copy-of select="current-group()"/></block>
</xsl:for-each-group>
    </xsl:for-each-group>
  </xsl:template>

  <xsl:template match="*[@width and preceding-sibling::*[@width]]"/>
</xsl:stylesheet>

When applied on the provided source XML document:

<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>


the wanted result is produced:


<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>

On Wed, Sep 16, 2020 at 2:19 PM Christophe Marchand cmarchand@xxxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> Hello all !
>
> A slide is divided as blocks. Usually, there is one bloc per line, but
> sometimes, two or more blocks can be on one line, if their width sum is
> 100.
>
> My input has non-grouped blocks, and I want my input group blocks per line.
>
> 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...
>
> Is a solution with two-pass where I first calculate cumulated width with
> an accumulator, followed a group-end-with="@cumulative-width eq 100"
> could be a correct solution ?
>
> Best,
> Christophe
> 
>


-- 
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
To achieve the impossible dream, try going to sleep.
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they write
all patents, too? :)
-------------------------------------
Sanity is madness put to good use.
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.

Current Thread