多种字体类型的XSLT转换

时间:2014-05-11 19:54:41

标签: html xml xslt

我正在尝试从XML进行XSLT转换,我想将字体样式标记转换为HTML标记,但是我做错了。 我的XML文件就像这样:

<root>
    <p>
        <span>
            <i/>
                italic
        </span>
        <span>
            <i/>
            <b/>
                bold-italic
        </span>
        <span>
                normal
        </span>
    </p>
</root>

我想要的是具有相同标签的HTML,但我的XSLT转换不起作用: HTML:

<p>
    <i>italic</i> 
    <i><b>bold-italic</b></i> 
    normal
<p>

我正在尝试xsl:if条件但它不起作用,我不知道我做错了什么: XSLT:

<xsl:template match="p">
    <p>
         <xsl:for-each select="span">
             <xsl:if test="i">
                    <i>
                    <xsl:value-of select="."/> 
                    </i>  
                </xsl:if>
                <xsl:if test="b">
                    <b>
                    <xsl:value-of select="."/> 
                    </b>  
                </xsl:if>
            </xsl:for-each> 
    </p>
</xsl:template>

你知道如何修复我的代码吗?

2 个答案:

答案 0 :(得分:3)

你能拥有的不仅仅是 b i 元素吗?可以使用通用解决方案来执行此操作,该解决方案为 span 元素的每个子元素创建嵌套元素。

此解决方案使用与 span 匹配的递归模板,但参数包含需要输出的子元素的索引号。当此索引超过子元素数时,将输出文本。

尝试这个XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="span">
        <xsl:param name="num" select="1"/>
        <xsl:variable name="childElement" select="*[$num]"/>
        <xsl:choose>
            <xsl:when test="$childElement">
                <xsl:element name="{local-name($childElement)}">
                    <xsl:apply-templates select=".">
                        <xsl:with-param name="num" select="$num + 1"/>
                    </xsl:apply-templates>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

除了文本之外,这确实假设所有span元素仅包含要嵌套的元素。

答案 1 :(得分:1)

您可以使用带有谓词的XPath表达式测试span元素的内容,该谓词用于测试其内容,并为每种情况匹配不同的模板。由于b需要i bold-italic,因此您应该在其中一个谓词中使用该表达式。

下面的样式表仅使用模板进行转换(无需for-each)。我假设您的<span>元素的内容是文字(不是混合内容):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:strip-space elements="*"/>

    <xsl:template match="p">
        <p><xsl:apply-templates/></p>
    </xsl:template>

    <xsl:template match="span[i]">
        <i><xsl:value-of select="."/></i>
    </xsl:template>

    <xsl:template match="span[b]">
        <b><xsl:value-of select="."/></b>
    </xsl:template>

    <xsl:template match="span[i and b]">
        <i><b><xsl:value-of select="."/></b></i>
    </xsl:template>

</xsl:stylesheet>