Bug #3908
closed
XQuery allows a context item to be supplied when it is already initialized in the query
Category:
XQuery conformance
Applies to branch:
9.8, trunk
Fix Committed on Branch:
9.8
Fixed in Maintenance Release:
Description
With a query
declare context item := 3; .
it can be called from the command line specifying -s:temp.xml, and the query returns the content of temp.xml.
This conflicts with the XQuery recommendation which says:
If VarValue
is specified, then the initial context item is the result of evaluating VarValue
.
Note:
In such a case, the initial context item does not obtain its value from the external environment. If the external environment attempts to provide a value for the initial context item, it is outside the scope of this specification whether that is ignored, or results in an error.
It seems we have two options, ignoring the -s option or rejecting it as an error; using the value (which we do) is not an option.
For both XQuery and XSLT, we keep information about the context item requirement in a GlobalContextRequirement
object (whose fields are not especially well documented or clearly named). The fields (with their apparent meaning) are:
requiredItemTypes (XQuery allows more than one, in different modules)
defaultValue (XQuery only)
mayBeOmitted
absentFocus
In XSLT, use=required sets mayBeOmitted=false, absentFocus=false. use=optional sets mayBeOmitted=true, absentFocus=false. use=absent sets mayBeOmitted=true, absentFocus=true.
In XQuery, it seems there is a combination not possible in XSLT: there is a context item, but it cannot be specified externally. I'm not sure we can actually represent that combination in the GlobalContextRequirement
object currently.
The XQuery spec isn't very clear what happens if you specify "declare context item external" with no default value, and no value is supplied externally. The analogy with external variables suggests that it's an error. So the possible options seem to be:
- := value --> there will always be a context item, the value cannot be supplied externally
- external := value --> there will always be a context item, if none is supplied externally then the default is used
- external --> there will always be a context item, it must be supplied externally.
This turns out not to be a very good correspondence to the XSLT options:
- req --> there will always be a context item, it must be supplied externally.
- opt --> there may or may not be a context item, if there is then it will be supplied externally
- pro --> there will be no context item
The options in the two languages are so different it's probably a mistake to try and fit them into the same mould.
A progress report on this: I attempted a rewrite of GlobalContextRequirement to refactor the different options and make them consistent. But it caused a surprising number of problems. (A lot of difficulty with load-xquery-module(), for example.) So for the time being I've rolled the changes back. Will focus now on getting 9.9 out, and come back to this later with a less radical approach to the solution.
- Status changed from New to Resolved
- Fix Committed on Branch 9.8 added
I have added tests to TestXQueryCompiler (9.8) / TestXQueryEvaluator (9.9).
The tests were working in 9.9 as issued; I have retrofitted the changes to 9.8 so it is now working on 9.8 as well. For 9.8, XQueryEvaluator.setContextItem() throws a SaxonApiUncheckedException if the context item is not declared external; for 9.9 this is a normal checked exception.
- Status changed from Resolved to Closed
- Fixed in Maintenance Release 9.8.0.15 added
Bug fix applied in the Saxon 9.8.0.15 maintenance release.
Please register to edit this issue
Also available in: Atom
PDF