Создание XSLT из формул
Ниже приводится список компонентов, необходимых для создания XSLT-функций из формул схемы. Список состоит из файлов с "говорящими" именами. Файлы примеров представлены в виде исходных кодов и будут обсуждаться чуть дальше, а ниже объясняется их роль.
- Файл Schema.xml определяет структуру финансового отчета в терминах исходных и вычисленных элементов. Вычисленный элемент включает использованную формулу; эта формула ссылается на другие элементы схемы (исходные или вычисленные).
- В файле Instance.xml исходным элементам, определенным в файле schema.xml, присваиваются конкретные данные. Данные элемента - это одно или более значений, каждое со своим контекстом (периодом). Этот файл также содержит контексты.
- Файл Compiler.xslt пишется вручную. Он преобразует формулы файла schema.xml в XSLT-файл с именем functions.xslt, где каждая формула становится эквивалентной XSLT-функцией. Файл назван компилятором (compiler), потому что можно провести аналогию с разбором файла schema.xml и генерацией эквивалентных вызываемых XSLT-функций. В результате, каждый файл schema.xml будет компилирован в эквивалентный файл functions.xslt.
Для того чтобы применить формулы, конечному пользователю нужно, чтобы из файла schema.xml создавался совместимый с ним файл instance.xml, а также файл functions.xslt. Функции этих файлов будут вызываться из их собственных XSLT. В исходных кодах файла host.xslt показывается, как используются функции файла functions.xslt.
Взаимодействие этих компонентов показано на рис. 1, который демонстрирует, что XSLT имеет две четко выраженные роли во всем процессе: он используется для компиляции при создании файла functions.xslt, а также для численных расчетов при последующем использовании этого файла. Компиляция должна повторяться после любых изменений в формуле и обычно не имеет временных ограничений. Однако, осуществление численных расчетов, которые могут выполняться в приложении для браузера, персонального компьютера или сервера, должно быть максимально производительным.
Рис.1. Две роли XSLT: создание и вызов функций
Пример: упрощенное использование вычислительного XSLT 2.0
Упрощение заключается в том, что пропущенные (несуществующие) данные рассматриваются как данные, значение которых равно нулю. Файл schema.xml (листинг 1) имеет три исходных элемента и четыре вычисленных. После преобразования в файл functions.xslt (листинг 2) вычисленный элемент становится элементом <xsl:function> с тем же именем. В файле
functions.xslt префикс пространства имен formula используется для этих функций, автоматически генерируемых из формул, для того, чтобы отличать их от фиксированных вспомогательных функций (пространство имен helper), которые они вызывают (см. ниже). Предполагается, что исходные данные в файле instance.xml (листинг 3) - это данные для одной компании.
Структура формульной функции в файле functions.xslt проста: она имеет один параметр context_id, который является индикатором того периода отчета, который вычисляется из файла instance.xml. Она содержит XSLT-переменную для каждого аргумента в формуле элемента и выдает формулу, вычисленную по прописанной схеме. Например, выражение formula:F10 - это формульная функция для следующей операции: <item id="F10" formula="$F1 + $F2" type="calc"/>
Выражение formula:F10 содержит переменные $F1 и $F2, созданные следующим образом: <xsl:variable name="F1" select="helper:get_input_value ( 'F1', $context_id)" as="xs:double"/>
Соответственно, его результатом является: <xsl:sequence select="$F1 + $F2"/>
А вот более сложный пример: <item id="F13" formula="if( ($F10 - $F10_prev) gt 0.01*$F10_prev ) then ($F10 + $F3) else ($F10)" type="calc"/>
В соответствующей функции formula:F13 переменной вычисляемого элемента $F10 присваивается значение путем вызова формульной функции с идентичным именем, параметром которой является context_id: <xsl:variable name="F10" select="formula:F10( $context_id)" as="xs:double"/>
В определении элемента F13 модификатор _prev в выражении $F10_prev указывает, что значение должно относиться к предыдущему контексту. Такие ссылки часто встречаются в финансовых формулах. Соответствующая переменная в выражении formula:F13 создается следующим образом: <xsl:variable name="F10_prev" select="formula:F10(helper:get_ previous($context_id))" as="xs:double"/>
Здесь функция helper:get_previous(context_id) просто выдает значение context_id для периода в один год, предшествующего тому, который был указан.
Если обратиться к исходным кодам, то файл
compiler.xslt (листинг 4) использовался для создания файла functions.xslt из schema.xml; файл host.xslt (листинг 5) показывает, как вызываются функции в файле
functions.xslt; файл calculated_data.xml (листинг 6) показывает результат, который получается при преобразовании instance.xml с помощью файла
host.xslt.
Все эти задачи сравнительно простые, а формулы в файле functions.xslt обладают той же гибкостью, что и формулы XPath 2.0.