将直引号转换为智能引号

时间:2013-05-20 08:59:28

标签: xslt

我有以下xml

<para>A number of the offences set out in the Companies Ordinance are expressed to apply to "officers" of the company. "Officer" includes directors, managers and the company secretary: Companies Ordinance, s.2(1).</para>

这里实际上在输入中给出的引号是“但我想将它转换为智能引号。我使用了下面的xslt。

<xsl:template match="para/text()">
<xsl:when test="contains(.,$quot)">
<xsl:value-of select="translate(.,$quot,'“')"/>
<xsl:value-of select="translate(substring-after(.,$quot),$quot,'”')"/>
</xsl:when>
</xsl:template>

但我的收入低于ooutput。

A number of the offences set out in the Companies Ordinance are expressed to apply to “officers“ of the company. “Officer“ includes directors, managers and the company secretary: Companies Ordinance, s.2(1).

但我希望如下所示。

A number of the offences set out in the Companies Ordinance are expressed to apply to “officers” of the company. “Officer” includes directors, managers and the company secretary: Companies Ordinance, s.2(1).

请让我知道如何解决这个问题。

由于

1 个答案:

答案 0 :(得分:0)

您的方法存在的主要问题是翻译功能会将所有引号替换为智能开启引号。因此,后续的 substring-after 函数实际上不会找到任何内容,因为找不到任何引号。

在这种情况下,您真正​​需要的是递归模板,以及 substring-before substring-after 的组合。命名模板实际上可以与现有模板组合,默认参数将用于初始匹配

   <xsl:template match="para/text()" name="replace">
      <xsl:param name="text" select="."/>
      <xsl:param name="usequote" select="$openquote"/>

$ openquote 将是包含开头报价的变量)

然后,您将检查所选文本是否包含引号

<xsl:when test="contains($text,$quot)">

如果是这样,您将首先在引号之前输出文本,然后输出新的公开引用

<xsl:value-of select="concat(substring-before($text, $quot), $usequote)"/>

然后使用引用后的文本递归调用模板,并使用close quote作为参数,因此下一个引用查找将被关闭。

<xsl:call-template name="replace">
   <xsl:with-param name="text" select="substring-after($text,$quot)"/>
   <xsl:with-param name="usequote"
         select="substring(concat($openquote, $closequote), 2 - ($usequote=$closequote), 1)"/>
</xsl:call-template>

注意:选择 usequote 基本上会在打开和关闭引号之间切换。它利用了事实'true'在数值表达式中的计算结果为1,并将'false'计算为0。

试试这个XSLT。注意,在这种情况下,我使用开括号和近括号,只是为了使输出更清晰,但您可以根据需要轻松地将变量更改为智能引号。 (在这种情况下,您可能必须为输出指定编码)。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="text"/>

   <xsl:variable name="quot">"</xsl:variable>
   <xsl:variable name="openquote">[</xsl:variable>
   <xsl:variable name="closequote">]</xsl:variable>

   <xsl:template match="para/text()" name="replace">
      <xsl:param name="text" select="."/>
      <xsl:param name="usequote" select="$openquote"/>
      <xsl:choose>
         <xsl:when test="contains($text,$quot)">
            <xsl:value-of select="concat(substring-before($text, $quot), $usequote)"/>
            <xsl:call-template name="replace">
               <xsl:with-param name="text" select="substring-after($text,$quot)"/>
               <xsl:with-param name="usequote"
                    select="substring(concat($openquote, $closequote), 2 - ($usequote=$closequote), 1)"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$text"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

应用于XML时,输出以下内容

A number of the offences set out in the Companies Ordinance are expressed to apply to [officers] of the company. [Officer] includes directors, managers and the company secretary: Companies Ordinance, s.2(1).