Книга: XSLT
Режимы: форматирование в зависимости от контекста
Разделы на этой странице:
Режимы: форматирование в зависимости от контекста
В некоторых случаях выбор узлов может требовать буквально мастерства. Например, шаблон с условием выбора «*» выбирает и «PLANET». Если вам нужно обрабатывать элементы <PLANET>
по-другому, чем все остальные элементы, вы можете задать шаблон, выбирающий «PLANET
»; тогда процессор XSLT определит, что «PLANET
» ближе к элементу <PLANET>
, чем «*», и воспользуется правилом выбора «PLANET
». Но не всегда все так просто. Например, вам может быть нужно, чтобы правило «PLANETS
» выбирало не все, а лишь некоторые элементы <PLANET>
. Один из способов решения этой задачи — воспользоваться режимами (mode).
Для задания режима обработки служит атрибут mode
элемента <xsl:apply-templates>
. При задании режима будут применяться только те шаблоны, элементы <xsl:template>
, атрибут mode
которых установлен в тот же режим. Таким образом, при помощи шаблона можно выбрать только один определенный узел, даже если в ином случае они бы выбирали много узлов. Это очень удобно, если, например, нам нужно обработать какие-то элементы <PLANET>
отлично от других.
Рассмотрим пример. Здесь я создал новый режим обработки данных планет «fancy» (красивый), отображающий данные полужирным шрифтом. Но я хочу, чтобы полужирным выделялись только данные Земли, а не других планет. Это может составить проблему: поскольку все данные планет хранятся в одном типе элемента — <PLANET>
, — постольку образец «PLANET
» выберет их все. Режим решает это затруднение. В частности, если текущая планета — Земля, я могу установить режим обработки в «fancy
»:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/PLANETS">
<HTML>
<HEAD>
<TITLE>
The Planets Table
</TITLE>
</HEAD>
<BODY>
<H1>
The Planets Table
</H1>
<TABLE BORDER="2">
<TR>
<TD>Name</TD>
<TD>Mass</TD>
<TD>Radius</TD>
<TD>Day</TD>
</TR>
<xsl:apply-templates/>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="PLANET">
<xsl:if test="NAME='Earth'">
<TR>
<TD><xsl:apply-templates select="NAME" mode="fancy"/></TD>
<TD><xsl:apply-templates select="MASS" mode="fancy"/></TD>
<TD><xsl:apply-templates select="RADIUS" mode="fancy"/></TD>
<TD><xsl:apply-templates select="DAY" mode="fancy"/></TD>
</TR>
</xsl:if>
<xsl:if test=NAME!='Earth'">
<TR>
<TD><xsl:apply-templates select="NAME"/></TD>
<TD><xsl:apply-templates select="MASS"/></TD>
<TD><xsl:apply-templates select="RADIUS"/></TD>
<TD><xsl:apply-templates select="DAY"/></TD>
</TR>
</xsl:if>
</xsl:template>
.
.
.
После этого я устанавливаю нужные правила шаблона (листинг 6.13), оба для режима обработки «fancy
», который выделяет выходные данные полужирным, и не задаю никакого специального режима обработки.
Листинг 6.13. Применение режимов
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/PLANETS">
<HTML>
<HEAD>
<TITLE>
The Planets Table
</TITLE>
</HEAD>
<BODY>
<H1>
The Planets Table
</H1>
<TABLE BORDER="2">
<TR>
<TD>Name</TD>
<TD>Mass</TD>
<TD>Radius</TD>
<TD>Day</TD>
</TR>
<xsl:apply-templates/>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="PLANET">
<xsl:if test="NAME='Earth'">
<TR>
<TD><xsl:apply-templates select="NAME" mode="fancy"/></TD>
<TD><xsl:apply-templates select="MASS" mode="fancy"/></TD>
<TD><xsl:apply-templates select="RADIUS" mode="fancy"/></TD>
<TD><xsl:apply-templates select="DAY" mode="fancy"/></TD>
</TR>
</xsl:if>
<xsl:if test=NAME!='Earth'">
<TR>
<TD><xsl:apply-templates select="NAME"/></TD>
<TD><xsl:apply-templates select="MASS"/></TD>
<TD><xsl:apply-templates select="RADIUS"/></TD>
<TD><xsl:apply-templates select="DAY"/></TD>
</TR>
</xsl:if>
</xsl:template>
<xsl:template match="NAME">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="MASS">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select="@UNITS"/>
</xsl:template>
<xsl:template match="RADIUS">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select="@UNITS"/>
</xsl:template>
<xsl:template match="DAY">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select=@UNITS"/>
</xsl:template>
<xsl:template match="NAME" mode="fancy">
<B><xsl:value-of select="."/></B>
</xsl:template>
<xsl:template match="MASS" mode="fancy">
<B>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select="@UNITS"/>
</B>
</xsl:template>
<xsl:template match="RADIUS" mode="fancy">
<B>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select="@UNITS"/>
</B>
</xsl:template>
<xsl:template match="DAY" mode="fancy">
<B>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:value-of select="@UNITS"/>
</B>
</xsl:template>
</xsl:stylesheet>
Вот результат. Заметьте, что одни только данные Земли выделены полужирным:
<HTML>
<HEAD>
<TITLE>
The Fancy Planets Table
</TITLE>
</HEAD>
<BODY>
<H1>
The Fancy Planets Table
</Н1>
<TABLE BORDER="2">
<TR>
<TD>Name</TD>
<TD>Mass</TD>
<TD>Radius</TD>
<TD>Day</TD>
</TR>
<TR>
<TD>Mercury</TD>
<TD>.0553 (Earth = 1)</TD>
<TD>1516 miles</TD>
<TD>58.65 days</TD>
</TR>
<TR>
<TD>Venus</TD>
<TD>.815 (Earth = 1)</TD>
<TD>3716 miles</TD>
<TD>116.75 days</TD>
</TR>
<TR>
<TD><B>Earth</B></TD>
<TD><B>1 (Earth = 1)</B></TD>
<TD><B>2107 miles</B></TD>
<TD><B>1 days</B></TD>
</TR>
</TABLE>
</BODY>
</HTML>
Этот документ показан на рис. 6.4.
Рис. 6.4. Применение режимов обработки
Режимы также очень удобны в том случае, когда требуется обработать один и тот же документ более одного раза; классический пример — создание оглавления.
Следующий пример демонстрирует создание оглавления. Я добавил в planets.xml
оглавление в элементе <TOC>
(table of contents, оглавление), имеющем три элемента <ENTRY>
для каждой из планет. Заметьте, что здесь мне необходимо применить два шаблона, выбирающие элементы <PLANET>
, — один для создания оглавления и еще один для копирования всех элементов <PLANET>
в результирующий документ — я использую режимы для того, чтобы их различать. Начну с установки режима в «toc
» и применения шаблона, который поддерживает этот режим и создает оглавление:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http//www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="PLANETS">
<PLANETS>
<TOC>
<xsl:apply-templates mode="toc"/>
</TOC>
.
.
.
</PLANETS>
</xsl:template>
<xsl:template match="PLANET" mode="toc">
<ENTRY>
<xsl:value-of select="NAME"/>
</ENTRY>
</xsl:template>
.
.
.
Затем я применяю общий шаблон без каких-либо режимов обработки ко всем элементам и атрибутам, копируя их в результирующий документ (листинг 6.14).
Листинг 6.14. Создание оглавления
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="PLANETS">
<PLANETS>
<TOC>
<xsl:apply-templates mode="toc"/>
</TOC>
<xsl:apply-templates select="@*|node()"/>
</PLANETS>
</xsl:template>
<xsl:template match="PLANET" mode="toc">
<ENTRY>
<xsl:value-of select="NAME"/>
</ENTRY>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
И, наконец, результат, выводящий planets.xml
с оглавлением:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="planets.xsl"?>
<PLANETS>
<TOC>
<ENTRY>Mercury</ENTRY>
<ENTRY>Venus</ENTRY>
<ENTRY>Earth</ENTRY>
</TOC>
<PLANET>
<NAME>Mercury</NAME>
<MASS UNITS="(Earth = 1)">.0553</MASS>
<DAY UNITS="days">58.65</DAY>
<RADIUS UNITS="miles">1516</RADIUS>
<DENSITY UNITS="(Earth = 1)">.983</DENSITY>
<DISTANCE UNITS="million miles">43.4</DISTANCE><!--В перигелии->
</PLANET>
.
.
.
</PLANETS>
В этой главе мы рассмотрели большую часть базового материала, и в следующей главе я собираюсь уделить внимание созданию полных выражений XPath. Хотя вы уже немного знакомы с этой темой по обсуждению образцов выбора в главе 4, нам осталось еще рассмотреть весьма значительную часть.
- Элемент
- Изменение структуры документа на основе входных данных
- Элемент : создание новых элементов на этапе выполнения
- Элемент : создание новых атрибутов
- Элемент : создание комментариев
- Элемент : создание инструкций обработки
- Элемент : создание нескольких выходных документов
- Элемент : создание объявлений пространств имен
- Элемент : создание наборов атрибутов
- Пропуск объявления XML и создание фрагментов XML
- Создание уникальных идентификаторов при помощи generate-id
- Создание разделов CDATA
- Установка кодировки символов
- Режимы: форматирование в зависимости от контекста
- Границы контекста объекта
- 8.5.3. Режимы энергосбережения
- 1. Ограничение функциональной зависимости
- 4. Режимы работы экспертных систем
- 1.1 Режимы ядра и пользователя Windows
- Как в документ Microsoft Word вставить текст, в котором отсутствует форматирование?
- Трюки с форматированием
- 2.9. Форматирование строк
- Чем отличается быстрое форматирование от обычного?
- Как сбросить форматирование текста в Microsoft Word?
- 4.20. Форматирование дискет в Linux
- Режимы работы проигрывателя