| 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. |