Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

//a[@href]

гораздо удобней и экономней с точки зрения вычислительных ресурсов объявить переменную вида

<xsl:variable name="links" select="//a[@href]"/>

и использовать ее в преобразовании как

$a
. Фильтрующие выражения языка XPath (продукция
FilterExpr
) позволяют затем обращаться к узлам выбранного множества так же, как если бы мы работали с изначальным выражением. Например,
$a[1]
будет эквивалентно
//a[@href][1]
, a
$a/@href
— выражению
//a[@href]/@href
. При
этом при обращении к
$a
процессор не будет заново искать все элементы a с атрибутом
href
, что, по всей вероятности, положительно скажется на производительности.

Другой иллюстрацией этому же случаю использования переменной может быть следующая ситуация: в некоторых случаях выражения могут быть просты для вычисления, но слишком громоздки для записи. Гораздо элегантней один раз вычислить это громоздкое выражение, сохранить его в переменной и затем обращаться по короткому имени. Например, следующий элемент

xsl:variable
вычисляет и сохраняет в переменной
gv
длинную и громоздкую ссылку:

<xsl:variable name="gv"

 select="concat('http://host.com:8080/GeoView/GeoView.jsp?',

 'Language=en&amp;',

 'SearchText=Select&amp;',

 'SearchTarget=mainFrame&amp;',

 'SearchURL=http://host.com:8080/servlet/upload')"/>

После такого определения применение этой ссылки в преобразовании становится удобным и лаконичным:

<а href="#" target="_blank">Launch GeoBrowser</a>

Второй типовой случай использования переменных также заметно облегчает создание выходящего дерева, делая этот процесс гибким и легко конфигурируемым. Примером формирования HTML-документа при помощи такого подхода может быть следующий шаблон:

<xsl:template match="/">

 <html>

<xsl:copy-of select="$head"/>

<xsl:copy-of select="$body"/>

 </html>

</xsl:template>

Достоинство этого подхода в том, что переменные, содержащие фрагменты деревьев как бы становятся модулями, блоками, из которых в итоге собирается результирующий документ.

Более практичным применением возможности переменных содержать фрагменты деревьев является условное присвоение переменной значения. Представим себе следующий алгоритм:

если

 условие1

то

 присвоить переменной1 значение 1

иначе

 присвоить переменной1 значение2

Для процедурного языка с изменяемыми переменными это не проблема. На Java такой код выглядел бы элементарно:

переменная1 = условие1 ? значение1 : значение2;

или чуть в более длинном варианте:

if (условие1)

 переменная1 = значение1;

else

 переменная1 = значение2;

Однако

если бы в XSLT мы написали что-нибудь наподобие:

<xsl:choose>

 <xsl:when test="условие1">

<xsl:variable name="переменная1" select="значение1"/>

 </xsl:when>

 <xsl:otherwise>

<xsl:variable name="переменная1" select="значение2"/>

 </xsl:otherwise>

</xsl:choose>

то требуемого результата все равно не достигли бы по той простой причине, что определенные нами переменные были бы доступны только в своей области видимости, которая заканчивается закрывающими тегами элементов

xsl:when
и
xsl:otherwise
. Правильный шаблон для решения этой задачи выглядит следующим образом:

<xsl:variable name="переменная1">

 <xsl:choose>

<xsl:when test="условие1">

<xsl:copy-of select="значение1"/>

</xsl:when>

<xsl:otherwise>

<xsl:copy-of select="значение2"/>

</xsl:otherwise>

 </xsl:choose>

<xsl:variable>

Конечно, это не точно то же самое — на самом деле мы получаем не значение, а дерево, содержащее это значение, но для строковых и численных значений особой разницы нет: дерево будет вести себя точно так же, как число или строка. Для булевых значений и множеств узлов приходится изыскивать другие методы. Булевое значение можно выразить через условие, например:

<xsl:variable name="переменная 1"

 select="(значение 1 and условие1) or (значение2 and not(условие2))"/>

Для множества узлов можно использовать предикаты и операции над множествами:

<xsl:variable name="переменная1"

 select="значение1[условие1] | значение2[not(условие2)]"/>

Заметим, что шаблон, содержащийся в элементе

xsl:variable
, может включать в себя такие элементы, как
xsl:call-template
,
xsl:apply-templates
и так далее. То есть переменной можно присвоить результат выполнения одного или нескольких шаблонов.

Использование внешних документов в преобразовании, как правило, сопровождается громоздкими выражениями вида:

document('http://www.xmlhost.com/docs/а.xml')/page/request/param

и так далее.

Поделиться с друзьями: