<xsl:result-document> XSLT

Элемент xsl:result-document создает дерево результата. Как правило, дерево результата записывается в файл, хотя процессор XSLT 2.0 этого делать не обязан. Инструкция <xsl:result-document> удобна для построения нескольких файлов по одной таблице стилей. Кроме того, она позволяет сгенерировать имя выходного файла на стадии выполнения.

Синтаксис

XSLT 2.0

<xsl:result-document
    format = "qname"
    href = "uri-reference"
    validation = "strict | lax | preserve | strip"
    type = "qname"
    method = "xml | html | xhtml | text | qname-but-not-ncname"
    byte-order-mark = "yes | no"
    cdata-section-elements = "qnames"
    doctype-public = "string"
    doctype-system = "string"
    encoding = "string"
    escape-uri-attributes = "yes | no"
    include-content-type = "yes | no"
    indent = "yes | no"
    media-type = "string"
    normalization-form = "NFC | NFD | NFKC | NFKD | fully-normalized | none | nmtoken"
    omit-xml-declaration = "yes | no"
    standalone = "yes | no | omit"
    undeclare-prefixes = "yes | no"
    use-character-maps = "qnames"
    output-version = "nmtoken">
    <!-- Content: sequence-constructor -->
</xsl:result-document>
  • formatнеобязательный атрибут, ссылается на спецификацию вывода, определяемую для именованного элемента <xsl:output>. Вы можете определить набор свойств (метод вывода, кодировку символов и т. д.), а затем многократно использовать готовую спецификацию, указывая ее атрибут name в соответствующем элементе <xsl:output>.
  • hrefнеобязательный атрибут, определяет URIадрес итогового документа. Обычно используется для определения имени файла итогового документа, хотя процессор XSLT может использовать этот URI-адрес любым способом на свое усмотрение.
  • typeнеобязательный атрибут, определяет тип данных элемента документа. Им может быть любой из встроенных типов данных или же тип данных, определенный в схеме (при использовании схемосовместимого процессора XSLT 2.0). Атрибуты type и validation являются взаимоисключающими.
  • validationнеобязательный атрибут, определяет способ проверки нового элемента документа. Атрибут validation имеет четыре допустимых значения: strict, lax, preserve и strip. Атрибут validation="strict" означает, что процессор XSLT должен искать во всех объявленных схемах объявление элемента (<xs:element>) с таким же именем, как у элемента документа. Если процессору не удается найти подходящее объявление, происходит фатальная ошибка. Если же процессор находит объявление элемента документа, он проверяет по нему новый документ. Значение validation="lax" работает аналогично validation="strict", но если процессору не удается найти объявление элемента документа ни в одной из объявленных схем, ошибка не происходит. В этом случае элемент документа имеет обозначение типа xs:untyped. Со значением validation="preserve" созданный элемент получает обозначение типа xs:anyType, а обозначения типов всех узлов, содержащихся в новом элементе документа, сохраняются без изменений. Проверка по схеме не выполняется. Наконец, значение validation="strip" создает элемент документа с типом xs:anyType. Атрибуты validation и type являются взаимоисключающими.
  • methodнеобязательный атрибут, определяет метод вывода дерева результата. Допустимые значения: xml, html, xhtml и text. Процессор XSLT может дополнить список другими значениями; заинформацией о поддержке других методов вывода обращайтесь к документации своего процессора.
  • byte-order-markнеобязательный атрибут, определяет, должна ли метка порядка байтов записываться в выходной документ. Допустимые значения: yes и no. По умолчанию значение yes используется для кодировки UTF16, тогда как значение по умолчанию для UTF8 зависит от процессора XSLT. Для всех остальных кодировок по умолчанию используется значение no.
  • cdata-section-elementsнеобязательный атрибут, перечисляет элементы, которые записываются в выходной документ в виде секций CDATA. Соблюдение всех ограничений и правил экранирования для секций CDATA обеспечивается процессором XSLT. Если потребуется перечислить более одного элемента, разделите их имена одним или несколькими символами-пропусками. Атрибут используется только в режимах method="xml" и method="xhtml".
  • doctype-publicнеобязательный атрибут, определяет значение атрибута PUBLIC в объявлении DOCTYPE выходного документа. Атрибут определяет открытый идентификатор DTD выходного документа. Игнорируется при наличии атрибута method="text".
  • doctype-systemнеобязательный атрибут, определяет значение атрибута SYSTEM в объявлении DOCTYPE в выходном документе. Атрибут определяет системный идентификатор DTD выходного документа. Игнорируется при наличии атрибута method="text".
  • encodingнеобязательный атрибут, определяет значение атрибута encoding в объявлении XML выходного документа. Игнорируется при наличии атрибута method="text".
  • escape-uri-attributesнеобязательный атрибут, определяет, должны ли специальные символы в атрибутах HTML и XHTML с URIзначениями заменяться своими шестнадцатеричными эквивалентами. Например, если URI-адрес содержит пробелы, в преобразованном значении каждый пробел заменяется обозначением %20.
  • include-content-typeнеобязательный атрибут, определяет, должен ли тип содержимого записываться в выходной документ. Допустимые значения: yes и no; по умолчанию используется значение yes. Например, при использовании атрибута include-content-type для method="html" в элемент <head> документа HTML включается элемент <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">.
  • indentнеобязательный атрибут, определяет наличие отступов в тегах выходного документа. Допустимые значения: yes и no. Атрибут игнорируется в режиме method="text".
  • media-typeнеобязательный атрибут, определяет тип MIME для выходного документа. По умолчанию используются значения text/xml для method="xml", text/html для method="html" и method="xhtml" и text/plain для method="text".
  • normalization-formнеобязательный атрибут, допустимые значения: NFC, NFD, NFKC, NFKD, fully-normalized и none. Процессоры XSLT могут поддерживать и другие значения; за информацией о поддержке других форм нормализации обращайтесь к документации своего процессора.
  • omit-xml-declarationнеобязательный атрибут, определяет, должно ли объявление XML быть опущено в выходном документе. Допустимые значения: yes и no; по умолчанию используется no.
  • standaloneнеобязательный атрибут, определяет, должно ли объявление XML включать атрибут standalone. Допустимые значения: yes (объявление содержит атрибут standalone="yes"), no (объявление содержит атрибут standalone="no") и omit (объявление не содержит атрибут standalone).
  • undeclare-prefixesнеобязательный атрибут, определяет, должен ли выходной документ включать отменяющие объявления пространств имен (такие объявления связывают префикс пространства имен с пустой строкой, например xmlns:doug=""). Допустимые значения: yes и no. За полной информацией об этом малопонятном атрибуте обращайтесь к разделу 20 спецификации XSLT 2.0.
  • use-character-mapsнеобязательный атрибут, определяет список разделенных пробелами именованных карт символов, используемых при построении выходного документа.
  • output-versionнеобязательный атрибут, переопределяет атрибут version элемента <xsl:output>.

XSLT 3.0

<xsl:result-document
    format? = { eqname }
    href? = { uri }
    validation? = "strict" | "lax" | "preserve" | "strip"
    type? = eqname
    method? = { "xml" | "html" | "xhtml" | "text" | eqname }
    byte-order-mark? = { boolean }
    cdata-section-elements? = { eqnames }
    doctype-public? = { string }
    doctype-system? = { string }
    encoding? = { string }
    escape-uri-attributes? = { boolean }
    html-version? = { decimal }
    include-content-type? = { boolean }
    indent? = { boolean }
    item-separator? = { string }
    media-type? = { string }
    normalization-form? = { "NFC" | "NFD" | "NFKC" | "NFKD" | "fully-normalized" | "none" | nmtoken }
    omit-xml-declaration? = { boolean }
    parameter-document? = { uri }
    standalone? = { boolean | "omit" }
    suppress-indentation? = { eqnames }
    undeclare-prefixes? = { boolean }
    use-character-maps? = eqnames
    output-version? = { nmtoken } >
    <!-- Content: sequence-constructor -->
</xsl:result-document>

Описание и примеры

Пример

Для демонстрации возможностей <xsl:result-document> используется следующий небольшой документ DocBook:

<?xml version="1.0"?>
<!-- chapters.xml -->
<book>
    <title>XSLT Topics</title>
    <chapter>
        <title>XPath</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Stylesheet Basics</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Branching and Control Elements</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Functions</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Creating Links and Cross-References</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Sorting and Grouping Elements</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
    <chapter>
        <title>Combining XML Documents</title>
        <para>If this chapter had any text, it would appear here.</para>
    </chapter>
</book>

Таблица стилей используется для создания нескольких документов. Сначала создается общий файл HTML с перечислением всех названий (<title>) элементов <chapter>, определенных в документе. Каждое название оформляется в виде ссылки на отдельный файл HTML, создаваемый при помощи <xsl:result-document>. Элемент <xsl:result-document> создает отдельный файл HTML для каждого элемента <chapter>. Таблица стилей выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<!-- result-document.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" include-content-type="no"/>
    <xsl:template match="/">
        <html>
            <head>
                <title><xsl:value-of select="book/title"/></title>
            </head>
            <body>
                <h1><xsl:value-of select="book/title"/></h1>
                <p>Here are some interesting XSLT topics:</p>
                <ul>
                    <xsl:for-each select="book/chapter">
                        <li>
                            <a href="{concat('chapter', position(), '.html')}">
                                <xsl:value-of select="title"/>
                            </a>
                        </li>
                    </xsl:for-each>
                </ul>
                <xsl:for-each select="book/chapter">
                    <xsl:result-document method="html" include-content-type="no" href="{concat('chapter', position(), '.html')}">
                        <html>
                            <head>
                                <title><xsl:value-of select="title"/></title>
                            </head>
                            <body>
                                <h1><xsl:value-of select="title"/></h1>
                                <xsl:apply-templates select="*[position() > 1]"/>
                            </body>
                        </html>
                    </xsl:result-document>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="para">
        <p><xsl:apply-templates select="*|text()"/></p>
    </xsl:template>
</xsl:stylesheet>

Таблица стилей начинается с создания главного документа HTML. Элемент <xsl:for-each select="book/chapter"> создает пункт списка и ссылку для каждого элемента <chapter> в исходном документе. Затем другой элемент <xsl:for-each> при помощи <xsl:result-document> создает новый документ для каждого элемента <chapter>. Обратите внимание на использование шаблона значения атрибута {concat('chapter', position(), '.html')} для создания имен файлов и ссылок. Можно было потребовать, чтобы в каждый элемент <chapter> включался специальный идентификационный атрибут, но проще воспользоваться жестко заданной схемой построения имен для создания файлов и ссылок. Четвертый элемент <chapter> соответствует файлу chapter4.html. Главный файл HTML выглядит так:

<html>
    <head>
        <title>XSLT Topics</title>
    </head>
    <body>
        <h1>XSLT Topics</h1>
        <p>Here are some interesting XSLT topics:</p>
        <ul>
            <li><a href="chapter1.html">XPath</a></li>
            <li><a href="chapter2.html">Stylesheet Basics</a></li>
            <li><a href="chapter3.html">Branching and Control Elements</a></li>
            <li><a href="chapter4.html">Functions</a></li>
            <li><a href="chapter5.html">Creating Links and Cross-References</a></li>
            <li><a href="chapter6.html">Sorting and Grouping Elements</a></li>
            <li><a href="chapter7.html">Combining XML Documents</a></li>
        </ul>
    </body>
</html>

Каждый файл HTML отдельной главы выглядит примерно так:

<html>
    <head>
        <title>XPath</title>
    </head>
    <body>
        <h1>XPath</h1>
        <p>If this chapter had any text, it would appear here.</p>
    </body>
</html>

Щелчок на любой ссылке открывает один документ отдельной главы, созданный элементом <xsl:result-document>. Элемент <xsl:result-document> официально заменяет стандартные элементы расширения в большинстве процессоров XSLT 1.0. Для создания нескольких выходных файлов в процессорах XSLT 1.0 приходилось вызывать элементы расширения, поддерживаемые конкретным процессором.