1

I've got this code (which is working properly):

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

And i attempted to normalize it abit as such:

   <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:variable name="jump" select="2"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="substring($input, $position, 1)"/>
               <xsl:variable name="jump" select="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>

But after I've "normalized" it.. it's not working anymore. I suspect its got something to do with the select="$position + $jump" portion but i'm not sure what's wrong with it. does anyone know what's wrong?

Chris Laarman
  • 1,559
  • 12
  • 25
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    Don't say that something "doesn't work". Tell us how it fails. The first thing you need when debugging someone's code is to know the error messages. – Michael Kay Jun 09 '11 at 11:11
  • well its working but not working as expected.. so i'd get no error messages – Pacerier Jun 09 '11 at 16:42

2 Answers2

4

Your problem is that the variable $jump is out of scope. You can't set variables inside a xsl:choose, and expect their value to persist outside. I believe you have to edit the middle section like this:

<xsl:variable name="char" select="substring($input, $position, 1)" />

<xsl:variable name="jump">
    <xsl:choose>
        <xsl:when test="$char = '_'">2</xsl:when>
        <xsl:otherwise>1</xsl:otherwise>
    </xsl:choose>
</xsl:variable>

<xsl:choose>
    <xsl:when test="$char = '_'">
        <xsl:value-of select="translate(substring($input, $position + 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$char"/>
    </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>

The xsl:choose must go within the xsl:variable, not the other way around.

To be honest though, I can't see anything objectionable with your original code. It looks cleaner to me.

Eric
  • 95,302
  • 53
  • 242
  • 374
  • well compared to this solution, the `Part 1` code of my question is cleaner of course.. since this repeats the `substring($input, $position, 1)`. However comparing `Part 2` to `Part 1`, part two is way cleaner (well assuming if it did worked of course) – Pacerier Jun 09 '11 at 16:48
  • @Pacerier: Store that in the variable then! `` – Eric Jun 09 '11 at 21:52
  • you are missing my point.. `Part 2` is cleaner than `Part 1` because we do not have to repeat `` neither do we have to repeat `` neither do we have to repeat `` (all of which are repeated in `Part 1 Code` ) – Pacerier Jun 12 '11 at 14:13
1

Your two $jump variables each go out of scope before you reference them.

In XSLT as in any block-structured language a variable has a scope, out of which it is undefined.

    <xsl:when test="substring($input, $position, 1) = '_'">
        <xsl:value-of select=
        "translate(substring($input, $position + 1, 1),
                   'abcdefghijklmnopqrstuvwxyz',
                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
        <xsl:variable name="jump" select="2"/>
    </xsl:when>

here you are defining the $jump variable at the very end of its scope and it immediately ceases to exist. This is an obvious error and Some XSLT processors as Saxon even issue a warning message about this.

You have exactly the same problem with the other variable (also named $jump) definition.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431