我正在尝试从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>
你知道如何修复我的代码吗?
答案 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>