Для того чтобы перевести надписи на этих кнопках на другой язык достаточно просто переопределить переменные. Например, результатом выполнения следующего шаблона.
Листинг 5.25. Преобразование de.xsl
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
будет тот же фрагмент, но уже на немецком языке:
С другой стороны, переопределение переменных может быть и опасным: в случае, если отдельные модули разрабатывались независимо, совпадение имен глобальных переменных может привести к ошибкам. Для того чтобы такое было в принципе исключено, имя переменной следует объявлять в определенном пространстве имен, например:
В том случае, если префиксы app
и db
(которые, конечно же, должны быть объявлены) будут указывать на разные пространства имен, никакого конфликта между этими двумя переменными не будет.
Возвращаясь к теме совпадений имен переменных, продемонстрируем "скрытие" локальной переменной значения глобальной:
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
i equals
i equals
Результатом выполнения этого шаблона будет:
i equals 1
i equals 2
Как можно видеть, объявление локальной переменной i
"скрыло" значение глобальной переменной i
. Более того, это преобразование любопытно еще и тем, что локальная переменная объявляется через глобальную — такое тоже допускается.
Рассмотрим теперь случай двух локальных переменных. Попробуем объявить две локальные переменные — одну за другой в следующем шаблоне:
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
i equals
i equals
В тексте этого шаблона мы выделили две области видимости двух переменных: серой заливкой — область видимости первой и полужирным шрифтом — область действия второй переменной. Вследствие того, что эти области пересекаются, шаблон будет некорректным — процессор выдаст сообщение об ошибке вида:
Failed to compile style sheet
At xsl:variable on line 9 of file stylesheet.xsl:
Variable is already declared in this template
Приведем теперь другое преобразование, в котором элементы xsl:variable
принадлежат двум братским элементам:
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
i equals
i equals
В этом случае никакого пересечения областей видимости нет, поэтому и ошибкой наличие в одном шаблоне двух локальных переменных с одинаковыми именами тоже не будет. Приведенное выше преобразование возвратит результат вида:
i equals 1
i equals 2
Как правило, первой реакцией на известие о том, что переменные в XSLT нельзя изменять является реплика: "Да зачем они вообще тогда нужны?!".
Претензия со стороны процедурного программирования вполне серьезна и обоснованна — изменяемые переменные являются большим подспорьем в сложных многошаговых вычислениях. Тем не менее, переменные, даже в том виде, в каком они присутствуют в XSLT, являются очень важным и полезным элементом языка. Ниже мы перечислим наиболее типичные случаи использования переменных.
□ Переменные могут содержать значения выражений, которые много раз используются в преобразовании. Это избавит процессор от необходимости пересчитывать выражение каждый раз по-новому.
□ Переменной может присваиваться результат преобразования, что позволяет манипулировать уже сгенерированными частями документа.
□ Переменные могут использоваться для более прозрачного доступа к внешним документам.
Примеры
Первый случай использования совершенно очевиден: если в преобразовании многократно используется какое-либо сложное для вычисления или просто громоздкое для записи выражение, переменная может служить для сохранения единожды вычисленного результата. Например, если мы много раз обращаемся ко множеству ссылок данного документа посредством выражения вида:
//a[@href]
гораздо удобней и экономней с точки зрения вычислительных ресурсов объявить переменную вида
и использовать ее в преобразовании как $a
. Фильтрующие выражения языка XPath (продукция FilterExpr
) позволяют затем обращаться к узлам выбранного множества так же, как если бы мы работали с изначальным выражением. Например, $a[1]
будет эквивалентно //a[@href][1]
, a $a/@href
— выражению //a[@href]/@href
. При этом при обращении к $a
процессор не будет заново искать все элементы a с атрибутом href
, что, по всей вероятности, положительно скажется на производительности.
Читать дальше