Режимы
Режимы
Очень часто в преобразованиях требуется обрабатывать одни и те же узлы, но разными способами. Типичным примером такого рода задачи является генерация оглавления документа вместе с преобразованием его содержимого. Очевидно, что просто шаблонами здесь не обойтись, и чтобы не получить другой результат, нужно каким-то образом указывать, что по-другому должна вестись и обработка.
Эта проблема решается в XSLT просто и элегантно. Атрибут mode элемента xsl:template задает режим этого шаблона. Точно такой же атрибут есть у элемента xsl:apply-templates: в этом элементе он устанавливает режим обработки. При выполнении xsl:apply-templates процессор будет применять только те шаблоны преобразования, режим которых совпадает с выбранным режимом обработки.
Пример
В качестве примера приведем преобразование, которое добавляет в XHTML-файл перечень текстовых ссылок, обнаруженных в этом документе. Грубо говоря, XHTML — это XML-версия языка HTML, а значит XSLT вполне подходит для обработки XHTML-документов.
URI пространства имен языка XHTML — "http://www.w3.org/1999/xhtml"; этому языку мы назначим префикс "xhtml" и, кроме того, сделаем это пространство пространством имен по умолчанию:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml">
...
</xsl:stylesheet>
Начнем с шаблона, который будет выводить каждую из ссылок. В каждой ссылке мы будем выводить только ее атрибут href и текст, который она содержит. Для удобочитаемости мы также добавим элемент br и символ переноса строки 
.
<xsl:template match="xhtml:a">
<xsl:copy>
<xsl:copy-of select="@href|text()"/>
</xsl:copy>
<br/>
<xsl:text>
</xsl:text>
</xsl:template>
Мы чуть позже познакомимся с элементами xsl:copy, xsl:copy-of и xsl:text, пока же скажем, что
<xsl:copy>
<xsl:copy-of select="@href|text()"/>
</xsl:copy>
копирует в выходящий документ текущий узел, его атрибут href (@href) и дочерние текстовые узлы (text()).
Элемент <xsl:text>
</xsl:text> выводит символ переноса строки. Элемент <br/> является литеральным элементом результата — он никак не обрабатывается, а просто выводится в результирующий документ.
Следующее преобразование называется идентичным преобразованием — оно просто копирует все узлы один в один:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
И, наконец, нам понадобится преобразование для элемента body — в него мы включим копию содержимого, а также ссылки, отсортированные в алфавитном порядке:
<xsl:template match="xhtml:body">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<h1>Links found on this page:<h1>
<xsl:apply-templates
select=".//xhtml:a[@href and not(xhtml:*)]">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
Если мы попытаемся выполнить преобразование, состоящее из этих шаблонов, мы обнаружим, что в тексте самого документа ссылки испортились — там тоже добавились элементы br и переносы строк. Это произошло потому, что шаблон для обработки ссылок имеет больший приоритет, чем шаблон, копирующий содержимое документа.
Для исправления этой ошибки мы выделим шаблон обработки ссылок в отдельный режим links:
<xsl:template match="xhtml:a" mode="links">
...
</xsl:template>
Теперь это правило не будет применяться к ссылкам во время копирования содержимого документа, потому что при выполнении инструкции
<xsl:apply-templates select="@*|node()"/>
режим будет пустым, значит шаблон для xhtml:а вызываться не будет. Для того чтобы применить его при помощи xsl:apply-templates, мы добавим в этот элемент атрибут mode:
<xsl:apply-templates
select=".//xhtml:a[@href and not(xhtml:*)]"
mode="links">
<xsl:sort select="."/>
</xsl:apply-templates>
Разберем более подробно это определение. Данная инструкция будет применять шаблоны с режимом links к узлам, возвращаемым выражением ".//xhtml:a[@href and not (xhtml:*)]", отсортированным в алфавитном порядке своих строковых значений. Выражение ".//xhtml:a[@href and not(xhtml:*)]" возвращает всех потомков текущего узла (путь выборки ".//"), которые принадлежат пространству имен xhtml, являются элементами с именами а, (тест имени "xhtml:a"), при этом имеют атрибут href и не включают в себя другие элементы (предикат "[@href and not (xhtml:*)]").
Преобразование целиком будет иметь следующий вид.
Листинг 5.4. Преобразование, добавляющее перечень ссылок
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="xhtml:body">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<h1>Links found on this page:</h1>
<xsl:apply-templates select=".//xhtml:a[@href and not (xhtml:*)]">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xhtml:a">
<xsl:copy>
<xsl:copy-of select="@href|text()"/>
</xsl:copy>
<br/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
Применив это преобразование, например, к главной странице Консорциума W3 (http://www.w3.org), мы получим ее точный дубликат, в конце которого будет приведен перечень всех найденных текстовых ссылок. Выходящий документ будет заканчиваться фрагментом вида:
<h1>Links found on this page:</h1>
<a href="Consortium/">About W3C</a><br/>
<a href="WAI/">Accessibility</a><br/>
<a href="Consortium/Activities">Activities</a><br/>
и так далее.
Заметим, что того же эффекта можно было добиться другими способами, например, при помощи именованных шаблонов или элемента xsl:for-each, однако применение режимов, пожалуй, является наиболее гибкой техникой.
Досадным ограничением режимов является то, что режим нельзя выбирать динамически. Атрибут mode обязан иметь фиксированное значение, то есть вызов вида:
<xsl:apply-templates mode="{$mode}"/>
будет некорректным. Особо серьезных практических противопоказаний для динамических режимов нет, будем надеяться, что в следующих версиях XSLT они появятся.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Режимы наложения
Режимы наложения По умолчанию слой, наложенный на другой, непрозрачными участками полностью перекрывает изображение нижележащего слоя. Данный режим наложения называется Нормальный. Однако программа Adobe Photoshop предлагает несколько различных режимов наложения, при
Режимы
Режимы Программа RoughDraft очень удобна, в первую очередь, для людей творческих профессий: журналистов, писателей, сценаристов и т. д. Ко всем вышеописанным удобствам программа предлагает применение так называемых режимов, которые доступны в меню Mode (Режим).Что такое режим?
Режимы ввода
Режимы ввода Первые модели сотовых телефонов для отправки сообщений имели только один режима ввода. Пользователь нажимал на кнопки телефона в определенном порядке, вводя тот или иной символ. Затем появились другие режимы. В частности, сейчас поддерживается числовой
6.4. Графические режимы
6.4. Графические режимы Операционная система Windows поддерживает пять различных графических режимов, которые позволяют приложениям определять тип смешивания цветов, место и параметры вывода и т. д.:• настройки фона – определяет, как происходит смешивание цветов фона
Режимы
Режимы Очень часто в преобразованиях требуется обрабатывать одни и те же узлы, но разными способами. Типичным примером такого рода задачи является генерация оглавления документа вместе с преобразованием его содержимого. Очевидно, что просто шаблонами здесь не обойтись,
Цветовые режимы
Цветовые режимы Битовая картаВ режиме битовой карты (Bitmap) глубина цвета равна единице, следовательно, каждый пиксел может быть черного или белого цвета. Таким образом, изображение в режиме битовой карты будет монохромным. Файлы изображений, выполненных в режиме битовой
Сюжетные режимы
Сюжетные режимы Чтобы облегчить жизнь владельцев цифровых камер, производители фототехники догадались объединить параметры для типичных сюжетов, объектов и ситуаций съемки в так называемые сюжетные режимы настройки экспозиции. Они позволяют получать отличные снимки,
Режимы протяжки
Режимы протяжки Цифровым камерам (правда, не всем) доступно несколько режимов съемки, аналогичных тем, которые в традиционной фотографии называются режимами протяжки фотопленки. Правда, пленки в вашей цифровой камере нет, и в дальнейшем режимом протяжки мы будем
Режимы фокусировки
Режимы фокусировки Для упрощения работы фотографа расстояния, измеряемые системами автоматической фокусировки, объединены в ступени, или шаги (Stops). К примеру, в недорогих камерах с несложным объективом имеется, как правило, трехступенчатый автофокус, три настройки
10.7. Режимы электропитания
10.7. Режимы электропитания Откройте апплет Управление электропитанием. Вкладка Схемы управления питанием позволяет выбрать одну из схем автоматического отключения питания некоторых компонентов компьютера, например монитора, жестких дисков, или же установить время
Режимы энергосбережения
Режимы энергосбережения Понятие «энергосбережение» используется в компьютерной терминологии достаточно давно. Экономия энергии важна не только для ноутбуков, но и для настольных компьютеров. Конечно, сидя дома за своим ПК, вы не обращаете внимания на то, что он остается
Творческие режимы
Творческие режимы Программный режим Обозначается буквой Р. Это, в общем-то, автоматический режим, но в отличие от Авто он позволяет вам вносить свои изменения во многие выбранные камерой параметры: менять светочувствительность ISO, баланс белого, выбрать режим и точку
Режимы съемки
Режимы съемки Не пытайтесь чрезмерно увеличить светочувствительность, чтобы на фотографии не проявились шумы. Достаточно 50, 100 или 200 единиц ISO, в зависимости от модели камеры. Для получения более качественного изображения это имеет большое значение. Если вы хотите