Reputation: 105
I have a accumulator which is used in a streaming XSLT3 stylesheet. I want to use the fn:path in the accumulator rule, however, I get the following error:
The xsl:accumulator-rule/@select expression (or contained sequence constructor) for a streaming accumulator must be grounded and motionless. Operand {.} of {fn:path(...)} selects streamed nodes in a context that allows arbitrary navigation (line XX)
I don't see why path() would be disallowed in this context, as streaming XSLT has access to all ancestors of the matched node.
<xsl:accumulator name="schxslt:tracking"
as="map(xs:string, xs:string)"
initial-value="map{}"
streamable="yes">
<xsl:accumulator-rule match="someNode"
select="map:put($value,current()/path(),'')"
phase="start"/>
</xsl:accumulator>
On Saxon EE 9.9.1.7 (Oxygen)
Upvotes: 0
Views: 78
Reputation: 167716
fn:path
can't compute the positional predicates (e.g. Q{}foo[2]
) as only ancestors but not siblings are stored. So fn:path
is not streamable, https://www.w3.org/TR/xslt-30/#classifying-built-in-functions classifies fn:path() – Equivalent to fn:path(.)
and fn:path(N)
which means "Navigation".
In https://github.com/martin-honnen/schxslt/blob/release-1.4.6-xslt3-streaming-test/src/main/resources/xslt/3.0-streamable/streaming-utilities/position-accumulator.xsl I have tried to replace fn:path
with some streamable functions storing "positions" in accumulators. The code looks a bit awful and needs some polishing but it does give some useful results with streaming where fn:path
doesn't work.
At https://xsltfiddle.liberty-development.net/pNmCztr is a simple test that compares fn:path() = mf:path(.)
without streaming so there at least you get comparable results.
Upvotes: 0