Jeni Tennison
>> Given this, the fact that you're getting an error highlights for you
>> the fact that in XSLT 1.0 you're only testing the first of the rows
>> for content whereas you actually want to test if "all the cells are
>> empty" or, in other words, if any of the cells has content. For the
>> test to succeed when any of the $rows has content, you should use:
>>
>> count($rows) = 3 and $rows[normalize-space(.)]
> ^^^^^^^^^^^^^^^^^^^^^^^
The predicate works in XSLT 2.0 just as it does in XSLT 1.0 -- it
filters the sequence of nodes held in the $rows variable to include
only those for which the test "normalize-space(.)" is true. The test
"normalize-space(.)" will be true for those nodes in $rows that have
non-whitespace characters in their string values. The fact that the
resulting sequence of nodes is used as an argument to the "and"
operator means that the sequence is interpreted as a boolean value --
true if the sequence contains items and false otherwise. Therefore if
there are any nodes left after the filtering (i.e. any nodes that have
non-whitespace characters in their string values) then it will be
true.
To make the boolean casts explicit, the above is the same as: count($rows) = 3 and boolean($rows[boolean(normalize-space(.))]) If you want to reinterpret that as a "some" expression, it's: count($rows) = 3 and
some $r in $rows satisfies normalize-space($r)
or as a "for" expression:
count($rows) = 3 and
for $r in $rows return if (normalize-space($r)) then $r else ()
Since we know that there are three nodes in $rows, it's the same as:
count($rows) = 3 and
(normalize-space($rows[1]) or
normalize-space($rows[2]) or
normalize-space($rows[3]))
As far as what a processor would do, an optimised processor would most
likely iterate over the nodes in $rows until it found one for which
normalize-space(.) returned a non-empty string, and then return true
for the sub-expression. |