using not(following-sibling::text()) instead of last() fixed it. Could you explain why or give some pointers to the problems of last()?
There are two ways of evaluating patterns: left-to-right, and right-to-left, corresponding to the "formal" and "informal" semantics given in section 5.5.3 of the specification. The right-to-left method is much more efficient, but it cannot be used for all patterns; in particular, patterns that use positional predicates are tricky. Saxon will handle a number of cases efficiently, including match="para[last()]"
, but for some others, including match="para[last()-1]"
and (it seems) match="section/para[last()]"
, it takes the slow-but-methodical route. I'll take a look at the code and see if this can be improved.