With streaming processing, should I be able to match on a map with e.g. match=".[. instance of map(xs:string, xs:decimal)]" and then call map:get(., 'foo') inside the template?
Added by Martin Honnen over 8 years ago
https://www.w3.org/TR/xslt-30/#maps-streaming says
??Because maps cannot contain references to streamed nodes, they are effectively grounded, and can therefore be used freely in contexts (such as parameters to functions or templates) where only grounded operands are permitted.??
so I would expect to be able to use a template matching on a @map@ and access its members inside the template.
A simplified test case is
However, Saxon 9.7.0.7J EE rejects the stylesheet as not being streamable:
Static error at xsl:template on line 22 column 68 of test201608020402.xsl: XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules. * Operand . of map:get(...) selects streamed nodes in a context that allows arbitrary navigation (line 24)
It seems desirable to me that the assessment of the @map:get(., 'lat')@ call in the template takes into account that the operand @.@ is not a streamed node but an instance of @map(xs:string, xs:decimal)@, as tested in the match pattern, but I am not sure the streamability analysis is supposed to take that into account. On the other hand, it seems the first argument to @map:get@ is known to be a map by its signature, that also makes me think the code should be streamable.
Exselt compiles and runs the stylesheet fine.
Is Saxon too rigid here? If not, is there no way to match on a @map@ in a streamable mode and access its members inside the template? Is the only way out to make sure the match on the map is done in a non streamable mode?
An input sample for testing is
Replies (2)
RE: With streaming processing, should I be able to match on a map with e.g. match=".[. instance of map(xs:string, xs:decimal)]" and then call map:get(., 'foo') inside the template? - Added by Michael Kay over 8 years ago
This should indeed be streamable, by virtue of the fact that the operand usages for map:get() are given in the spec as
map:get(I, A)
So the first operand should be usage inspection but Saxon is treating it as usage navigation. With inspection usage, the map:get() call becomes motionless and the template rule is therefore streamable.
Fixing this in 9.7 is non-trivial because the map functions are implemented as "intrinsic extension functions" using the ExtensionFunctionDefinition API, and this API does not give any opportunity to declare operand usages for the function arguments.
The implementation has changed on the 9.8 branch so these functions are implemented as system functions, which does allow the usage to be declared. I'm therefore going to treat this as an unimplemented feature rather than a bug, and fix it only in 9.8.
I've committed this test case as streamable-140.
RE: With streaming processing, should I be able to match on a map with e.g. match=".[. instance of map(xs:string, xs:decimal)]" and then call map:get(., 'foo') inside the template? - Added by Michael Kay over 8 years ago
I've now added (on the 9.8 branch only) operand usages for all the map and array functions. Testing them all could be a bit laborious...
Please register to reply