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