【问题标题】:XSLT transformation for multiple font types多种字体类型的 XSLT 转换
【发布时间】:2014-05-11 19:54:40
【问题描述】:

我正在尝试从 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>

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

【问题讨论】:

  • 在开始编写代码之前,您能否解释一下转换背后的逻辑?您有一个包含 empty &lt;i/&gt; 元素和一些文本的跨度;为什么这会导致输出中的文本 inside&lt;i&gt; 元素?
  • 我解析了大的 .odt 文档。接收字体样式的最快方法是,每个 span 或 p 元素都附加新标签 或两者都

标签: html xml xslt


【解决方案1】:

除了 bi 元素之外,您还能拥有更多元素吗?可以使用通用解决方案来做到这一点,该解决方案为 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 元素除了文本之外仅包含您要嵌套的元素。

【讨论】:

  • 只有三个选项。看起来很有趣,我也会尝试这个选项。
【解决方案2】:

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

下面的样式表只使用模板进行转换(不需要for-each)。我假设您的 &lt;span&gt; 元素的内容是 text (不是混合内容):

<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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2015-06-27
    • 1970-01-01
    • 2017-11-17
    相关资源
    最近更新 更多