select
. Его значением должно быть множество узлов. Полученное множество узлов упорядочивается и становится текущим списком узлов контекста преобразования.
□ Для каждого из узлов этого списка процессор находит наиболее подходящий шаблон для обработки. Процессор делает этот узел текущим и затем выполняет в измененном контексте выбранное шаблонное правило.
□ Дерево, которое является результатом выполнения шаблона, добавляется в выходящее дерево.
Применительно к нашему примеру с para
и bold
, мы можем изменить преобразование так, что в создаваемый элемент p будет включаться не текстовое значение элемента para, а результат обработки его дочерних узлов.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='bold'>
<b><xsl:value-of select='.'/></b>
</xsl:template>
<xsl:template match='para'>
<p><xsl:apply-templates</p>
</xsl:template>
</xsl:stylesheet>
Проследим за процессом выполнения этого преобразования.
□ Обработка начинается с корневого узла дерева. Для него нет заданных шаблонных правил, значит, применено будет правило по умолчанию — обработать все дочерние узлы. Множество дочерних узлов корня содержит единственный элемент para
, значит, текущий список узлов контекста будет состоять из одного узла. Для него в преобразовании определен шаблон, который и будет выполнен процессором.
□ Шаблон, соответствующий элементу para
, создает элемент p
, содержимым которого будет результат выполнения инструкции xsl:apply- templates
, то есть результат применения шаблонов к дочерним узлам текущего узла — элемента para
.
□ Единственным дочерним узлом элемента para
является элемент bold
. Процессор изменит контекст так, что текущий список узлов будет содержать только элемент bold
и выполнит соответствующее шаблонное правило, которое создаст элемент b
и включит в него узел, вычисленный инструкцией <xsl:value-of select='.'/>
, то есть текстовый узел со строковым значением текущего узла, элемента bold
.
Три шага этого преобразования продемонстрированы на рис. 5.1.

Рис. 5.1. Процесс преобразования
Здесь слева показан текущий список узлов, посередине — дерево документа с выделенным пунктиром текущим узлом, справа — генерируемое выходящее дерево.
Результатом этого преобразования будет документ:
<p><b>text</b></p>
Рассмотрим чуть более сложное преобразование документа:
<para>
<bold>text1</bold>
<para>
<bold>text2</bold>
</para>
</para>
Порядок действий в этом случае будет приблизительно следующим.
□ Первым обрабатывается корневой узел. Процессор применяет шаблоны к дочерним узлам (вернее к одному дочернему узлу — элементу para
).
□ Шаблон, обрабатывающий элемент para, создает в выходящем документе элемент p и применяет шаблоны к своим дочерним узлам — на этот раз их два, bold
и para
.
□ Шаблон, обрабатывающий элемент bold
, создает в выходящем документе элемент b
и текстовый узел со значением 'text1
'.
□ Шаблон, обрабатывающий элемент para
, создает в выходящем дереве узел p
и применяет шаблоны к дочерним узлам.
□ Единственным дочерним узлом элемента para
является элемент bold
.
□ Шаблон, обрабатывающий этот элемент bold
, создает в выходящем документе элемент b
и текстовый узел со значением 'text2
'.
Процесс преобразования показан на рис. 5.2.

Рис. 5.2. Процесс преобразования
Результатом этого преобразования будет документ:
<p>
<b>text1</b>
<p>
<b>text2</b>
</p>
</p>
Атрибут select
элемента xsl:apply-templates
позволяет выбирать, к каким именно узлам будет применяться этот шаблон. Значение select
— это XPath- выражение, которое должно возвращать множество узлов. В случае, если атрибут select
указан, шаблоны будут поочередно применяться к каждому из узлов выбранного множества.
Если при обработке элементов para мы хотим обрабатывать только дочерние элементы bold
и никакие другие, шаблон обработки элементов para
будет записан следующим образом:
<xsl:template match='para'>
<p><xsl:apply-templates select='bold'/></p>
</xsl:template>
Результатом обработки документа
<para>
<bold>text1</bold>
<para>
<bold>text2</bold>
</para>
</para>
будет теперь
<p>
<b>text1</b>