Обработка строк не является сильной стороной XSLT - это язык обработки XML, в конце концов, не язык общего назначения.
Ваша проблема может быть решена с помощью рекурсии, однако:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="eee">
<fff>
<xsl:call-template name="process">
<xsl:with-param name="text" select="text()" />
</xsl:call-template>
</fff>
</xsl:template>
<xsl:template name="process">
<xsl:param name="text" select="''" />
<xsl:variable name="head" select="substring-before($text, '[')" />
<xsl:variable name="tag" select="substring-before(substring-after($text, '['), ']')" />
<xsl:variable name="tail" select="substring-after($text, ']')" />
<xsl:choose>
<xsl:when test="$head != '' and $tag != ''">
<xsl:value-of select="$head" />
<ggg name="{$tag}" />
<!-- recursive step: process the remainder of the string -->
<xsl:call-template name="process">
<xsl:with-param name="text" select="$tail" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Приведенные выше шаблоны вывода, для вашего ввода:
<fff>XML ELEMENT VALUE
<ggg name="part"/>.HTML element value <ggg name="HTPART"/>.
HTML element value <ggg name="HTPART2"/>.
</fff>