Поскольку вы сказали, что функция 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>