Handling null and undefined objects in ixsl:get() and ixsl:set-property
(Having already spent lots of time working on this, it's time to try to get the issues in writing.)
We need to clarify how
ixsl:set-property. Both the code and documentation need work.
Currently the documentation for
If the specified object or property does not exist, then the function returns the empty sequence (with a console log warning in the latter case). (Note the difference to the similar function
ixsl:call(), for which a run-time error is raised in this case.)
An error will be raised at run-time if the specified object does not exist or is not unique. If the specified property does not exist, then there is no error, but a warning is output in the console log.
Note that the property name string supplied to
ixsl:set-property can be a dot separated list of names to access a nested property; but we are not clear about what happens when we encounter null or undefined objects in such a nested chain of objects.
For instance consider
ixsl:get($object, 'a.b.c') and
$object.a.b returns null or undefined? Currently if either of these is null, Saxon-JS 2.2 crashes with an uncaught TypeError, so there is definitely a bug here.
#1 Updated by Debbie Lockett 2 months ago
However it would then be inconsistent not to throw an error if the initial object is null or undefined; i.e.
ixsl:get($object, 'prop') should throw an error if
$object is null or undefined. This would be a change in behaviour for Saxon-JS, which could potentially cause problems from unexpected errors in existing applications.
Note that we did previously look into what to do in this case (see Bug #3501: Error when object supplied to ixsl:get() is null), but it now seems that that solution was not fully thought through. At that time we decided that it would make sense for
ixsl:get($object, 'prop') to return the empty sequence when
$object is null; so that we get the same result as when using the lookup operator:
$object?prop. Note that by the XPath specification,
()?prop always returns the empty sequence.
However, we subsequently clarified that
ixsl:get($object, 'prop') and
$object?prop are not always equivalent; see
In order to use this
$objectis treated as a JSValue wrapped external object.
And this specifically points out that you may not get the same result for null or undefined objects!
#2 Updated by Debbie Lockett 2 months ago
If we amend the definition of
ixsl:set-property, for which we already specify that the supplied object must exist. We should update the function signature to reflect this to provide the correct cardinality check - which means a change in
IXSLFunctionSet.java for Saxon on Java, and in
lib/xpath/xsltData.js for the XX compiler.
#3 Updated by Debbie Lockett 2 months ago
- Saxon-JS code changes (in ExtraFn.js and lib/xpath/xsltData.js)
- New selenium browser tests: ixsl/get20; ixsl2/getlookup20, getlookup20b
- Updated results for tests ixsl/getEmpty01, getEmpty02, getEmpty04
These now all align with the proposed solution above.
I have not yet done the following:
- Commit update to IXSLFunctionSet.java for Saxon on Java
- Documentation updates
#5 Updated by Debbie Lockett about 2 months ago
- Status changed from Resolved to In Progress
Reopened because the new logic (that we should always throw an error if we ever attempt to get a property of null or undefined; in particular when accessing nested properties) is also relevant to
#6 Updated by Debbie Lockett about 1 month ago
- Status changed from In Progress to Resolved
New logic also applied for
ixsl:remove-property; so marking resolved again.
- New selenium browser tests: ixsl/call20, ixsl/contains20, ixsl/removeProperty20
- Saxon-JS code changes (in ExtraFn.js)
- Further documentation updates
Please register to edit this issue