因为你说 translate() 函数成功删除了<sup> 和</sup>,所以我假设<sup> 不是XML 文档中的元素,而是编码为文本。
translate() 函数被定义为替换单个字符,一般不适用于字符串替换,当字符串长度大于 1 时。
可以在 XSLT 中编写和使用通用字符串替换递归模板/函数。
XSLT 2.0 程序员可以使用标准的 XPath 2.0 函数 replace()。
在您的特定情况下,这可能就足够了:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vPart1" select=
"substring-before(., '<sup>')"/>
<xsl:value-of select="$vPart1"/>
<xsl:variable name="vPart2" select=
"substring-before(substring-after(., '<sup>'),
'</sup>'
)"/>
<xsl:value-of select="$vPart2"/>
<xsl:variable name="vPart3" select=
"substring-after(., '</sup>')"/>
<xsl:value-of select="$vPart3"/>
</xsl:template>
</xsl:stylesheet>
当此转换应用于以下 XML 文档时:
<name>
<![CDATA[sony Braiva <sup>tm</sup> xxx]]>
</name>
产生想要的结果:
<name>
sony Braiva tm xxx
</name>
或者,这里是成熟的递归模板解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vFirstReplacement">
<xsl:call-template name="replace">
<xsl:with-param name="pText" select="."/>
<xsl:with-param name="pPattern"
select="'<sup>'"/>
<xsl:with-param name="pReplacement" select="''"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="replace">
<xsl:with-param name="pText"
select="$vFirstReplacement"/>
<xsl:with-param name="pPattern"
select="'</sup>'"/>
<xsl:with-param name="pReplacement" select="''"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="pText"/>
<xsl:param name="pPattern"/>
<xsl:param name="pReplacement"/>
<xsl:choose>
<xsl:when test="not(contains($pText, $pPattern))">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=
"substring-before($pText, $pPattern)"/>
<xsl:value-of select="$pReplacement"/>
<xsl:call-template name="replace">
<xsl:with-param name="pText" select=
"substring-after($pText, $pPattern)"/>
<xsl:with-param name="pPattern"
select="$pPattern"/>
<xsl:with-param name="pReplacement"
select="$pReplacement"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当此转换应用于此 XML 文档时:
<name>
<![CDATA[sony Braiva <sup>tm</sup> xxx]]>
</name>
产生了想要的正确结果:
<name>
sony Braiva tm xxx
</name>
最后,这里是 XSLT 2.0 解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select=
"replace(
replace(., '<sup>', ''),
'</sup>',
''
)
"/>
</xsl:template>
</xsl:stylesheet>