我一直在反对用 HTML 元素替换 XSLT 字符,但无济于事,并且终其一生都无法弄清楚如何让 XSLT 用包含制表符的 span 元素替换制表符。
我在 XHTML 文档中拥有的是一个包含制表符的 pre 元素,我发现了一个 XSLT 字符串替换模板函数,我正在使用它来尝试用被 span 包围的制表符替换制表符:
<xsl:template match="xhtml:pre">
<xsl:element name="{local-name()}">
<xsl:variable name="BodyText"><span class="tabspan">	</span></xsl:variable>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="@*|node()"/>
<xsl:with-param name="search" select="'	'"/>
<xsl:with-param name="replace" select="$BodyText"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<!-- Replacement template function for XSLT 1.0 -->
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:param name="search"/>
<xsl:param name="replace"/>
<xsl:choose>
<xsl:when test="contains($text, $search)">
<xsl:variable name="replace-next">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-after($text, $search)"/>
<xsl:with-param name="search" select="$search"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat(substring-before($text, $search),$replace, $replace-next)"/>
</xsl:when>
<xsl:otherwise>
<span class="tabspan">
<xsl:value-of select="$text"/>
</span>
</xsl:otherwise>
</xsl:choose>
但是,无论我如何更改代码,输出中都缺少 span 元素(如果我尝试通过上面的 xsl:variable 分配它(,或者它没有正确转换表示尖括号的 XML 转义字符
>
<
尽管转换离奇
"
到引号。诚然,我很困惑,对 XSLT 1.0 了解不够。由于转换系统的限制,XSLT 2.0、3.0 和 EXSLT 不是一个选项。
考虑以下最小示例:
输入
<html xmlns="http://www.w3.org/1999/xhtml">
<head/>
<body>
<p>This is an example.</p>
<pre>Text before text in the middle text after</pre>
</body>
</html>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xhtml:pre">
<xsl:copy>
<xsl:call-template name="replace-tabs">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="replace-tabs">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, '	')">
<xsl:value-of select="substring-before($text, '	')"/>
<span class="tabspan">
<xsl:text>	</xsl:text>
</span>
<xsl:call-template name="replace-tabs">
<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>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head/>
<body>
<p>This is an example.</p>
<pre>Text before<span class="tabspan"> </span>text in the middle<span class="tabspan"> </span>text after</pre>
</body>
</html>
要使其更接近您的尝试,请执行以下操作:
<xsl:variable name="BodyText">
<span class="tabspan">
<xsl:text>	</xsl:text>
</span>
</xsl:variable>
<xsl:template match="xhtml:pre">
<xsl:copy>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="searchString" select="'	'"/>
<xsl:with-param name="replacement" select="$BodyText"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:param name="searchString"/>
<xsl:param name="replacement"/>
<xsl:choose>
<xsl:when test="contains($text, $searchString)">
<xsl:value-of select="substring-before($text, $searchString)"/>
<xsl:copy-of select="$replacement"/>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-after($text, $searchString)"/>
<xsl:with-param name="searchString" select="$searchString"/>
<xsl:with-param name="replacement" select="$replacement"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>