J. Nicholas
J. Nicholas

Reputation: 105

use of fn:path in streaming

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

Answers (1)

Martin Honnen
Martin Honnen

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

Related Questions