Re: [xsl] xsl:for-each-group help needed !
2020-09-17 09:53:57
My goal wasn't to start a competition between best XSL coders ! I do not
have enough prices for awards !
But, indeed, this use case may occurs. But I've decided to let the
writer correct what he has done by hand.
To be honest, our editor can not generate such things... but writers may
modify generated files, and try to change width values...
Thanks again, based on Gerrit solution, I have now something that
correctly works.
Le 17/09/2020 à 16:26, Imsieke, Gerrit, le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de
a écrit :
Hi Martin,
Does your code handle this 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="i6a" width="80">content</block>
<block>content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
<block id="i9">content</block>
</blocks>
i6 and i6a, taken together, have a width of 105. I guess then i6a
needs to be on a new line.
I introduced an accumulator that can have two values:
<xsl:accumulator name="width" as="xs:integer+" initial-value="0">
<xsl:accumulator-rule match="blocks" select="0"/>
<xsl:accumulator-rule match="block"
select="let $line-width-so-far := $value[1],
$current-width := xs:integer((@width, 100)[1]),
$would-be-line-width := $line-width-so-far
+ $current-width
return (
if ($would-be-line-width gt 100)
then $current-width
else (),
$would-be-line-width
)"/>
</xsl:accumulator>
If the line becomes too long, the width of the current block will be
prepended to the would-be line length in the accumulator. So then
there is a sequence of "line length if line wrap happened before
current block" and "line length if line wrap did not happen before
current block".
If, on the other hand, the would-be line length is less than or equal
to 100, only a single value (the would-be line length) will go into
the accumulator.
I added its accumulator value(s) to each block:
<blocks>
<block id="i1" width="100" acc="100">content</block>
<block type="composite">
<block id="i2" width="33" acc="33 133">content</block>
<block id="i3" width="67" acc="100">content</block>
</block>
<block type="composite">
<block id="i4" width="50" acc="50 150">content</block>
<block id="i5" width="50" acc="100">content</block>
</block>
<block id="i6" width="25" acc="25 125">content</block>
<block id="i6a" width="80" acc="80 105">content</block>
<block width="100" acc="100 180">content</block>
<block type="composite">
<block id="i7" width="55" acc="55 155">content</block>
<block id="i8" width="20" acc="75">content</block>
</block>
<block id="i9" width="100" acc="100 175">content</block>
</blocks>
This has been achieved with a single grouping:
<xsl:template match="blocks">
<xsl:copy>
<xsl:for-each-group select="block"
group-starting-with="block[accumulator-before('width')[last()] gt 100]">
<xsl:choose>
<xsl:when test="count(current-group()) eq 1">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<block type="composite">
<xsl:apply-templates select="current-group()"/>
</block>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
Gerrit
On 17.09.2020 00:16, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de wrote:
I was wondering what output is wanted for
<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>content</block>
<block id="i7" width="55">content</block>
<block id="i8" width="20">content</block>
<block id="i9">content</block>
</blocks>
Neither my suggestion nor the above seem to only wrap the adjacent
block[@width] where the accumulator gives 100.
I complicated or strengthened my attempt as
<xsl:template match="blocks">
<xsl:copy>
<xsl:for-each-group select="block" group-adjacent="not(@width)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="current-group()"
group-ending-with="block[accumulator-before('width') eq 100]">
<xsl:choose>
<xsl:when
test="current-group()[last()][accumulator-before('width') eq 100]">
<block type="composite">
<xsl:apply-templates select="current-group()"/>
</block>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
--~----------------------------------------------------------------
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
--~--
<Prev in Thread] |
Current Thread |
[Next in Thread>
|
- [xsl] xsl:for-each-group help needed !, Christophe Marchand cmarchand(_at_)oxiane(_dot_)com
- Re: [xsl] xsl:for-each-group help needed !, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Imsieke, Gerrit, le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Imsieke, Gerrit, le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !,
Christophe Marchand cmarchand(_at_)oxiane(_dot_)com <=
- Re: [xsl] xsl:for-each-group help needed !, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Imsieke, Gerrit, le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Christophe Marchand cmarchand(_at_)oxiane(_dot_)com
- Re: [xsl] xsl:for-each-group help needed !, Imsieke, Gerrit, le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de
- Re: [xsl] xsl:for-each-group help needed !, Graydon graydon(_at_)marost(_dot_)ca
- Re: [xsl] xsl:for-each-group help needed !, Christophe Marchand cmarchand(_at_)oxiane(_dot_)com
Re: [xsl] xsl:for-each-group help needed !, Dimitre Novatchev dnovatchev(_at_)gmail(_dot_)com
|
|
|