Subject: Re: [xsl] 99 bottles of beer From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx> Date: Mon, 5 Feb 2007 20:36:32 +0000 |
Andrew Welch wrote: > > Nice! However a couple of small problems: > > 2 bottles of beer on the wall. > 2 bottles of beer. > Take one down, pass it around > 1 bottles of beer on the wall. > ^^^^^^^ > > 1 bottle of beer on the wall. > 1 bottle of beer. > Take one down, pass it around > 0 bottle of beer on the wall. > ^^^^^^^^ > > You just need to modify it slightly:
Thanks for the correction. But now we have duplicated logic (the cast + ends-with), which some consider bad programming practice. Here's an update that does not duplicate the logic, removes the nested for (better: it shows a way of shortcutting nested loops with the comma operator), corrects my error and is much less readable (which was not on purpose, btw).
for $i in reverse(1 to 99), $j in (1 to 3)
return concat ($i - xs:integer($j mod 3 = 0), ' bottle', ('s')[not($i * 3 - $j = (1 to 3))], ' of beer',
(' on the wall.', '. Take one down, pass it around', ' on the wall. ' )[$j]
(I like the idea of using the predicate instead of if...then...else)
As a tutorial it suits well for explaining why:
('s')[$i * 3 - $j != (1 to 3)]
yields exactly the same result as:
('s')[$i * 3 - $j = (1 to 3)]
which is quite counter-intuitive (IIRC, for a '!=' to return false, none from the left must be the same as any from the right; to be true, only one item needs to be unequal. This is not backed up by the example above, but I am sure I am overlooking something. Moreover, I found that (1 to 2) != 10 returns false, and (1,2) != 10 returns true.... I am really missing something here, this must be a faq somewhere :S ).
The difference there is that (1 to 2) != 10 returns a sequence of 2 items "true true", whereas (1,2) != 10 returns a single "true". I would have to look it up but I think anything other than a single "true" converts to false, so "true true" returns false.
You could rewrite it as ((1 to 2) != 10) = false() to check the values in the sequence for any occurance of false(), and return a single true/false.
cheers andrew
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] 99 bottles of beer, Abel Braaksma | Thread | RE: [xsl] 99 bottles of beer, Michael Kay |
Re: [xsl] 99 bottles of beer, Abel Braaksma | Date | Re: [xsl] Microsoft XML Team blog: , Rashmi Rubdi |
Month |