Часть 1 (1075656), страница 3
Текст из файла (страница 3)
Это можно рассматривать как оператор вывода. Тэг TR формируетстроку таблицы в HTML. Элементы TH формируют заголовки в первой строкетаблицы.<xsl:for-each select="languages/language"><!-- Перебор в цикле всех элементов language, вложенных в элементlanguages. -->Элемент for-each – единственная разновидность циклов в XSLT.
Никакихдругих видов циклов в XSLT нет. В атрибуте select указывается XPath выражение,которое возвращает перебираемые в цикле элементы.Содержимое элемента for-each (тело цикла) выполняется для каждого узла,который возвращается в атрибуте select.Поэтому тело цикла будет выполняться три раза, для каждого элементаlanguage.<TR><TD><xsl:value-of select="@id"/></TD><!-- Выбор значения атрибута id элемента language -->Обратите внимание, что, попадая внутрь тела цикла, мы «проваливаемся» вконтекст, который задается текущим значением атрибута select элемента for-each.Все XPath-выражения внутри тела цикла должны быть контекстными.Здесь мы формируем строку таблицы с помощью элемента TR.
Элемент TDзадает ячейку таблицы.Элемент value-of возвращает значение, задаваемое в виде XPath-выражения ватрибуте select. Обратите внимание, что это XPath-выражение контекстное, оно24возвращает атрибут id для текущего элемента language, который соответствуеттекущей итерации цикла.Атрибут select используется и в элементе for-each, и в элементе value-of. И втом, и в другом случае это XPath-выражение. Однако смысл у них различный.В элементе for-each предполагается, что это выражение возвращаетнесколько значений. Для каждого значения выполняется итерация цикла.В элементе value-of предполагается, что выражение возвращает единственноезначение.
Если по ошибке написать неоднозначное выражение, то, как правило,XSLT-процессор возвращает первое значение.Далее с помощью элемента value-of формируются другие ячейки таблицы.Значение select="." возвращает XML-значение для элемента language. Нобраузер не отображает XML-тэги, а отображает только текстовое содержимоевложенных элементов.Все XPath-выражения являются контекстными. Выражение <xsl:value-ofselect="name(.)"/>возвращаетназваниетекущегоэлемента(language),авыражение <xsl:value-of select="name(parent::*)"/> возвращает название элементаверхнего уровня (languages). Вместо select="name(parent::*)" также можноиспользовать select="name(..)".<TD><xsl:value-of select="name"/></TD><!-- Выбор значения элемента name, вложенного в элемент language --><TD><xsl:value-of select="year"/></TD><!-- Выбор значения элемента year, вложенного в элемент language --><TD><xsl:value-of select="howold"/></TD><!-- Выбор значения элемента howold, вложенного в элемент language -><TD><xsl:value-of select="name(.)"/></TD><!-- Название текущего элемента --><TD><xsl:value-of select="."/></TD><!-- Содержимое текущего элемента (контекст) --><TD><xsl:value-of select="name(parent::*)"/></TD><!-- Название элемента верхнего уровня (также можно использоватьselect="name(..)") -->25</TR>Далее следуют необходимые закрывающие тэги.</xsl:for-each></TABLE></BODY></HTML></xsl:template></xsl:stylesheet>3.4.2 XSLT-преобразования с адаптируемой структуройРассмотренный шаблон XSLT является шаблоном с фиксированнойструктурой выходного HTML–документа.
Если во входном XML-документепоменять местами элементы <name> и <year>, то это не приведет к перестановкеколонок в таблице.Рассмотрим XSLT-преобразование, которое не содержит жестко заданнуюструктуру выходного документа, а адаптируется к структуре входного документа.Адаптивность XSLT-преобразования достигается за счет того, чтоиспользуются несколько элементов template, каждый из которых соответствуетэлементу входного документа.Порядок вызова элементов template не задается. Они вызываются в такойпоследовательности, в которой встречаются соответствующие элементы вовходном документе.Файл XSLT:<?xml version="1.0" encoding="Windows-1251"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки корневого элемента XML - документа --><xsl:template match="/"><HTML><HEAD><LINK href="met.css" rel="stylesheet" type="text/css"/></HEAD>26<BODY><xsl:apply-templates/></BODY></HTML></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента languages --><xsl:template match="languages"><!-- Вызов шаблона для элемента language (шаблон вызываетсянеобходимое количество раз) --><xsl:apply-templates/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента language --><xsl:template match="language"><!-- Получение значения атрибута id (префикс @ означает атрибут) --><B>Номер: <xsl:value-of select="@id"/></B><BR/><!-- Вызов шаблонов для элементов name, year и howold --><xsl:apply-templates/><HR/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента name --><xsl:template match="name">Наименование языка: <B><xsl:value-of select="."/></B><BR/><!-- select="." - получение значения текущего элемента --></xsl:template>27<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента year --><xsl:template match="year">Год создания: <U><xsl:value-of select="."/></U><BR/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента howold --><xsl:template match="howold">Возраст технологии (лет): <I><xsl:value-ofselect="."/></I><BR/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--></xsl:stylesheet>Просмотр результата в браузере:28XML файл в этом примере такой же, как и предыдущем случае.
Дляприменения к нему XSLT-преобразования можно использовать инструкцию<?xml-stylesheet type="text/xsl" href="преобразования.xslназвание XSLT-"?>В этом случае результат отображается в браузере. Или можно использоватьотладчик XSLT, встроенный в XMLPad.Рассмотрим более подробно текст преобразования XSLT.<?xml version="1.0" encoding="Windows-1251"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки корневого элемента XML - документа --><xsl:template match="/">Как и в предыдущем примере, здесь присутствует шаблон для корневогоэлемента.
Но в отличие от предыдущего примера здесь присутствуют и другиешаблоны.<HTML><HEAD><LINK href="met.css" rel="stylesheet" type="text/css"/>В секции HEAD документа HTML встречается тэг LINK, который связываетHTML-документ с внешней таблицей стилей. После обработки XML-документа спомощью XSLT к полученному HTML-документу будет применена таблицастилей CSS.</HEAD><BODY><xsl:apply-templates/>Главной инструкцией в этом примере является apply-templates. Этаинструкция выполняет следующие действия:1. В текущем контексте (в текущем тэге) входного документа находит всенепосредственно вложенные элементы.292. Для каждого такого элемента пытается найти соответствующий шаблон(template) и выполнить его.
Соответствующим является шаблон вида <xsl:templatematch=" название элемента ">.В нашем примере в корневой элемент непосредственно вложен элементlanguages, поэтому далее будет вызван <xsl:template match="languages">.Обратите внимание, что реальный корневой элемент документа «languages»считается вложенным в корневой элемент «/». Поэтому элементы language невложены непосредственно в «/».</BODY></HTML></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента languages --><xsl:template match="languages"><!-- Вызов шаблона для элемента language (шаблон вызываетсянеобходимое количество раз) --><xsl:apply-templates/>В нашем примере в элемент languages непосредственно вложен элементlanguage, поэтому далее будут вызваны шаблоны <xsl:template match="language">для каждого элемента language.</xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента language --><xsl:template match="language"><!-- Получение значения атрибута id (префикс @ означает атрибут) --><B>Номер: <xsl:value-of select="@id"/></B><BR/><!-- Вызов шаблонов для элементов name, year и howold --><xsl:apply-templates/>30В нашем примере в элемент language непосредственно вложены элементыname, year и howold.
Инструкция apply-templates будет вызывать шаблоны дляэтих элементов.<HR/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента name --><xsl:template match="name">Наименование языка: <B><xsl:value-of select="."/></B><BR/>Так как в этом шаблоне мы находимся в контексте элемента name (то естьуже «провалились» внутрь элемента name), то для получения значения текущегоэлемента надо использовать XPath-выражение «.» или «self::*».Если вместо выражения <xsl:value-of select="."/> использовать <xsl:value-ofselect="name"/>, то оно вернет пустое значение, так как будет искатьнесуществующий элемент name внутри текущего элемента name.Шаблоны для элементов year и howold построены аналогично шаблону дляэлемента name.</xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента year --><xsl:template match="year">Год создания: <U><xsl:value-of select="."/></U><BR/></xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- Шаблон обработки элемента howold --><xsl:template match="howold">Возраст технологии (лет): <I><xsl:value-ofselect="."/></I><BR/>31</xsl:template><!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--></xsl:stylesheet>Отметим, что текстовое содержимое элемента CDATA_Example скопированов выходной поток, что в нашем случае является нежелательным эффектом.Поэтому, в преобразовании лучше создавать шаблоны для всех возможныхэлементов.