XSLT 1.0 将制表符替换为包含制表符的 HTML 元素



我一直在反对用 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">&#x9;</span></xsl:variable>
            <xsl:call-template name="replace">
                <xsl:with-param name="text" select="@*|node()"/>
                <xsl:with-param name="search" select="'&#x9;'"/>
                <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 转义字符

&gt;
&lt;

尽管转换离奇

&quot;

到引号。诚然,我很困惑,对 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, '&#9;')">
            <xsl:value-of select="substring-before($text, '&#9;')"/>
            <span class="tabspan">
                <xsl:text>&#9;</xsl:text>
            </span>
            <xsl:call-template name="replace-tabs">
                <xsl:with-param name="text" select="substring-after($text, '&#9;')"/>
            </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>&#9;</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="'&#9;'"/>
            <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>

相关内容

  • 没有找到相关文章

最新更新