как мне не повторить повторяющуюся логику в моем коде xslt? - PullRequest
3 голосов
/ 09 июня 2011

как лучше написать этот код:

 <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 все нормально, если мы сделаем `select =" $ position + $ jump "`? , но этот метод (или хак, как я его называю) не работает ... так что у меня сейчас нет решений, и мне было интересно, может ли кто-нибудь помочь.

В основном я думал так:

<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 ]

3 голосов
/ 10 июня 2011

Лучше написать это в 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 голос
/ 10 июня 2011

Как ясно говорит @ 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
...