xsl-list
[Top] [All Lists]

Re: [xsl] FizzBuzz in XSLT 1.0. Help with a 2.0/FXSL solution?

2007-03-14 14:15:33
M. David Peterson wrote:
I been bouncing around different ideas in my head all morning as to the best 
way to optimize this in XSLT 2.0/FXSL, but as of yet, haven't come up with 
something that I think really takes advantage of what XSLT 2.0/FXSL bring to 
the table.  Ideas from the community at large?

Hi David,

Though others have already provided good solutions, I couldn't resist upon reading your request. Coming from a Perl world, I like one-liners, and though very much against any spirit of clear code, here's a version that does away with if-statements altogether (oops, I see now that David C's second approach already had that).

I agree with David C that a slightly different input XML would make the code a fair amount more readable. With the proposed start/end it looks like this (quite like David's simplified example):

<xsl:template match="fizzbuzz">
   <xsl:value-of separator="&#10;"
       select="for $i in start to end
return ((string-join(test/mod[$i mod @value = @test], ''))[.], $i)[1]" />
</xsl:template>


With the original input document, however, my attempt looks like this:

<xsl:template match="fizzbuzz">
   <xsl:value-of separator="&#10;"
       select="
           for $i in range/xs:integer(tokenize(., '\D')[1])
           to range/xs:integer(tokenize(., '\D')[last()])
return (string-join(test/mod[$i mod @value = @test], '')[.], $i)[1]" />
</xsl:template>


Note that there's a slight change in semantics for the range value (now any separator works). I.e.:

<!-- outputs 'FizzBuzz' -->
<range>54390</range>

<!-- outputs '4 Buzz Fizz 7' -->
<range>4 to 7</range>

<!-- outputs all up to 100 -->
<range>1-100</range>

The oddbit in my code (well, it took me some time to get it right) is the string-join. Most functions return an empty sequence when provided with an empty sequence, but not string-join, hence the rather awkward conversion to a sequence and testing for self: string-join(inp-seq, '')[.]

This returns an empty sequence when it string-join returns an empty string, which will be factored out, hence the following: ((), $i)[1] will return the last value.

Thanks for the exercise ;)

Cheers,
-- Abel Braaksma
  http://www.nuntia.nl


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--