Использование шаблонов
Рассмотрим следующий XML-документ (полные тексты в прилагаемых файлах): Пример 16. XML-документ в примере содержит 2 типа контейнеров. Первый – Captions – содержит заголовки для организации «красивого» вывода: <Captions> <Caption> Моя библиотека </Caption> <CaptionTitle> Название </CaptionTitle> … </Captions> Второй – Book – содержит описание книги: <Book> <dc:title> Война и мир </dc:title> … </Book> Описание автора – creator – в свою очередь представлено в виде контейнера: <dc:creator> <vCard:N> <vCard:Family>Пушкин</vCard:Family> <vCard:Given> Александр </vCard:Given> <vCard:Other> Сергеевич </vCard:Other> </vCard:N> </dc:creator> Так же в примере указаны 2 пространства имен: <Library xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" > xmlns:dc – указвающее на применение схемы метаданных Dublin Core и – xmlns:vCard – указвающее на применение схемы метаданных VisitCard. Оба пространства имен должны быть тоже указаны и в XSL-документах. Сначала рассмотрим простые варианты XSL-преобразований, без использования нескольких шаблонов. Первый вариант – простое XSL-преобразование: <?xml version="1.0" encoding="windows-1251"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" > <xsl:template match="/"> <xsl:value-of select="Library/Book/dc:title"/><br/> <xsl:value-of select="Library/Book/dc:creator"/><br/> … </xsl:template> </xsl:stylesheet>
Второй вариант – с использованием XSL-элемента for-each:
<tr bgcolor="#CCCCCC"> <td align="center"> <xsl:value-of select="Library/Captions/CaptionTitle"/> </td> <td align="center"> <xsl:value-of select="Library/Captions/CaptionCreator"/> </td> … </tr> В этот вариант включена сортировка по авторам: <xsl:for-each select="Library/Book"> <xsl:sort select="dc:creator" /> <tr> <td><xsl:value-of select="dc:title"/></td> <td><xsl:value-of select="dc:creator"/></td> … </tr> </xsl:for-each> Так как в XML-документе используется кодовое обозначения языка документа, то для вывода используется условный элемент xsl:if: <td><xsl:if test="dc:language='ru'"> <i>русский</i> </xsl:if></td> Вид XML-документа с этим вариантом XSL-преобразования:
Как уже было указано выше, XSL-документ может содержать один или несколько шаблонов. Атрибут match шаблона указывает на ветвь, которая в нем обрабатывается. XSL-документ должен содержать один и только один шаблон, представляющий корневой элемент XML-документа, то есть шаблон с атрибутом match="/". Браузер использует шаблон для отображения указанной ветви элементов XML-документа. Так как в исходном XML-документе содержатся несколько контейнеров, то естественно преобразование некоторых из них удобно оформить отдельным шаблоном. Шаблон для контейнера Library/Book: <xsl:template match="Library/Book"> <tr> <td><xsl:value-of select="dc:title"/></td> <td><xsl:apply-templates select='dc:creator/vCard:N'/></td> <td><xsl:value-of select="dc:description"/></td> … </tr> </xsl:template> В атрибуте match указывается полное имя контейнера, для которого написан шаблон. В теле шаблона, как и в теле элемента for-each, во всех XSL-элементах указывается только имена дочерних XML-элементов контейнера, без указания имени шаблона. Для вызова шаблона используется следующий XSL-элемент: <xsl:apply-templates select='Library/Book'> <xsl:sort order="descending" select="dc:title"/> </xsl:apply-templates> В приведенном элементе apply-templates атрибут select играет роль имени шаблона, по этому имени определяется какой шаблон нужно использовать. Шаблон применяется ко всем элементам, встречающимся в XML-документе, то есть шаблон очень похож на элемент цикла for-each, в том числе можно использовать и сортировку. В приведенном примере осуществляется сортировка по названию (элемент title) в порядке убывания. Шаблон для контейнера vCard:N: <xsl:template match="Library/Book/dc:creator/vCard:N"> <i><xsl:value-of select="vCard:Family"/></i><br/> <xsl:value-of select="vCard:Given"/><br/> <xsl:value-of select="vCard:Other"/><br/> </xsl:template> Для вызова шаблона используется следующий XSL-элемент: <xsl:apply-templates select='dc:creator/vCard:N'/> Так как этот шаблон вызывается из другого, то в атрибуте select указывается не полное имя контейнера, а в соответствии с правилами записи имен XML-элементов внутри шаблона и цикла, XSL сам расширяет имя до полного. Ниже приводится окно браузера с получившимся преобразованием. Изменение цвета фона ячеек таблицы достигается использованием следующих XSL-элементов: <td> <xsl:if test="position() mod 2 = 0"> <xsl:attribute name="bgcolor">yellow</xsl:attribute> </xsl:if> <xsl:value-of select="dc:title"/> </td> Элемент xsl:attribute добавляет к HTML-тегу <td> атрибут bgcolor и указывает его значение – yellow. В условном элементе определяется является ли строка четной.
В шаблонах и в элементе for-each имеется возможность вставлять условия фильтрации, которые позволяют ограничить число выводимых элементов. В следующем примере использован элемент: <xsl:for-each select= "Library/Book[dc:creator/vCard:N/vCard:Family='Пушкин']"> Условие dc:creator/vCard:N/vCard:Family='Пушкин' определяет что в выходной поток попадут только те элементы контейнера Book в которых фамилия автора – Пушкин.
|