Стивен Холзнер - XSLT
<xsl:template match="RADIUS">
<TD xsl:version="1.0">RADIUS</TD>
</xsl:template>
В следующем списке перечислены все возможные атрибуты элемента буквального результата:
• Attribute Value Templates, шаблон значений атрибута (необязательный). Любые выражения XPath в фигурных скобках вычисляются, и результат в виде строкового значения копируется в атрибут в результирующем дереве. Устанавливается в шаблон значений атрибута (см. главу 3);
• xsl:exclude-result-prefixes (необязательный). Определяет, какие пространства имен не будут скопированы в результирующее дерево. Принимает значения списка префиксов пространств имен, разделенных символами- разделителями;
• xsl:extension-element-prefixes (необязательный). Заставляет процессор XSLT трактовать дочерние элементы элемента буквального результата в перечисленных пространствах имен как элементы расширения, а не элементы буквального результата;
• xsl:use-attribute-sets (необязательный). Атрибуты в перечисленных наборах атрибутов добавляются в элемент буквального результата и копируются в результирующее дерево. Принимает значение списка QName, идентифицирующих поименованные элементы <xsl:attribute-set>;
• xsl:version (необязательный). Устанавливает версию элементов XSL в элементе буквального результата. Принимает численное значение.
Теперь можно начать работать с этой информацией.
Совпадающие элементы в шаблонах
Для указания того, с каким узлом или узлами вы хотите работать в шаблоне, в XSLT имеются разнообразные способы поиска или выбора узлов. Следует установить атрибут match элемента <xsl:template> в образец (pattern), определяющий имя узла или узлов, с которыми вы хотите работать. В главе 3, посвященной шаблонам, будет показано, как создавать образцы. Например, образец «/» соответствует корневому узлу; образец «*» задает любой узел элемента; образцу «PLANET» удовлетворяют все узлы элемента <PLANET> и т.д.
Для начала я создал короткий пример, заменяющий корневой узел, — а следовательно, и весь документ — на HTML-странице. Первое, что я сделал, — создал шаблон с элементом <xsl:template>, установив атрибут match в образец для совпадения
<?xml version="1.0">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
.
.
.
</xsl:template>
</xsl:stylesheet>
Когда устанавливается соответствие с корневым узлом, шаблон применяется к самому узлу. В данном случае (листинг 2.2) я хочу заменить корневой узел документом HTML, поэтому я только включу этот документ HTML непосредственно в качестве содержимого элемента <xsl:template>.
Листинг 2.2. Простейшее преобразование<?xml version="1..0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>
A trivial transformation
</TITLE>
</HEAD>
<BODY>
This transformation has replaced the entire document.
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
Результат: при помощи элемента <xsl:template> я установил правило в таблице стилей. Когда процессор XSL считывает документ, первым узлом является корневой узел. Это правило находит данный корневой узел, и от того процессор XSL копирует литералы в результирующее дерево, что даст нам HTML doc и заменит его документом HTML, генерируя следующий результат:
<HTML>
<HEAD>
<TITLE>
A trivial transformation
</TITLE>
</HEAD>
<BODY>
This transformation has replaced the entire document.
</BODY>
</HTML>
Рассмотренный пример иллюстрирует первое, устаревшее преобразование. Была создана простая таблица стилей с единственным элементом <xsl:template>, который содержит только элемент буквального результата. Все, что сделано в примере, — замена всего документа XML на документ HTML, что не очень впечатляет. Далее мы увидим, как работает рекурсивная обработка с использованием элемента <xsl:apply-templates>.
Элемент <xsl:apply-templates>
В уже написанном нами основном шаблоне корневой узел искался по выражению "/" и заменялся на элемент буквального вывода. Однако, когда мы ищем корневой узел, обычно нам нужно обработать и всю оставшуюся часть документа, что мы сделаем при помощи элемента <xsl:apply-templates>.
В следующем списке перечислены атрибуты этого элемента:
• select (необязательный). Набор обрабатываемых узлов. Если атрибут опущен, автоматически обрабатываются все потомки узла. Устанавливается в выражение;
• mode (необязательный). Устанавливает режим обработки. К этому узлу применяются правила шаблона с режимом выбора. Принимает значение типа QName.
Элемент <xsl:apply-templates> может содержать ноль или более элементов <xsl:sort>, или ноль или более элементов <xsl:with-param>.
В следующем примере шаблон ищет корневой узел и замещает его элементом буквального результата <HTML>:
<?xml version="1.0">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://ww.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
</HTML>
</xsl:template>
.
.
.
С другой стороны, мы только нашли корневой узел, а дерево данных planets.xml имеет ряд узлов под корневым узлом:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="planets.xsl"?>
<PLANETS>
<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><!--B перигелии-->
</PLANET>
.
.
.
Для обработки не только одного корневого узла можно использовать <xsl:apply-templates>, добавив этот элемент следующим образом:
<?xml version="1.0">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<xsl:apply-templates/>
</HTML>
</xsl:template>
.
.
.
Этот элемент дает указание процессору XSLT просмотреть все дочерние узлы корневого узла и попытаться найти шаблон, которому эти узлы удовлетворяют. Например, вам может потребоваться заменить все элементы <PLANET> на <P>Planet</P>. Элементы <PLANET> — дочерние узлы элемента <PLANETS>, поэтому сначала я добавил новый шаблон для <PLANETS>, что говорит процессору о том, что следует продолжать поиск дочерних узлов:
<?xml version="1.0">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<xsl:apply-templates/>
</HTML>
</xsl:template>
<xsl:template match="PLANETS">
<xsl:apply-templates/>
</xsl:template>
.
.
.
Теперь можно добавить еще один шаблон для следующего уровня, включающего элементы <PLANET>. В этом случае я просто заменю каждый элемент <PLANET> элементом буквального результата <P>Planet</P> (листинг 2.3).
Листинг 2.3. Использование <xsl:apply-templates/><?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
<xsl:template match="/">
<HTML>
<xsl:apply-templates/>
</HTML>
</xsl:template>
<xsl:template match="PLANETS">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="PLANET">
<P>
Planet
</P>
</xsl:template>
</xsl:stylesheet>
Вот результат применения этой таблицы стилей:
<HTML>
<Р>
Planet
</Р>
<Р>
Planet
</Р>
<P>
Planet
</Р>
</HTML>
Как видите, от элемента <PLANETS> ничего не осталось. Все, что осталось, — три элемента буквального результата <P>Planet</P>, которые заменили три элемента <PLANET>.