我怎么不在我的xslt代码中重复重复的逻辑?

时间:2011-06-09 17:10:32

标签: xml xslt exslt

编写此代码的更好方法是什么:

 <xsl:template name="CamelChain">
      <xsl:param name="input"/>
      <xsl:param name="position"/>
      <xsl:if test="$position &lt;= string-length($input)">
         <xsl:choose>
         <xsl:when test="substring($input, $position, 1) = '_'">
            <xsl:value-of select="translate(substring($input, $position + 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>

            <xsl:call-template name="CamelChain">
               <xsl:with-param name="input" select="$input"/>
               <xsl:with-param name="position" select="$position + 2"/>
            </xsl:call-template>
         </xsl:when>

         <xsl:otherwise>

            <xsl:value-of select="substring($input, $position, 1)"/>

            <xsl:call-template name="CamelChain">
               <xsl:with-param name="input" select="$input"/>
               <xsl:with-param name="position" select="$position + 1"/>
            </xsl:call-template>
         </xsl:otherwise>
         </xsl:choose>
      </xsl:if>
   </xsl:template>

好吧干净但我相信它可以清洁。现在说我正在重复这个逻辑:

<xsl:call-template name="CamelChain">
               <xsl:with-param name="input" select="$input"/>
               <xsl:with-param name="position" select="$new_position"/>
            </xsl:call-template>

基本上任何人都有任何解决方案吗?

我自己亲自尝试过@ xslt is it ok if we do `select="$position + $jump"`?,但是这种方法(或者我称之为hack)不起作用..所以我目前没有解决方案,并且想知道是否有人可以提供帮助。

基本上我的想法是:

<xsl:template name="CamelChain">
      <xsl:param name="input"/>
      <xsl:param name="position"/>
      <xsl:variable name="jump"/>
      <xsl:if test="$position &lt;= string-length($input)">
         <xsl:choose>
            <xsl:when test="substring($input, $position, 1) = '_'">
               <xsl:value-of select="translate(substring($input, $position + 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
               <!-- set jump to 2 -->
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="substring($input, $position, 1)"/>
               <!-- set jump to 1 -->
            </xsl:otherwise>
         </xsl:choose>
         <xsl:call-template name="CamelChain">
            <xsl:with-param name="input" select="$input"/>
            <xsl:with-param name="position" select="$position + $jump"/>
         </xsl:call-template>
      </xsl:if>
   </xsl:template>

或者也许是完全不同或充满异国情调的东西。 (这里没有扩展的XSLT 1.0)

2 个答案:

答案 0 :(得分:3)

更好的方法是在XSLT 2.0中编写它:

<xsl:analyze-string select="$in" regex="_.">
  <xsl:matching-substring>
    <xsl:value-of select="uppercase(substring(., 2, 1))"/>
  </xsl:matching-substring>
  <xsl:non-matching-substring>
     <xsl:value-of select="value-of select="."/>
  </xsl:non-matching-substring>
</xsl:analyze-string>

我担心你尝试的很难,解决XSLT 1.0中的字符操作问题会很乏味和冗长。

答案 1 :(得分:1)

正如@ Michael-Key明确指出的那样,XSLT 1.0中的字符串操作是冗长的(好吧,单调乏味......)。

我查看了你的模板,我认为只要在模板范围内进行模板递归调用就不那么容易了,除非你改变了对模板设计方式的看法。

请注意,您的模板不会输入大写输入字的第一个字母。这是想要吗?

然而,由于存在更加乏味和冗长的风险,我想向您展示这种方法:

  • 仅使用一个参数
  • 第一个字符的问题已修复
  • 使用变量(以便您可以看到它们如何工作)
  • 模板为每个_调用一次,而不是每个字符调用一次(显然不是吗?)

<xsl:template name="CamelCase">

    <xsl:param name="input" select="'this_string_will_be_camel_case'"/>

    <xsl:variable name="camel">
        <xsl:variable name="sub" select="substring-before($input,'_')"/> 
        <xsl:choose>
            <xsl:when test="not(string-length($sub)=0)">
                <xsl:value-of select="$sub"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$input"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:variable name="case">
        <xsl:value-of select="translate(
            substring($camel,1,1),
            'abcdefghijklmnopqrstuvwxyz',
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    </xsl:variable>

    <xsl:value-of select="concat($case,substring($camel,2))"/>

    <xsl:if test="not(string-length($camel)=0)">
        <xsl:call-template name="CamelCase">
            <xsl:with-param name="input" select="substring-after($input,'_')"/>
        </xsl:call-template>
    </xsl:if>

</xsl:template>

例如,如果你把它称为:

 <xsl:call-template name="CamelCase"/>

它将返回:

 ThisStringWillBeCamelCase