Subject: Re: [xsl] update value of variable in for-each loop|
From: David Rudel <fwqhgads@xxxxxxxxx>
Date: Wed, 9 Apr 2014 07:13:24 +0200
Henry, Everything Mike and David has said is true, but I think the reason this is not giving the output you expect may be based on a misunderstanding about how for-each works and the nature of variable declaration in XSLT. Below I have pasted one part of your code: <xsl:variable name="foo"> <xsl:for-each select="data"> <xsl:choose> <xsl:when test="contains(elements/ elementA '1234) or contains(elements/package/id '55) or contains(elements/category/id, '67)" or contains(............."> <xsl:value-of select="1"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="0"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:variable> Call this block "B" I think you may be thinking of "B" as a type of procedure where "$foo" is being defined. However, that is not quite true. "B" is not merely a procedure in which you define $foo. Rather, this code fragment defines $foo as the collection of all the things created by the block. In particular, B does not say "Look through the data nodes and if *any* of them satisfy the test ["contains(elements/ elementA '1234) or contains(elements/package/id '55) or contains(elements/category/id, '67)" or contains(............."], then assign the value of "1" to B, otherwise assign "0." Rather, what this code does is say "Create a temporary document in memory. Go through every data node, testing each one separately. _Each_ time a data element passes the test, write down a "1" (as a text node) in this temporary document. _Each_ time a data element fails the test, write down a "0" (as a text node). Then assign the value of $foo to be this entire temporary document. Then later when you test the value of $foo, it atomizes this temporary document into a string of the individual 1s and 0s. Also, you shouldn't think of variables in XSLT the same way as you do in other languages. In most languages, you initialize a variable (I think this is what you were doing with the empty instruction <xsl:variable name="foo"/> at the top). Then you change the variable as the program progresses. Variables in XSLT are immutable. They cannot be changed. Once you define a variable in a given scope, you should not redefine the same variable in that scope. This is why David was saying that the <xsl:variable name="foo"/> line served no purpose. (Indeed, I'm surprised your processor did not raise a warning when you defined $foo twice in the same scope.) -David On Tue, Apr 8, 2014 at 10:54 PM, David Carlisle <davidc@xxxxxxxxx> wrote: > On 08/04/2014 21:49, henry human wrote: >> >> When I run this code the output of the variable foo is never 1 or 0 >> as I expect but either 0011 or 11 or 0001 > > > Yes, but the code clearly is going to make 000111 etc, because that's > what it is coded to do. You have only shown the code. You _want_ it to > do something else but you have not said what that is, you expect that we > can tell from the code when you want it to be 1 and when you want it to > be 0, but how can we guess that? We do know the input, or the desired > output or the intention of the code block. > > > David > > -- > google plus: https:/profiles.google.com/d.p.carlisle > -- "A false conclusion, once arrived at and widely accepted is not dislodged easily, and the less it is understood, the more tenaciously it is held." - Cantor's Law of Preservation of Ignorance.