</xsl:stylesheet>
будет тот же фрагмент, но уже на немецком языке:
<input type='button' value='Senden'/>
<input type='reset' value='Loeschen'/>
С другой стороны, переопределение переменных может быть и опасным: в случае, если отдельные модули разрабатывались независимо, совпадение имен глобальных переменных может привести к ошибкам. Для того чтобы такое было в принципе исключено, имя переменной следует объявлять в определенном пространстве имен, например:
<xsl:variable name='app:href' select='...'/>
<xsl:variable name='db:href' select='...'/>
В том случае, если префиксы app и db (которые, конечно же, должны быть объявлены) будут указывать на разные пространства имен, никакого конфликта между этими двумя переменными не будет.
Возвращаясь к теме совпадений имен переменных, продемонстрируем 'скрытие' локальной переменной значения глобальной:
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:variable name='i' select='1'/>
<xsl:template match='/'>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
<xsl:text>
</xsl:text>
<xsl:variable name='i' select='$i + 1'/>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
</xsl:template>
</xsl:stylesheet>
Результатом выполнения этого шаблона будет:
i equals 1
i equals 2
Как можно видеть, объявление локальной переменной i 'скрыло' значение глобальной переменной i. Более того, это преобразование любопытно еще и тем, что локальная переменная объявляется через глобальную — такое тоже допускается.
Рассмотрим теперь случай двух локальных переменных. Попробуем объявить две локальные переменные — одну за другой в следующем шаблоне:
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='/'>
<xsl:variable name='i' select='1'/>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
<xsl:text>
</xsl:text>
<xsl:variable name='i' select='2'/>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
</xsl:template>
</xsl:stylesheet>
В тексте этого шаблона мы выделили две области видимости двух переменных: серой заливкой — область видимости первой и полужирным шрифтом — область действия второй переменной. Вследствие того, что эти области пересекаются, шаблон будет некорректным — процессор выдаст сообщение об ошибке вида:
Failed to compile style sheet
At xsl:variable on line 9 of file stylesheet.xsl:
Variable is already declared in this template
Приведем теперь другое преобразование, в котором элементы xsl:variable принадлежат двум братским элементам:
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='/'>
<p>
<xsl:variable name='i' select='1'/>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
</p>
<p>
<xsl:variable name='i' select='2'/>
<xsl:text>i equals </xsl:text>
<xsl:value-of select='$i'/>
</p>
</xsl:template>
</xsl:stylesheet>
В этом случае никакого пересечения областей видимости нет, поэтому и ошибкой наличие в одном шаблоне двух локальных переменных с одинаковыми именами тоже не будет. Приведенное выше преобразование возвратит результат вида:
<p>
i equals 1
</p>
<p>
i equals 2
</p>
Использование переменных
Как правило, первой реакцией на известие о том, что переменные в XSLT нельзя изменять является реплика: 'Да зачем они вообще тогда нужны?!'.
Претензия со стороны процедурного программирования вполне серьезна и обоснованна — изменяемые переменные являются большим подспорьем в сложных многошаговых вычислениях. Тем не менее, переменные, даже в том виде, в каком они присутствуют в XSLT, являются очень важным и полезным элементом языка. Ниже мы перечислим наиболее типичные случаи использования переменных.
□ Переменные могут содержать значения выражений, которые много раз используются в преобразовании. Это избавит процессор от необходимости пересчитывать выражение каждый раз по-
