XSLT如何处理多个嵌套元素?

时间:2014-04-22 12:30:10

标签: xslt xslt-1.0

我想将带有特殊标记的纯文本转换为HTML格式的文本。

例如,

这是原始值

Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text.

原始值作为实际值(仅供参考)

   
Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text.

HTML格式我希望结果

Th<i>is is a <u>com<b>bina</b>tion</u></i> text.

我尝试使用下面的模板,但XSLT解析器无法对其进行解析。

<xsl:template name="decorateValue">
<xsl:param name="originalString" />

<xsl:variable name="preString" select="substring-before($originalString, '&lt;')" />
<xsl:variable name="postString" select="substring-after($originalString, '&lt;')" />

<xsl:value-of select="$preString" />

<xsl:variable name="tagName" select="substring-before($postString, '&gt;')" />

<xsl:choose>
    <xsl:when test="$tagName='bold'">
            <xsl:element name="b">
    </xsl:when>
    <xsl:when test="$tagName='/bold'">
            </xsl:element>
    </xsl:when>
    <xsl:when test="$tagName='italic'">
            <xsl:element name="i">
    </xsl:when>
    <xsl:when test="$tagName='/italic'">
            </xsl:element>
    </xsl:when>
    <xsl:when test="$tagName='under'">
            <xsl:element name="u">
    </xsl:when>
    <xsl:when test="$tagName='/under'">
            </xsl:element>
    </xsl:when>
</xsl:choose>

<xsl:call-template name="decorateValue">
    <xsl:with-param name="originalString" 
                    select="substring-after($postString, '&gt;')" />
</xsl:call-template>
</xsl:template>

有什么想法解决这个问题吗?

我会提前感激。

1 个答案:

答案 0 :(得分:0)

如果你能真正保留原文,你的生活会更容易。然后你可以改变
Th<italic>is is a <under>com<bold>bina</bold>tion</under></italic> text.很容易进入xHTML

<xsl:template match="italic">
    <xsl:element name="i">
         <xsl:apply-templates />
    </xsl:element>
</xsl:template>

您无法在示例中混合您的代码。你打开一个xsl:when并打开一个xsl:元素,然后关闭xsl:when。这不是有效的XML!

因此,如果您想使用编码字符串,您需要以下内容:

<xsl:template name="decorateValue">
    <xsl:param name="originalString" />

    <xsl:if test="$originalString!=''">

        <xsl:variable name="preString" select="substring-before($originalString, '&lt;')" />
        <xsl:variable name="postString" select="substring-after($originalString, '&lt;')" />
        <xsl:variable name="endString" select="'magic happens here!'" />

        <xsl:value-of select="$preString" />

        <xsl:variable name="tagName" select="substring-before($postString, '&gt;')" />
        <xsl:variable name="restString" select="'magic happens here!'" />

        <xsl:choose>
            <xsl:when test="$tagName='bold'">
                <xsl:element name="b">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
            <xsl:when test="$tagName='italic'">
                <xsl:element name="i">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
            <xsl:when test="$tagName='under'">
                <xsl:element name="u">
                    <xsl:call-template name="decorateValue">
                        <xsl:with-param name="originalString" 
                            select="$restString" />
                    </xsl:call-template>
                </xsl:element>
            </xsl:when>
        </xsl:choose>
        <xsl:value-of select="$endString" />
    </xsl:if>
</xsl:template>

您会看到'magic happens here'的2个地方。这是您需要应用前一个字符串和后一个字符串模式(在XSLT中是PITA)的位置。最好的解释可以在XSLT Cookbook中找到(并且您希望至少拥有XSLT 2.0。

希望指针有所帮助。你可能会考虑将模式分解为个体,所以你不要为了&gt;而钓鱼。单独,但完整的标签。您仍然需要使用前/后/后函数。