</xsl:template>
</xsl:stylesheet>
Забегая вперед скажем, что в изначальном контексте преобразования текущее множество состоит из единственного узла — корневого узла документа. Он становится текущим и обрабатывается соответствующим шаблоном.
В нашем случае шаблонное правило, обрабатывающее корневой узел, выглядит как:
<xsl:template match='/'>
<html>
<head>
<title>Summer</title>
</head>
<body>
<xsl:apply-templates select='summer'/>
</body>
</html>
</xsl:template>
Тело этого шаблона выполняется в том самом изначальном контексте, о котором мы только что упомянули: текущее множество состоит из корневого узла, он же является и текущим узлом. Мы можем показать контекст, выделяя текущее множество, пунктиром, а текущий узел — полужирной линией (рис. 3.20).
Рис. 3.20. Первоначальный контекст преобразования
Атрибут select
элемента xsl:apply-templates
задает выражение, вычисляющее множество узлов, которые должны быть обработаны. Выражение summer
, которое содержит этот атрибут, является относительным путем выборки, который возвращает все дочерние элементы summer
текущего узла. Поскольку текущим узлом в данном контексте является корневой узел дерева, значением выражения summer
будет множество узлов, состоящее из субэлемента summer, корневого узла.
При выполнении элемента xsl:apply-templates
процессор сделает это вычисленное множество узлов текущим множеством и начнет поочередно обрабатывать его узлы, делая их при этом текущими. Иначе говоря, выполнение элемента
<xsl:apply-templates select='summer'/>
сведется к выполнению шаблона, обрабатывающего элемент summer
. Этот шаблон выглядит следующим образом:
<xsl:template match='summer'>
<table>
<tr>
<xsl:apply-templates select='month'/>
</tr>
</table>
</xsl:template>
Выполняться он будет в следующем контексте (рис. 3.21):
Рис. 3.21. Контекст шаблона элемента summer
Атрибут select
элемента xsl:apply-templates,
который присутствует в этом шаблоне, вычисляет новое текущее множество: путь выборки month
возвращает все дочерние элементы month
текущего узла. Текущим узлом является элемент summer
, то есть новое текущее множество будет состоять из трех его дочерних элементов month
. Таким образом, процессор будет поочередно выполнять шаблоны в каждом из трех следующих контекстов, показанных на рис. 3.22.
Рис. 3.22. Изменение контекста при выполнении шаблона элемента month
Шаблон, вычисляемый в каждом из этих контекстов, имеет следующий вид:
<xsl:template match='month'>
<td>
<xsl:value-of select='.'/>
</td>
</xsl:template>
Элемент xsl:value-of
этого шаблона создает в элементе td
текстовый узел, значение которого равно строковому значению выражения '.
', то есть строковому значению текущего узла, и в каждом случае это будет строковое значение соответствующего элемента month
.
Контекст преобразования позволяет более четко определить такие понятия, как 'обработка узла', 'применение шаблона к узлу' и так далее. Все эти выражения означают одно: выполнение соответствующего шаблона с данным узлом в качестве текущего.
Выполнение преобразования
Несмотря на полную свободу в порядке выполнения шаблонов, правила изменения контекста и компоновки результирующего дерева, спецификация XSLT оговаривает очень четко — это делает XSLT весьма гибким языком, программы на котором при этом выполняются совершенно детерминированным образом.
Типовой процесс выполнения преобразования согласно спецификации включает следующие стадии:
□ дерево выходящего документа создается путем обработки множества, состоящего из единственного узла — текущего узла дерева;
□ результатом применения шаблонов к обрабатываемому множеству узлов является объединение фрагментов деревьев, которые являются результатами обработки каждого из узлов множества;
□ каждый из узлов обрабатываемого множества преобразуется следующим образом:
• из всех шаблонов, определенных в данном преобразовании, выбираются шаблоны, соответствующие данному узлу (соответствие определяется паттерном, указанным в атрибуте match
элемента xsl:template
);
• из этих шаблонов выбирается наиболее подходящий;
• выбранный шаблон выполняется в контексте обрабатываемого множества как
□ если шаблон содержит инструкции xsl:apply-templates
или xsl:foreach
, которые дополнительно выбирают узлы для обработки, процесс рекурсивно продолжается до тех пор, пока обрабатываемое множество будет содержать хотя бы один узел.
В общих чертах этот процесс был продемонстрирован на примере, приведенном в описании контекста преобразования. Сейчас мы завершим картину, показав, как в каждом из шаблонов будут создаваться результирующие фрагменты деревьев и как они затем будут 'сращиваться' в дерево выходящего документа.
На сей раз, мы начнем с самых 'глубоких' шаблонов — шаблонов, обрабатывающих элементы