这是我的需要: 我有一个由多个嵌套SPAN组成的HTML文本。 一些跨度包括内联css。在那个内联CSS中,我需要将一些样式属性转换为" classic" HTML,就像。 某些跨度具有一个或多个要由HTML元素替换的属性。
以下是输入示例:
<HTML>
<SPAN>
Some sentance including another
<SPAN STYLE="font-weight: bold;" >
included bold block
</SPAN>
with a tail in it and line breaks<BR/>
</SPAN>
<SPAN STYLE= "font-family: 'Helvetica';font-weight: bold;" >
Another span with 1 attribute not to be taken into account and 1 to be
</SPAN>
<SPAN STYLE= "font-family: 'Helvetica';font-weight: bold;text-decoration:underline;" >
Another span with two attributes to be taken into account
</SPAN>
</HTML>
我想要的结果是:
<HTML>
<p>Some sentance including another
<p><b>included bold block </b></p>
with a tail in it and line breaks<BR/></p>
<p><b>Another span with 1 attribute not to be taken into account and 1 to be</b></p>
<p><b><u>Another span with two attributes to be taken into account</u></b></p>
</HTML>
我认为最好的方法是使用身份转换并使用模板来匹配属性,例如:
SPAN[contains(@STYLE, 'font-weight: bold;')
和:
SPAN[contains(@STYLE, 'text-decoration:underline;')]
这是我试过的......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'text-decoration:underline;')]">
<xsl:element name="u">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'font-weight: bold;')]">
<xsl:element name="b">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="SPAN">
<!-- replacing SPAN into <p>elements -->
<xsl:element name="p">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="SPAN/@STYLE"/>
<!-- suppression of the old Style attribute-->
</xsl:stylesheet>
问题是,当它运行时,它只匹配其中一个或者 我想我错误地理解如何在模板中使用xsl:copy来要求模板评估SPAN并重新评估相同范围内的其他模板,但是我没有成功让它工作有或没有它...
我提前感谢你对此的看法。
祝你好运。
答案 0 :(得分:0)
在这里,您可以使用XSLT 1.0中的模式进行操作
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'text-decoration:underline;')]" mode="u">
<u>
<xsl:apply-templates/>
</u>
</xsl:template>
<xsl:template match="SPAN" mode="u">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'font-weight: bold;')]" mode="b">
<b>
<xsl:apply-templates select="." mode="u" />
</b>
</xsl:template>
<xsl:template match="SPAN" mode="b">
<xsl:apply-templates select="." mode="u" />
</xsl:template>
<xsl:template match="SPAN">
<p>
<xsl:apply-templates select="." mode="b" />
</p>
</xsl:template>
</xsl:stylesheet>
请注意,匹配SPAN[contains(...)]
的模板的优先级高于匹配SPAN
的模板。
因此,实际上您可以更改模板。对于SPAN标记,输出p
节点,然后调用b
模板以检查粗体。然后b
模板调用u
模板以检查下划线,然后此模板处理子项。您可以以类似的方式添加更多模板(因此b
调用u
,然后u
调用i
,i
处理子项。
编辑:如果您想避免为每个模板编写两个模板,您可以将每对模板合并为一个模板,如此
<xsl:template match="SPAN" mode="b">
<xsl:choose>
<xsl:when test="contains(@STYLE, 'font-weight: bold;')">
<b>
<xsl:apply-templates select="." mode="u" />
</b>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="u" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
如果你可以使用XSLT 2.0,你可以使用优先级,而next-match
代替,这会减少模板的数量
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SPAN">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'text-decoration:underline;')]" priority="8">
<u>
<xsl:next-match />
</u>
</xsl:template>
<xsl:template match="SPAN[contains(@STYLE, 'font-weight: bold;')]" priority="9">
<b>
<xsl:next-match />
</b>
</xsl:template>
<xsl:template match="SPAN" priority="10">
<p>
<xsl:next-match />
</p>
</xsl:template>
</xsl:stylesheet>