views:

31

answers:

1

Can anyone explain to me the results of this query:

declare @xml xml;
set @xml = '<node attribute="true">Val</node>';

select
    T.c.query('xs:boolean(@attribute[1])') Value,
    T.c.query('xs:boolean(@attribute[1]) = false') ValueEqualsFalse,
    T.c.query('xs:boolean(@attribute[1]) = true') ValueEqualsTrue,
    T.c.query('xs:boolean(@attribute[1]) != false') ValueNotEqualsFalse,
    T.c.query('xs:boolean(@attribute[1]) != true') ValueNotEqualsTrue
from @Xml.nodes('node') T(c);

The first column, Value, returns true. The rest all return false. So having managed to cast the value to the correct type, how do I actually check it's value?

+1  A: 

you need to use fn:false() or false() and fn:true() or true() instead of just writing true or false.

This is a correct example:

T.c.query('xs:boolean(@attribute[1]) = false()') ValueEqualsFalse,
T.c.query('xs:boolean(@attribute[1]) = true()') ValueEqualsTrue,
T.c.query('xs:boolean(@attribute[1]) != false()') ValueNotEqualsFalse,
T.c.query('xs:boolean(@attribute[1]) != true()') ValueNotEqualsTrue

If you don't use the function false(), false is processed as a path expression, i.e. the processor thinks you are querying for a <false /> element. Therefore, there only exists a function for the constants true and false, because this is the only way to distinguish between the boolean constants and a path expression.

More in detail, using the negation would still return false in each example.

This is not what you want (just to demonstrate):

T.c.query('not(xs:boolean(@attribute[1])) = false') ValueEqualsFalse,
T.c.query('not(xs:boolean(@attribute[1])) = true') ValueEqualsTrue,
T.c.query('not(xs:boolean(@attribute[1])) != false') ValueNotEqualsFalse,
T.c.query('not(xs:boolean(@attribute[1])) != true') ValueNotEqualsTrue

the literals false and true both are evaluated to an empty sequence which neither matches the boolean value false() nor the boolean value true().

Dennis Knochenwefel
The empty sequence is not cast to `false` in the latter case. Instead you are comparing a boolean value with an empty sequence. The `=` and `!=` operators are sequence comparisons, and return true if there is a pair of items in the input sequences that satisfies the comparison. Since there are no items in the empty sequence that satisfy the comparison, the result of all these cases is false().
Oliver Hallam
Thanks Oliver! My mistake. I edited the post.
Dennis Knochenwefel
Evs