В XSLT 1.0 нет необходимости в атрибуте select — данные можно заключить внутри самого элемента :
turkey
Формально, однако, при пропуске атрибута select
в элементах или и задании этим элементам содержимого вы создаете фрагмент результирующего дерева, который больше не допускается в XSLT 1.1.
Стоит отметить, что имя переменной может включать префикс, как, например, star:PLANET
, который должен соответствовать активному пространству имен. Сравнения осуществляются не сравнением префиксов, а проверкой фактического URI префикса — поэтому star:PLANET
может быть тем же самым, что и nebula:PLANET
, если пространства имен star
и nebula
соответствуют одному и тому же URI.
Область видимости переменной
Элемент можно использовать как элемент верхнего уровня или внутри тела шаблона для создания переменных. Переменные, созданные в элементах высокого уровня, обладают глобальной областью видимости, созданные в телах шаблона — локальной. Область видимости переменной определяет, в какой части таблицы стилей вы можете ее использовать.
Областью видимости глобальной переменной является вся таблица стилей, подразумевая и импортированные или включенные таблицы стилей. Это означает, что переменная доступна в любом месте таблицы стилей, если только она не будет перекрыта локальной переменной с тем же именем. Можно даже обращаться к глобальной переменной до ее объявления. Однако нельзя создавать циклические ссылки (то есть если вы объявили a
через b
, нельзя объявлять b
через а
).
Область видимости локальной переменной ограничена следующими за ней братьями или потомками последующих братьев. В частности это значит, что если вы объявили переменную внутри таких элементов, как , или , она не будет доступна вне этих элементов.
Как правило, вы не можете изменять значение переменной, но вы можете перекрыть ее локальной переменной. То есть локальные переменные перекрывают глобальные в пределах области видимости локальных переменных. Пусть, например, я объявил переменную с именем movie
(кинокартина):
.
.
.
Это элемент верхнего уровня, поэтому movie
— глобальная переменная. Даже внутри шаблонов movie будет сохранять свое начальное значение, если не будет локальной переменной с таким же именем:
.
.
.
Однако если вы объявите локальную переменную movie, в шаблоне эта версия перекроет глобальную переменную:
.
.
.
В этом случае мы перекрыли глобальную переменную при помощи глобальной. Заметьте, однако, что нельзя снова объявить одну и ту же переменную в одном шаблоне с целью попытаться изменить ее значение:
.
.
.
За пределами шаблона локальная переменная невидима, и movie
содержит глобальное значение:
.
.
.
Глобальные переменные тоже нельзя объявлять повторно:
Несмотря на все эти ограничения, вы можете менять значение переменной на каждом шаге цикла , как мы увидим в следующем разделе.
Давайте рассмотрим примеры применения переменных. В следующем примере (листинг 9.1) я присваиваю переменной copyright
сообщение об авторских правах и затем с ее помощью добавляю атрибут copyright
во все элементы planets.xml
.
Листинг 9.1. Применение переменной
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Вот результирующий документ, дополненный атрибутами copyright
Mercury
.0553
58.65
1516
.983
43.4
Venus
.815
116.75
3716
.943
66.8
.
.
.
Переменные зачастую удобны для хранения значении, зависимых от контекста, и мы сейчас рассмотрим еще один пример, о котором я упоминал в начале главы. В этом случае я преобразую planets.xml
в новый документ, в котором для каждой планеты будет один элемент. Каждый из этих новых элементов будет содержать два элемента , содержащих планеты-братья текущей планеты — например, братьями Земли будут Венера и Меркурий:
Venus
Earth
Mercury
Earth
Mercury
Venus
Для примера я поочередно выбираю каждый элемент и прохожу в цикле по всем планетам, создавая элементы для всех планет, не являющихся контекстным узлом. Однако откуда мне известно внутри элемента , какая из планет является контекстным узлом, выбранным шаблоном? Внутри элемента «.» ссылается на текущий узел, с которым работает , но не на контекстный узел шаблона. Проблему можно решить, если сохранить контекстный узел в переменной, которую я назвал contextnode
:
Читать дальше