Другой способ выразить это в том, что вы хотите превратить все пары пробелов в два неразрывных пробела, табуляции в четыре неразрывных пробела и все разрывы строк в <br>
элементах. В XSLT 1.0 я бы сделал:
<xsl:template name="replace-spaces">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, ' ')"/>
</xsl:call-template>
<xsl:text>  </xsl:text>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($text, '	')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '	')"/>
</xsl:call-template>
<xsl:text>    </xsl:text>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '	')" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($text, '
')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '
')" />
</xsl:call-template>
<br />
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-after($text, '
')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Невозможность использовать хвостовую рекурсию - это немного больно, но это не должно быть реальной проблемой, если текст не очень длинный.
Решение XSLT 2.0 будет использовать <xsl:analyze-string>
.