代码之家  ›  专栏  ›  技术社区  ›  Jagger

XSLT 2.0,替换函数:如何用大写替换匹配的组?

  •  2
  • Jagger  · 技术社区  · 16 年前

    如果我的XSL文件中有以下元素:

    <xsl:value-of select="replace(lower-case(@name), '_([a-z0-9])', '$1')" />
    

    例如,从“get_polygene_lubricants”中,它生成了“getmultigene_lubbricants”。

    我想做的是将“_”后的第一个字母替换为 字母的大写变体。我在谷歌上搜索,阅读文档, 但我在XSLT中找不到任何解决这个简单问题的方法 替换。

    也许有人知道XSLT 2.0中是否可能?

    3 回复  |  直到 15 年前
        1
  •  6
  •   Dimitre Novatchev    16 年前

    已编辑 :根据原始海报的说明,由下划线分隔的第一个字符串的起始字母不应大写。

    此解决方案不使用递归,应该更有效 .

    这是新的解决方案 :

    string-join(
                (for  $i in 1 to count(tokenize(.,'_')),
                      $s in tokenize(.,'_')[$i],
                      $fl in substring($s,1,1),
                      $tail in substring($s,2)
                   return
                      if($i eq 1)
                       then $s
                       else concat(upper-case($fl), $tail)
                 ),
                            ''
               )
    

    结果现在完全符合要求:

    underLinedString
    

    下面是旧的解决方案 .

    replace()函数假设你有一个固定的替换 --因此,它不是解决这个问题的最佳工具。

    这是一个单行XPath 2.0解决方案 (它当然可以用作XSLT 2.0转换的一部分:):

    string-join(
                (for $s in tokenize(.,'_'),
                     $fl in substring($s,1,1),
                     $tail in substring($s,2)
                   return
                     concat(upper-case($fl), $tail)
                 ),
                ''
               )
    

    当我们在这样的XSLT 2.0转换中使用上述表达式时 :

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xsl:template match="/">
         <xsl:sequence select=
          "string-join(
                       (for $s in tokenize(.,'_'),
                        $fl in substring($s,1,1),
                        $tail in substring($s,2)
                      return
                    concat(upper-case($fl), $tail)
                       ),
                       ''
                      )
    
          "/>
        </xsl:template>
    </xsl:stylesheet>
    

    并将其应用于此XML文档:

    <t>under_lined_String</t>
    

    产生了想要的结果 :

    UnderLinedString
    
        2
  •  1
  •   baretta    16 年前

    您可以使用模板来实现这一点,递归调用自身来迭代字符串中的字符。此模板应采用位置参数,从1开始 并且随着对模板的每次调用而增加。当找到“_”时,使用translate(1.0)或大写(2.0)将下一个char转换为大写

        3
  •  0
  •   nicerobot    14 年前

    虽然已经回答了,但这是我的解决方案:

    <xsl:template name="camel-case">
      <xsl:param name='value'/>
      <xsl:analyze-string regex="^(.)" select="$value">
        <xsl:matching-substring><xsl:value-of select="upper-case(regex-group(1))"/></xsl:matching-substring>
        <xsl:non-matching-substring>
          <xsl:analyze-string regex="[_-](.)" select=".">
            <xsl:matching-substring><xsl:value-of select="upper-case(regex-group(1))"/></xsl:matching-substring>
            <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
          </xsl:analyze-string>
        </xsl:non-matching-substring>          
      </xsl:analyze-string>
    </xsl:template>
    

    用途:

    <xsl:call-template name="camel-case">
      <xsl:with-param name='value' select="."/>
    </xsl:call-template>