Xalan(XSLT)翻译方法的翻译比它应该的更多

Bil*_*zac 1 xml xslt xalan

我似乎遇到了Xalan的翻译方法的问题.我有以下代码:

translate(translate(string(name),'<sup>',''),'</sup>','')

这是用来去除<sup></sup>从字符串(名称).不幸的是,当我这样做时,它似乎也从名称中删除了s,u和p.所以名字就像sony Braiva <sup>tm</sup>变成了ony bravia tm

谢谢你的帮助提前:)

Dim*_*hev 5

因为你说,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(., '&lt;sup>')"/>

  <xsl:value-of select="$vPart1"/>

  <xsl:variable name="vPart2" select=
   "substring-before(substring-after(., '&lt;sup>'),
                     '&lt;/sup>'
                     )"/>

  <xsl:value-of select="$vPart2"/>

  <xsl:variable name="vPart3" select=
   "substring-after(., '&lt;/sup>')"/>

  <xsl:value-of select="$vPart3"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

将此转换应用于以下XML文档时:

<name>
 <![CDATA[sony Braiva <sup>tm</sup> xxx]]>
</name>
Run Code Online (Sandbox Code Playgroud)

产生了想要的结果:

<name>
sony Braiva tm xxx
</name>
Run Code Online (Sandbox Code Playgroud)

或者,这是完整的递归模板解决方案:

<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="'&lt;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="'&lt;/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>
Run Code Online (Sandbox Code Playgroud)

在此XML文档上应用此转换时:

<name>
 <![CDATA[sony Braiva <sup>tm</sup> xxx]]>
</name>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

<name>
 sony Braiva tm xxx
</name>
Run Code Online (Sandbox Code Playgroud)

最后,这是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(., '&lt;sup>', ''),
            '&lt;/sup>',
            ''
            )
   "/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)