[Home] [By Thread] [By Date] [Recent Entries]
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
|

Cart



