В 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:
Читать дальше