Oct. 23rd, 2009

kickaha: (Default)
While you can use booleans all day long inside a template in XSLT 1.0, you can *NOT* pass them as values across template application or call boundaries. They invisibly become strings, leading to interesting things such as:
 

<xsl:template name="check_something">
<xsl:value-of select="true()"/>
</xsl:template>
 
 
<xsl:template match="anElement">
<xsl:variable name="flag">
<xsl:call-template name="check_something"/>
</xsl:variable>
<xsl:message>flag? <xsl:value-of select="$flag"/></xsl:message>
<xsl:message>not(flag)? <xsl:value-of select="not($flag)"/></xsl:message>
<xsl:choose>
<xsl:when test="$flag">
<xsl:message>flag is true...</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:message>flag is false...</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
 
 
When check_something returns true, as above, then you get the following output:
 

flag? true
not(flag?) false
flag is true...
 

But if you change that true() in check_something to false(), you get...
 

flag? false
not(flag?) false
flag is true...
 

Why? Because value-of, the only way to transport a function value back out of the template, converts the boolean to a string. Either 'true' or 'false'. Which means in the second case, the string is 'false', leading to the correct output for the first line, has a boolean value of true (non-empty), which when not-ted, gives the *boolean* value on the second line, and when checked as a flag, is of course again true.  Note complete lack of any differentiation in the output between the booleans and the strings.

You have to do an explicit check against the *STRING* 'true' at the call site. Change the xsl:if in the template to use test="$flag = 'true'" and it works as expected.



If you're expecting a really insane language model, that is.

Profile

kickaha: (Default)
kickaha

July 2010

S M T W T F S
    123
45678910
11121314151617
18192021222324
25 262728293031

Page Summary

Style Credit

Expand Cut Tags

No cut tags