Книга: Технология XSLT

Элемент xsl:call-template

Элемент xsl:call-template

Приведем синтаксис этого элемента:

<xsl:call-template
 name="имя">
 <!-- Содержимое: несколько элементов xsl:with-param -->
</xsl:call-template>

Обязательный атрибут name указывает имя шаблона, который вызывается этой инструкцией. Например, шаблон с именем "head", приведенный выше, может быть вызван следующим образом:

<xsl:call-template name="head"/>

Атрибут name при вызове обязан иметь фиксированное значение — точно так же, как и в случае с mode и xsl:apply-templates, динамика здесь не разрешена.

При вызове xsl:call-template не изменяет контекста преобразования. Фактически, вызов именованного шаблона эквивалентен замене в тексте преобразования элемента xsl:call-template на тело вызываемого шаблона.

Приведем пример.

Листинг 5.6. Входящий документ

<content>
 Just a few words...
</content>

Листинг 5.7. Преобразование

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 <html>
  <xsl:call-template name="head"/>
  <body><xsl:copy-of select="content/node()"/></body>
 </html>
</xsl:template>
<xsl:template name="head">
 <head>
  <meta name="keywords" content="XSLT, XPath, XML"/>
  <meta name="description"
   content="This site is dedicated to XSLT and Xpath."/>
  <title>XSLTdev.ru - XSLT developer resource</title>
  <link rel="stylesheet" type="text/css" href="style/main.css"/>
 </head>
</xsl:template>
</xsl:stylesheet>

Листинг 5.8. Выходящий документ

<html>
 <head>
  <meta name="keywords" content="XSLT, XPath, XML">
  <meta name="description"
   content="This site is dedicated to XSLT and Xpath.">
  <title>XSLTdev.ru - XSLT developer resource</title>
  <link rel="stylesheet" type="text/css" href="style/main.css">
 </head>
 <body>Just a few words...</body>
</html>

Примечание

Несколько более эффективным способом использования в документе статических частей (как содержимое элемента head в приведенном примере) является хранение этих частей во внешних документах и вставка их в выходящий документ при помощи элемента xsl:copy-of и функции document.

В этом примере шаблон, обрабатывающий корневой элемент, фактически эквивалентен шаблону вида:

<xsl:template match="/">
 <html>
  <head>
   <meta name="keywords" content="XSLT, XPath, XML"/>
   <meta name="description"
    content="This site is dedicated to XSLT and Xpath."/>
   <title>XSLTdev.ru - XSLT developer resource</title>
   <link rel="stylesheet" type="text/css" href="style/main.css"/>
  </head>
  <body><xsl:value-of select="content"/></body>
 </html>
</xsl:template>

В принципе именованные шаблоны не обязаны иметь атрибут match, но он все же может быть определен. В этом случае шаблон можно будет применять как для обработки частей документов элементом xsl:apply-templates, так и вызывая его по имени элементом xsl:call-template.

Пример

Изменим объявление нашего шаблона head следующим образом:

<xsl:template name="head" match="head">
 ...
</xsl:template>

Теперь, если входящий документ будет иметь вид

<page>
 <head/>
 <content>Just a few words...</content>
</page>

то результат выполнения следующих двух шаблонов будет одинаков.

Листинг 5.9. Шаблон для page — версия 1

<xsl:template match="page">
 <html>
  <xsl:apply-templates select="head"/>
  <body><xsl:copy-of select="content/node()/></body>
 </html>
</xsl:template>

Листинг 5.10. Шаблон для page — версия 2

<xsl:template match="page">
 <html>
  <xsl:call-template name="head"/>
  <body><xsl:copy-of select="content/node()/></body>
 </html>
</xsl:template>

В чем же состоит разница вызова шаблона элементами xsl:apply-templates и xsl:call-template? Перечислим несколько отличий.

? Элемент xsl:apply-templates применяет подходящие шаблоны к узлам определенного множества; xsl:call-template просто выполняет тело фиксированного именованного шаблона.

? При вызове шаблона инструкцией xsl:apply-templates происходит изменение контекста — обрабатываемое множество узлов становится текущим списком узлов преобразования, а обрабатываемый узел — текущим узлом; xsl:call-template не изменяет контекст преобразования.

? Инструкция xsl:apply-templates позволяет использовать различные режимы — применяются только те шаблоны, значение атрибута mode которых равно значению этого атрибута у вызывающей инструкции; xsl:call-template выполняет шаблон с заданным именем вне зависимости от того, в каком режиме происходит обработка и каково значение атрибута mode этого шаблона.

? Если для обработки определенного узла подходит несколько шаблонов, то при выполнении xsl:apply-templates процессор будет выбирать наиболее подходящий из них; xsl:call-template всегда будет выполнять тот единственный шаблон преобразования, который имеет указанное имя.

? Если в преобразовании не определен шаблон для обработки некоторого узла, но к нему элементом xsl:apply-templates все же применяются шаблоны, процессор будет использовать шаблон обработки по умолчанию; если элемент xsl:call-template вызывает отсутствующий шаблон, процессор выдаст сообщение об ошибке, потому что не сможет найти шаблон с заданным именем.

? При использовании xsl:apply-templates процессор игнорирует значения атрибутов name элементов xsl:template; точно так же xsl:call-template принимает во внимание только значение атрибута name, игнорируя атрибуты match, mode и priority.

При желании можно найти еще с десяток отличий, но и этих положений вполне достаточно для того, чтобы понять разницу. Главным выводом из этого сравнения является то, что xsl:apply-templates демонстрирует декларативный, а xsl:call-template процедурный стиль программирования В первом случае мы используем объявленные (или задекларированные) правила преобразования, во втором — используем шаблон просто как процедуру.

Оглавление книги

Оглавление статьи/книги

Генерация: 1.069. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз