Перейти к содержанию

xsl:accumulator

Накопитель определяет некоторую обработку, которая должна происходить во время последовательной обработки документа: например, общее количество, которое должно быть накоплено.

Доступно в XSLT 3.0. Начиная с Saxon 9.8, доступен во всех изданиях. Реализовано в Saxon-PE и Saxon-EE начиная с Saxon 9.5.

Атрибуты

name
eqname
Определяет имя для аккумулятора.
initial-value
expression
Определяет начальное значение аккумулятора.
as?
sequence-type
Определяет тип переменной аккумулятора; по умолчанию item()*.
streamable?
boolean
Запрашивает потоковую оценку аккумулятора, если установлено значение yes. Требуется Saxon-EE.
saxon:trace?
boolean
Вызывает вывод сообщения трассировки (в логгер конфигурации) при каждом изменении значения аккумулятора. Сообщение включает имя аккумулятора, путь к узлу и новое значение аккумулятора. Подробности см. в saxon:trace.

Заметки по реализации Saxon

Saxon-HE и -PE поддерживают непотоковую реализацию; Saxon-EE дополнительно поддерживает потоковую реализацию.

Saxon имеет две совершенно отдельные реализации, одна для потоковых документов, другая для непотоковых. Накопители активно оцениваются для каждого потокового документа, к которому они применимы, но для непотоковых документов они оцениваются только по запросу (первый вызов функции накопителя для конкретного документа запускает оценку накопителя вплоть до данного узла). Значение накопителя для каждого непотокового узла хранится вместе с узлом, используя структуру данных, которая позволяет учесть тот факт, что значение накопителя часто будет меняться лишь изредка по мере прохождения документа.

Подробности

Накопители обусловлены необходимостью потоковой обработки, но они могут быть полезны и независимо от потоковой обработки. Смысл в том, что при обработке документа с помощью потоковой передачи вы видите каждый узел только один раз, поэтому вполне вероятно, что вам нужно запомнить то, что вы видели, чтобы использовать это позже. Накопители обеспечивают такую память.

Идея аккумуляторов состоит в том, чтобы определить некоторую обработку, которая должна происходить во время последовательной обработки документа: например, общее количество, которое должно накапливаться. Семантика определяется в терминах обхода дерева, представляющего документ, причем каждый узел посещается один раз перед обходом его поддерева и еще раз после обработки поддерева. При каждом посещении (как при посещении до, так и после) можно определить правила (используя xsl:accumulator-rule), которые активируются, и действие которых заключается в вычислении нового значения для аккумулятора на основе предыдущего значения и данных, видимых в обрабатываемом узле. Выражение, используемое для вычисления нового значения, должно быть "неподвижным", то есть оно должно вычисляться без изменения текущей позиции потокового ввода.

Аккумуляторы имеют процедурный характер, поскольку состояние аккумулятора изменяется по мере обработки документа. Тем не менее, они функционально "чисты": значение аккумулятора в определенном узле является чистой функцией этого узла. Любители функционального программирования узнают аккумуляторы как нечто очень похожее на операцию "сложения", которая часто используется для поочередного применения операции к каждому элементу последовательности.

Аккумулятор доступен через две функции: функцию предварительного понижения accumulator-before() и функцию последующего понижения accumulator-after(). Эти функции могут быть вызваны с указанием аккумулятора в качестве аргумента, чтобы получить значение аккумулятора для контекстного узла до обработки его дочерних узлов и после обработки его дочерних узлов. Иногда единственным значением, представляющим интерес, является значение после спуска для узла документа, то есть значение аккумулятора после обработки всего документа.

Аккумуляторы (в отличие от элементов xsl:key) применимы к некоторым исходным документам и не применимы к другим; правила можно найти в Applicability of Accumulators.

Примеры

Спецификация XSLT 3.0 содержит ряд примеров, иллюстрирующих использование аккумуляторов, и изучение этих примеров, вероятно, лучший способ получить представление об этой функции.

Ссылки

См. также

Комментарии