[Top] [All Lists]

Re: [xsl] group-starting-with and ending with

2020-03-06 01:31:06
Hi Byomokesh,

What are the rules for grouping?

Adjacent <bb> elements, including text in between, should be grouped in <st>?

What about the other elements, <x>, <cc>, and <dd>, should they also be surrounded by something if they occur multiple times?

I didn't apply your stylesheet yet, but the group-adjacent will probably have no tangible effect since if there are adjacent text(), x, cc, or dd nodes, they will be reproduced. This applies in particular to the text node ', ' between the bb elements. You will see the effect more clearly when you wrap the adjacent groups in an element, for example z:

<xsl:when test="current-grouping-key()">
    <xsl:copy-of select="current-group()"/>

Then suddenly many nodes, including the text between the bb elements, will be wrapped in a <z> element.

If you only want to wrap <bb> and interstitial text, you can use group adjacent="exists(self::bb | self::text()[following-sibling::*[1]/self::bb][preceding-sibling::*[1]/self::bb])", and if current-grouping-key() is true(), you surround the group with <st>, otherwise you reproduce the currrent-group().

Please note that group-adjacent and group-by expect an atomic grouping key. This has been (accidentally?) achieved in your template by using "self::text() or self::x or self::dd or self::cc". The 'or' operator forces each side to be cast to a boolean, which is equivalent to "exists(self::text()) or exists(self::x) or exists(self::dd) or exists(self::cc)". If there is only one or no node supplied to the group-adjacent expression such as "self::bb | self::text()[…]", it might throw an error when the node is empty. Please note that | (or union) ist not the same as 'or' in that it doesn’t force cast to boolean. Therefore I recommend to wrap the union expression in an exists(), as I did above. Learning the difference between 'or' and '|' (which is a synonym for 'union') is helpful. And also learning that group-starting-with and group-ending-with expect matching patterns while group-by and group-adjacent expect atomic values is helpful if one wants to know why something works and why not.


On 06.03.2020 07:47, Byomokesh Sahoo sahoo(_dot_)byomokesh(_at_)gmail(_dot_)com 

Is it any possibility to <st> start and end tag in <bb>Test1</bb>, <bb>Test2</bb>.

Here is my XML

<a><x>To</x> Test, <bb>Test1</bb>, <bb>Test2</bb>, <cc>Test3</cc>, <dd>USA</dd></a>

Desired Output

<a><x>To</x> Test, <st><bb>Test1</bb>, <bb>Test2</bb></st>, <cc>Test3</cc>, <dd>USA</dd></a>


<xsl:template match="a">
<xsl:element name="{local-name()}">
<xsl:for-each-group select="node()" group-adjacent="self::text() or self::x or self::dd or self::cc">
<xsl:when test="current-grouping-key()">
<xsl:copy-of select="current-group()"/>
<xsl:for-each-group select="*" group-starting-with="self::bb">
<xsl:for-each select="current-group()">
<xsl:copy-of select="current-group()"/>
<xsl:copy-of select="current-group()"/>
<xsl:copy-of select="current-group()"/>


XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/225679> (by email <>)

Gerrit Imsieke
Geschäftsführer / Managing Director
le-tex publishing services GmbH
Weissenfelser Str. 84, 04229 Leipzig, Germany
Phone +49 341 355356 110, Fax +49 341 355356 510
gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

Geschäftsführer / Managing Directors:
Gerrit Imsieke, Svea Jelonek, Thomas Schmidt
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>