Простой рекурсивный именованный шаблон должен сделать трюк:
<xsl:template name="wordsInTags">
<xsl:param name="text"
select="."/>
<xsl:param name="index"
select="1"/>
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<span class="word-{$index}">
<xsl:value-of select="substring-before($text, ' ')"/>
</span>
<xsl:text> </xsl:text>
<xsl:call-template name="wordsInTags">
<xsl:with-param name="text">
<xsl:value-of select="substring-after($text, ' ')"/>
</xsl:with-param>
<xsl:with-param name="index">
<xsl:value-of select="$index + 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<span class="word-{$index}">
<xsl:value-of select="$text"/>
</span>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
И затем просто вызвать его для элемента, в который нужно обернуть слова:
<xsl:template match="p">
<p>
<xsl:call-template name="wordsInTags"/>
</p>
</xsl:template>
Бросилвместе очень быстро, так что может потребоваться дополнительная работа, но это должно помочь вам начать.