我有一些包含样式跨度的HTML:
<p><span class="foo">unstyled span</span></p>
<p><span style="font-style: italic;">italic</span></p>
<p><span style="font-weight: bold; font-style: italic;">bold italic</span></p>
<p><span style="text-decoration: underline; font-style: italic; font-weight: bold;">underline italic bold</span></p>
Spans也用于设置字体和背景颜色以及更多内容。基本上我必须用span
,em
等替换strong
标签,尽可能保留一些样式并删除其他所有内容(不需要的样式和类)。对于上述输入,所需的输出为:
<p>unstyled span</p>
<p><em>italic</em></p>
<p><em><strong>bold italic</strong></em></p>
<p><em><strong><span style="text-decoration: underline;">underline italic bold</span></strong></em></p>
凭借我非常有限的XSLT技能,我能够编写以下转换来完成工作,但看起来很难看:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:template match="span">
<xsl:call-template name="startStyleTests" select="." />
</xsl:template>
<xsl:template name="startStyleTests">
<xsl:call-template name="testItalic" select="." />
</xsl:template>
<xsl:template name="testItalic">
<xsl:choose>
<xsl:when test="contains(./@style, 'italic')">
<xsl:element name="em"><xsl:call-template name="testBold" select="." /></xsl:element>
</xsl:when>
<xsl:otherwise><xsl:call-template name="testBold" select="." /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="testBold">
<xsl:choose>
<xsl:when test="contains(./@style, 'bold')">
<xsl:element name="strong"><xsl:call-template name="testUnderline" select="." /></xsl:element>
</xsl:when>
<xsl:otherwise><xsl:call-template name="testUnderline" select="." /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="testUnderline">
<xsl:choose>
<xsl:when test="contains(./@style, 'underline')">
<xsl:element name="span">
<xsl:attribute name="style">text-decoration: underline;</xsl:attribute>
<xsl:call-template name="endStyleTests" select="." />
</xsl:element>
</xsl:when>
<xsl:otherwise><xsl:call-template name="endStyleTests" select="." /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="endStyleTests">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
(为了便于阅读,删除了一些&#34; testSomething&#34;模板)
使用XSLT 1.0应该如何实现?
答案 0 :(得分:0)
你可以做的是创建一个包含&#34;映射的变量&#34;您想要的元素的样式
<xsl:variable name="styles">
<style match="italic" element="em" />
<style match="bold" element="strong" />
<style match="underline" element="span" style="text-decoration: underline;" />
</xsl:variable>
然后,您可以拥有一个模板,而不是每个样式映射都有单独的模板,它们依次递归地检查每个映射。
请注意,在XSLT 1.0中,styles
变量实际上包含所谓的&#34;结果树片段&#34;,因此您需要一个扩展函数来将它们作为节点进行处理。
试试这个XSLT
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:variable name="styles">
<style match="italic" element="em" />
<style match="bold" element="strong" />
<style match="underline" element="span" style="text-decoration: underline;" />
</xsl:variable>
<xsl:template match="span">
<xsl:call-template name="startStyleTests" />
</xsl:template>
<xsl:template name="startStyleTests">
<xsl:param name="styleNumber" select="1" />
<xsl:variable name="style" select="exslt:node-set($styles)/style[position() = $styleNumber]" />
<xsl:choose>
<xsl:when test="not($style)">
<xsl:call-template name="endStyleTests" />
</xsl:when>
<xsl:when test="contains(@style, $style/@match)">
<xsl:element name="{$style/@element}">
<xsl:if test="$style/@style">
<xsl:attribute name="style">
<xsl:value-of select="$style/@style" />
</xsl:attribute>
</xsl:if>
<xsl:call-template name="startStyleTests">
<xsl:with-param name="styleNumber" select="$styleNumber + 1" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="startStyleTests">
<xsl:with-param name="styleNumber" select="$styleNumber + 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="endStyleTests">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
或者,您可以将样式映射放在单独的XML文档中,然后使用document()
函数来访问它。这不需要扩展功能。