В предыдущем совете (См. Ссылки по теме) объяснялось, как совместить два различных XML-документа в таблице стилей. Для иллюстрации примера использовалась фотогалерея, собранная из четырех отдельных XML-документов, которые в конечном итоге были собраны в одну Web-страницу. Эта методика также подходит для совмещения log-файлов (сбора суточных отчетов в месячный) и оглавлений (сбора нескольких глав в одно оглавление).
Сегодня мы рассмотрим другой случай, при котором один XML-документ необходимо разбить на несколько частей. Длинные документы можно разбивать на небольшие страницы, которые будут быстрее загружаться.
Документ из Листинга 1 представляет собой небольшую фотогалерею, состоящую из четырех фото с описаниями. Нашей задачей будет создать из документа небольшой Web-сайт. Для ускорения загрузки каждая фотография должна размещаться на собственной странице. Сложностью здесь является разбиение оригинального документа на количество страниц, соответствующее количеству фотографий.
Листинг 1. gallery.xml – фотогалерея в одном XML-документе
<?xml version="1.0"?>
<gl:gallery xmlns:gl="http://ananas.org/2003/tips/gallery">
<gl:title>Flowers and plants</gl:title>
<gl:photo>
<gl:title>Rose</gl:title>
<gl:date>September 2002</gl:date>
<gl:image>rose.jpg</gl:image>
<gl:description>
This photo was taken early in the morning in a very soft light.
This rose flower was shot at a gas station on the highway!
</gl:description>
</gl:photo>
<gl:photo>
<gl:title>Orchid</gl:title>
<gl:date>May 2003</gl:date>
<gl:image>orchid.jpg</gl:image>
<gl:description>
This is a lady slipper (paphiopedilum liemianum) orchid.
In this shot, the flower is window-lit.
</gl:description>
</gl:photo>
<gl:photo>
<gl:title>Lily-of-the-valley</gl:title>
<gl:date>May 2003</gl:date>
<gl:image>lily.jpg</gl:image>
<gl:description>
The lily-of-the-valley is popular for its sweet perfume and is typically
associated with May 1st. This was done under artificial lights.
</gl:description>
</gl:photo>
<gl:photo>
<gl:title>Cardoon</gl:title>
<gl:date>September 2002</gl:date>
<gl:image>cardoon.jpg</gl:image>
<gl:description>
Also known as artichoke thistle, the cardoon is grown for its gentle
laxative properties. This specimen is dried and the colors have been
digitally altered to create a more graphic image.
</gl:description>
</gl:photo>
</gl:gallery>
|
В разбиении страниц есть как положительные, так и отрицательные моменты. Хорошим является то, что можно разбить документ на любое количество страниц при помощи обычного обработчика XSLT. Плохо то, что это, пока, не является стандартной функцией, так как XSLT-обработчики имеют различные реализации. К счастью, эти различия лишь "косметические".
Листинг 2 представляет собой таблицу стилей для публикации фотогалереи. Обратите особое внимание на шаблон для тега gl:photo. Этот шаблон создает отдельную HTML-страницу, сохраняющуюся как самостоятельный файл при помощи тега xalan:redirect. Таблица стилей была проверена на JDK 1.4.1 и работает только с XSL-обработчиками JDK или Xalan (Apache Xalan является основной реализацией для JAXP).
Листинг 2. jdk.xsl – таблица стилей для JDK 1.4 (и Xalan)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery"
xmlns:xalan="org.apache.xalan.xslt.extensions.Redirect"
extension-element-prefixes="xalan">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-0.html">here</a>.</p>
</body>
</html>
<xsl:apply-templates select="gl:photo"/>
</xsl:template>
<xsl:template match="gl:photo">
<xalan:write select="concat('photo-',position(),'.html')">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</xalan:write>
</xsl:template>
</xsl:stylesheet>
|
Исходный код (См. Ссылки по теме) включает в себя документ, таблицу стилей и небольшое Java-приложение для тестирования кода. Для запуска этого примера вам понадобится JDK 1.4.
Тег xalan:redirect указывает обработчику сохранить содержимое элемента в отдельном файле. Имя файла задается атрибутом select. В нашем примере таблица стилей создает имена файлов путем добавления номера фотографии (или, точнее, ее позиции) к строке photo-. Файлы называются, соответственно, photo-1.html, photo-2.html, photo-3.html и photo-4.html.
К несчастью тег xalan:redirect не является частью стандарта, так что другие обработчики не смогут его распознать. Тег xalan:redirect реализован как расширение. Для его объявления необходимо объявить пространство имен для URI-адреса org.apache.xalan.xslt.extensions.Redirect. Надо отметить, что этот адрес не является правильным URI, однако Xalan его все равно распознает. После этого необходимо объявить пространство имен как расширение с помощью атрибута extension-element-prefixes. Объявление пространства имен и атрибут extension-element-prefixes должны располагаться в элементе xsl:stylesheet.
Как обстоят дела с другими обработчиками
Xalan является хорошим обработчиком, однако существуют и другие. Вам необходимо изучить документацию вашего любимого XSLT-обработчика и найти эквивалентное расширение. На сколько мне известно, каждый XSLT-обработчик предлагает хотя бы одно расширение, позволяющее осуществлять вывод множества документов.
К примеру, если вы захотите воспользоваться обработчиком Saxon, автором которого является Michael Kay, вместо xalan:redirect. в шаблоне gl:photo вам необходимо будет использовать тег saxon:output. Изменения здесь минимальны, так как синтаксис тега saxon:output очень похож на xalan:redirect. В листинге 3 показана версия Листинга 2 для Saxon. Обратите внимание на использование пространства имен для расширения, определенного в Saxon.
Листинг 3. saxon.xsl – таблица стилей для Saxon
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery"
xmlns:saxon="http://icl.com/saxon"
extension-element-prefixes="saxon">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-1.html">here</a>.</p>
</body>
</html>
<xsl:apply-templates select="gl:photo"/>
</xsl:template>
<xsl:template match="gl:photo">
<saxon:output href="photo-{position()}.html">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</saxon:output>
</xsl:template>
</xsl:stylesheet>
|
В разрабатывающейся версии XSLT 2.0 определяется стандартная инструкция для генерирования многократных выводов. На практике она очень похожа на xalan:redirect или saxon:output, однако ей будет назначено стандартное имя. В последней версии проекта XSLT 2.0 (на момент написания статьи – 2 мая 2003 г.) эта инструкция называется xsl:result-document. В Листинге 4 демонстрируется ее использование. Обратите внимание, здесь уже используется таблица стилей XSLT 2.0, как заявлено в атрибуте версии.
Листинг 4. xsl2.xsl – таблица стилей XSLT 2.0 с новой инструкцией xsl:result-document
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<xsl:apply-templates select="gl:photo"/>
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-0.html">here</a>.</p>
</body>
</html>
</xsl:template>
<xsl:template match="gl:photo">
<xsl:result-document href="photo-{position()}.html">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
|
При публикации Web-сайта вам может помочь разбиение одного XML-документа на несколько частей. Это упрощает загрузку и улучшает эффективность, кроме того, может помочь при работе с фреймами. Между тем, использование множественных выводов не ограничивается лишь публикацией. Эту методику можно использовать также в проектах электронной коммерции для разбиения больших результатов экспорта баз данных на меньшие, которыми легче управлять.
| Имя | Размер | Метод загрузки |
|---|---|---|
| x-tipdivbigcode.zip | FTP |
- Оригинальная статья "Divide and conquer large XML documents"
- Ссылка на исходный код примера, используемого в данной статье.
- Статья "How to combine documents with XSLT" (developerWorks, Май 2003).
- Ресурс, посвященный программированию на XSLT – XMLPitstop.com.
- Ссылка для скачивания JDK 1.4 с со страницы IBM's developer kits или сайта Sun. Обработчик XSLT Xalan, встроенный в JDK, доступен отдельно на сайте Apache.
- Ссылка на XSLT-обработчик Saxon, доступный на сайте SourceForge. Автор: Michael Kay.
- Дополнительные источники по XML в разделе XML zone ресурса developerWorks
- Узнайте о том, как стать Cертифицированным Разработчиком IBM в области XML и родственных технологиях.
- Ссылки по теме:
How to combine documents with XSLT
IBM Developer Kits
Subscribe to the XML tips newsletter

Benoit Marchal является бельгийским консультантом. Он автор книги XML by Example, Second Edition и других книг по XML. Автор доступен для помощи в XML-проектах. С ним можно связаться по адресу bmarchal@pineapplesoft.com или через персональный сайт marchal.com.