использование fn:path в потоковой передаче

#saxon #xslt-3.0

#saxon #xslt-3.0

Вопрос:

У меня есть накопитель, который используется в потоковой таблице стилей XSLT3. Я хочу использовать fn:path в правиле накопителя, однако я получаю следующую ошибку:

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)

Я не понимаю, почему path() будет запрещен в этом контексте, поскольку потоковый XSLT имеет доступ ко всем предкам соответствующего узла.

 <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>
  

На Saxon EE 9.9.1.7 (кислород)

Ответ №1:

fn:path не удается вычислить позиционные предикаты (например Q{}foo[2] ), поскольку хранятся только предки, но не братья и сестры. So fn:path не является потоковым, https://www.w3.org/TR/xslt-30/#classifying-built-in-functions классифицирует fn:path() – Equivalent to fn:path(.) и fn:path(N) что означает «Навигация».

В 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 Я попытался fn:path заменить некоторые потоковые функции, хранящие «позиции» в аккумуляторах. Код выглядит немного ужасно и нуждается в некоторой доработке, но он дает некоторые полезные результаты при потоковой передаче там, где fn:path это не работает.

В https://xsltfiddle .liberty-development.net/pNmCztr это простой тест, который сравнивает fn:path() = mf:path(.) без потоковой передачи, так что, по крайней мере, вы получите сопоставимые результаты.