В это преобразование мы добавили еще одно шаблонное правило:
Это правило определяет обработку корневого узла — в атрибуте match
указан паттерн "/"
, что соответствует корню документа. Шаблон создает элементы html
, head
, title
, body
и в последний включает результат применения шаблонов к элементу msg
. Сравнивая тело этого шаблона с результатом выполнения преобразования, можно заметить, что процессор скопировал все элементы, не принадлежащие XSLT, не изменяя их, а элемент xsl:apply-templates
выполнил, применив шаблон к элементу msg
и включив в body
результат (он выделен в листинге полужирным шрифтом).
Продемонстрированная возможность вызова одних правил из других, а также наличие в XSLT таких управляющих конструкций, как xsl:if
, xsl:choose
и xsl:for-each
позволяет простым набором правил реализовывать очень сложную логику преобразования. В XSLT применяется один из основных принципов эффективной разработки: для того чтобы решить задачу, нужно разбить ее на более мелкие части и решить каждую из них по отдельности. Проблемой в данном случае является преобразование, и вместо того, чтобы описывать его целиком, XSLT позволяет определить простые правила обработки каждой из частей, связав эти правила логикой взаимных вызовов и управляющих конструкций.
Отсутствие "побочных" эффектов
Одним из краеугольных принципов XSLT, с которым, увы, нелегко смириться разработчику, работавшему только с процедурными языками, — это отсутствие "побочных" эффектов. Под побочными эффектами в данном случае понимаются изменения в окружении преобразования, которые отражаются на дальнейшем его выполнении.
Концепция отсутствия побочных эффектов берет начало в функциональном программировании, а оно, в свою очередь, в "чистых" математических функциях, не изменяющих своего окружения в процессе вычисления. Например, функция
f ( x , у ) > вернуть x + у ;
будет чистой функцией. Сколько бы раз мы ее не вызывали, ее результат все равно будет равен сумме аргументов. Кроме того, результат вычисления f ( f ( x 1, y 1), f ( x 2, y 2)) будет равен x 1+ y 1+ x 2+ y 2, в каком бы порядке мы не вычисляли эти функции:
f ( f ( x 1, y 1), f ( x 2, y 2)) = f ( x 1+ y 1, f ( x 2, y 2)) = x 1+ y 1+ f ( x 2, y 2) = x 1+ y 1+ x 2+ y 2
f ( f ( x 1, y 1), f ( x 2, y 2)) = f ( f ( x 1, y 1), x 2+ y 2) = f ( x 1, y 1) + x 2+ y 2= x 1+ y 1+ x 2+ y 2
f ( f ( x 1, y 1), f ( x 2, y 2)) = f ( x 1, y 1) + f ( x 2, y 2) = x 1+ y 1+ f ( x 2, y 2) = x 1+ y 1+ x 2+ y 2
и так далее.
Представим теперь похожую функцию, обладающую побочным эффектом:
f ( x , у ) → z присвоить x ; увеличить z на у ; вернуть z ;
В данном случае побочный эффект состоит в изменении значения переменной z . В этом случае результат вычисления выражения f ( z , f ( x , у )) строго зависит от того, в каком порядке будут вычисляться функции — в одних случаях результатом будет x + у + z , в других 2∙ x + 2∙ у . Для того чтобы результат вычислений с побочными эффектами был детерминирован, требуется строгая определенность в порядке действий. В XSLT же эта строгая определенность отсутствует, преобразование — это набор правил, а не последовательность действий.
Таковы теоретические посылки отсутствия побочных эффектов. Главным практическим ограничением является то, что преобразования не могут во время выполнения изменять переменные — после того, как переменной присвоено некоторое начальное значение, измениться оно больше не может.
Сильнее всего это ограничение сказывается на стиле XSLT-программирования. Он становится ближе к функциональному стилю таких языков, как Lisp и Prolog. Научиться соответствовать этому стилю просто, хотя поначалу он и будет казаться неудобным.
Слово extensible (англ. расширяемый) в расшифровке аббревиатуры XSLT исторически происходит из названия языка XSL, но оно вполне применимо и к самому XSLT: спецификация этого языка позволяет разрабатывать собственные функции и элементы и использовать их в преобразованиях.
Применительно к преобразованиям структуры, XSLT является чрезвычайно мощным языком, но в то же время вычислительная его часть страдает. В языке XPath, на который переложена задача вычислений в XSLT, есть основные арифметические и логические операторы, небольшая базовая библиотека функций для работы с различными типами данных — но не более. XPath мало подходит для действительно сложных вычислительных задач. Что касается самого XSLT, набор элементов этого языка можно назвать вполне достаточным для большинства задач. Но и тут встречаются приложения (и разработчики), которые требуют большего.
Читать дальше