6

我需要使用非常适合正则表达式的 XSLT 1.0 执行查找和替换。不幸的是,这些在 1.0 中不可用,而且由于无法更改安全设置,我也无法使用任何扩展库,例如 EXSLT。

我正在使用的字符串如下所示:

19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson

我需要将数字和; #字符替换为,. 例如,上面将更改为:

John Smith, Ben Reynolds, Terry Jackson

我知道需要一个递归字符串函数,可能使用子字符串和翻译,但我不知道从哪里开始。

有人对如何解决这个问题有一些指示吗?这是我开始的:

<xsl:template name="TrimMulti">
    <xsl:param name="FullString" />
    <xsl:variable name="NormalizedString">
        <xsl:value-of select="normalize-space($FullString)" />
    </xsl:variable>
    <xsl:variable name="Hash">#</xsl:variable>
    <xsl:choose>
        <xsl:when test="contains($NormalizedString, $Hash)">
            <!-- Do something and call TrimMulti -->
        </xsl:when>
    </xsl:choose>
</xsl:template>
4

2 回答 2

9

我希望您没有在 SO 上询问问题时过于简化问题,因为这应该不是什么大问题。

只要保持输入字符串的格式一致,就可以定义模板并递归调用它。

例如,

<xsl:template name="TrimMulti">
  <xsl:param name="InputString"/>
  <xsl:variable name="RemainingString" 
    select="substring-after($InputString,';#')"/>
  <xsl:choose>
    <xsl:when test="contains($RemainingString,';#')">
      <xsl:value-of 
        select="substring-before($RemainingString,';#')"/>
      <xsl:text>, </xsl:text>
      <xsl:call-template name="TrimMulti">
        <xsl:with-param 
          name="InputString"
          select="substring-after($RemainingString,';#')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$RemainingString"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

我通过以下调用测试了这个模板:

<xsl:template match="/">
  <xsl:call-template name="TrimMulti">
    <xsl:with-param name="InputString">19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson</xsl:with-param>
  </xsl:call-template>
</xsl:template>

并得到以下输出:

John Smith, Ben Reynolds, Terry Jackson

这似乎是你所追求的。

如果您熟悉函数式编程,那么对它所做的事情的解释很容易解释。InputString参数始终采用[number];#[name];#[rest of string]. 模板的每次调用都会TrimMulti切断该[number];#部分并打印该[name]部分,然后将剩余的表达式递归地传递给它自己。

基本情况是 whenInputString是形式[number];#[name],在这种情况下RemainingString变量将不包含;#。由于我们知道这是输入的结尾,所以这次我们不输出逗号。

于 2009-06-25T13:48:43.790 回答
-1

如果';' 和 '#' 字符在输入中无效,因为它们是分隔符,那么为什么翻译功能不起作用?它可能很难看(您必须在第二个参数中指定所有有效字符并在第三个参数中重复它们)但它会更容易调试。

translate($InputString, ';#abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ', ', abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ')
于 2012-03-29T15:50:43.343 回答