Error XPTY0004 on Saxon-HE 10.3 (not on 9.9.1-8)
I encountered what appears to be a bug in release 10.3. Attached stylesheet fails with the following message:
Error at char 9 in expression in xsl:value-of/@select on line 6 column 51 of stylesheet.xsl: XPTY0004 Cast does not allow an empty sequence In template rule with match="/" on line 4 of stylesheet.xsl Cast does not allow an empty sequence
The same stylesheet works with version 9.9.1-8.
#2 Updated by Pavel Vítkovský 3 months ago
Manifests both on my Windows 10 machine and on our production Linux server (locally tested on Java 8 and Java 11, on server with Java 11 only). I have attached zip archive I'm using on mu local machine. Both Saxon builds are downloaded from Maven central. Added also exception stack trace of the actual production stylesheet having this issue.
#3 Updated by Michael Kay 3 months ago
Problem now reproduced - but not in my normal debugging environment!
The specification says that xsl:value-of, when the select expression returns an empty sequence, should deliver a zero-length text node, but the function is actually returning an empty sequence. Because the static type analysis inferred a type of text() for the function result, the code for the comparison is assuming that it won't get an empty sequence, and fails when it does. There is some interplay here with the precise way in which the transformation is run; the function has to be executed in push mode for the failure to occur.
#5 Updated by Michael Kay 3 months ago
The optimisations carried out at compile time appear to be correct. The body of the function is reduced to
ValueOf(lastOf(tokenize((), "/", "")))
which should be OK: when the operand of
ValueOf is an empty sequence, the result of
ValueOf should be a single zero-length text node, However, the push-mode evaluation of this instruction, which has changed in 10.x to stream the result to the serializer, actually delivers an empty sequence rather than a single zero-length text node.
I don't know why this path is only taken in these particular circumstances, but there's a flaw in the logic here, and it's not immediately obvious how to fix it.
#6 Updated by Michael Kay 3 months ago
This bug is proving surprisingly difficult. I've made various attempts at fixing it by detecting the case where the xsl:value-of/select selects an empty sequence and emitting a zero-length text node in this case; all my attempts cause regression to significant numbers of other tests.
#7 Updated by Michael Kay 3 months ago
The only fix I've found that causes no regression is to suppress the optimisation in ValueOf (specifically, pushing the output of the select expression directly to the serializer) in the case where the select expression is capable of returning an empty sequence.
#8 Updated by Pavel Vítkovský 3 months ago
So far there is only a single location in one of the stylesheets that is affected by it in our case and since it is trivial to avoid it (and in fact improve the stylesheet, there really is no reason to use value-of) we're sticking with upgrade. Thanks for the insights.
#9 Updated by Michael Kay 3 months ago
Indeed, basic good practice like (a) declaring the types of the parameters and return value of
xsl:function, and (b) using
xsl:sequence rather than
xsl:value-of to return the function result, would have prevented the problem from occurring. But of course we have to treat it as a bug anyway.
#10 Updated by Michael Kay 3 months ago
- Category set to XSLT conformance
- Status changed from New to Resolved
- Assignee set to Michael Kay
- Priority changed from Low to Normal
- Applies to branch trunk added
- Fix Committed on Branch 10, trunk added
I have applied the change proposed: the optimisation no longer takes place if the expression is capable of returning an empty sequence.
Please register to edit this issue