HI Mike,
Thank you sincerely for the answer. If I could risk a follow up, working that code into a template and adding a xsl:choose for debugging, in my case I think I have to apply-templates to non-matching groups rather than copy the current-group() (to traverse the xml).
There are 2 problems with the output
a) the xml output - I expected that my comparison function (which has been made a little more complex) would only return true for i elements, but seems to return true for bird and cow, because they are all merged into one in the result xml
b) the comparison function is trying to manage the case of a more dynamic attribute comparison value (@s is not always 'b' but could be 'b i' etc), therefore it is looking at its neighbours before returning a boolean, but why isnt it simply a matter of stating group-adjacent=self::i/@s (ie group the i elements that have the same value in their @s), which would be the behaviour of 'group-by' I think? I get an error if I try that approach.
If you have time for an answer, its appreciated, in any event thanks for the pointers thus far.
XML/XSLT pasted below.
XSLT
Code:
<xsl:stylesheet
xmlns:f="http://whetever"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- return true if previous or next node is an 'i' and has the same value for @s-->
<xsl:function name="f:isMerged" as="xs:boolean">
<xsl:param name="e" as="node()"/>
<xsl:sequence select="$e/self::i[@s = preceding-sibling::*[1][self::i]/@s] or $e/self::i[@s = following-sibling::*[1][self::i]/@s]"/>
</xsl:function>
<xsl:function name="f:merge" as="node()*">
<xsl:param name="e" as="node()*"/>
<inline style="b"><xsl:value-of select="$e/string()" separator=""/></inline>
</xsl:function>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:copy-of select="text()" />
<xsl:for-each-group select="*" group-adjacent="boolean(*[f:isMerged(.)])">
<!--<xsl:sequence select="if (boolean(f:isMerged(.))) then f:merge(current-group()) else current-group()"/>-->
<xsl:choose>
<!-- current-grouping-key() should be true only for i elements, but bird and cow are in this group -->
<xsl:when test="current-grouping-key()">
<xsl:sequence select="f:merge(current-group())" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Sample XML
Code:
<code>
<section>
<p>text</p>
<section>
<i s='b'>join me</i>
<i s='b'>to me</i>
<bird>bird</bird>
<cow>cow</cow>
</section>
<para>
<dog/>
<cat/>
<bird/>
<sub-para>
<cat>cat</cat>
<bird/>
</sub-para>
</para>
</section>
</code>