Q:

Finding following sibling of text node

I am trying to wrap all the text node in a <text> element, but facing challenge when encounter an inline elements (i, b, emphasis), that should be in same <text> node (in other words, it should be considered as text)... Please see input and desired output below:
(Note: I have to do this for specific inline elements only, hence kept it in param (it could be anything), for rest of the elements standard <text> rule should be applied. (Please see my xslt for details)
Input XML:
    <?xml version="1.0" encoding="utf-8"?>
    <root>
        <para>XML Translation is a format that's used to <emphasis>exchange <i>localisation</i></emphasis>data</para>
        <para>The process can now be reformulated with more detail as follows:<ul>
                <li>Text extraction <note>Separation of translatable text from layout data</note></li>
                <li>Pre-translation</li>
                <li>Translation</li>
                <li>Reverse conversion</li>
                <li>Translation memory improvement</li>
            </ul>above mentioned steps should <b>executed</b> sequentially</para>
    </root>

OutPut should be:
            <?xml version="1.0" encoding="utf-8"?>
            <root>
                    <para>
                            <text xid="d0t3">XML Translation is a format that's used to <g ctype="emphasis">exchange <g ctype="i">localisation</g></g>data </text>
                    </para>
                    <para>
                            <text xid="d0t10">The process can now be reformulated with more detail as follows:</text>
                            <ul>
                                    <li><text xid="d0t13">Text extraction <g ctype="note">Separation of translatable text from layout data</g></text></li>
                                    <li><text xid="d0t17">Pre-translation</text></li>
                                    <li><text xid="d0t19">Translation</text></li>
                                    <li><text xid="d0t21">Reverse conversion</text></li>
                                    <li><text xid="d0t23">Translation memory improvement</text></li>
                            </ul>
                            <text xid="d0t24">above mentioned steps should <g ctype="b">executed</g> sequentially</text>               
                    </para>
            </root>

I am trying something like this, but not able to achieve correct result:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="2.0">
        <xsl:strip-space elements="*"/>
        <xsl:param name="inlineElement" select="('emphasis', 'i', 'note', 'b')"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="text()">
            <text>
                <xsl:attribute name="xid">
                    <xsl:value-of select="generate-id()"/>
                </xsl:attribute>
               <xsl:value-of select="."/>
                <xsl:if test="following-sibling::node()[local-name()=$inlineElement]">
                    <g>
                    <xsl:apply-templates select="following-sibling::node()[local-name()=$inlineElement]/text()"/>
                    </g>
                </xsl:if>
            </text>
        </xsl:template>
    </xsl:stylesheet>

A:

I would use for-each-group group-adjacent:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="2.0">
        <xsl:strip-space elements="*"/>
        <xsl:output indent="yes"/>
        <xsl:param name="inlineElement" select="('emphasis', 'i', 'note', 'b')"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>

        <xsl:template match="*[not(local-name() = $inlineElement)]">
          <xsl:copy>
            <xsl:for-each-group select="node()" group-adjacent="boolean(self::text() | self::*[local-name() = $inlineElement])">
              <xsl:choose>
                <xsl:when test="current-grouping-key()">
                  <text xid="{generate-id(current-group()[self::text()][1])}">
                    <xsl:apply-templates select="current-group()"/>
                  </text>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each-group>
          </xsl:copy>
        </xsl:template>

        <xsl:template match="*[local-name() = $inlineElement]">
          <g ctype="{local-name()}">
            <xsl:apply-templates/>
          </g>
        </xsl:template>

    </xsl:stylesheet>

That way, with Saxon 9.5, I get
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <para>
      <text xid="d1t3">XML Translation is a format that's used to <g ctype="emphasis">exchange <g ctype="i">localisation</g>
         </g>data</text>
   </para>
   <para>
      <text xid="d1t10">The process can now be reformulated with more detail as follows:</text>
      <ul>
         <li>
            <text xid="d1t13">Text extraction <g ctype="note">Separation of translatable text from layout data</g>
            </text>
         </li>
         <li>
            <text xid="d1t17">Pre-translation</text>
         </li>
         <li>
            <text xid="d1t19">Translation</text>
         </li>
         <li>
            <text xid="d1t21">Reverse conversion</text>
         </li>
         <li>
            <text xid="d1t23">Translation memory improvement</text>
         </li>
      </ul>
      <text xid="d1t24">above mentioned steps should <g ctype="b">executed</g> sequentially</text>
   </para>
</root>

