<xsl:document> XSLT

Элемент xsl:document создает новый узел документа. Элемент может использоваться, например, для проверки узла документа по схеме. Узел документа, созданный элементом <xsl:document>, не предназначен для сериализации (записи на диск); для создания сериализуемого узла документа следует использовать элемент <xsl:result-document>.

Синтаксис

XSLT 2.0 и XSLT 3.0

<xsl:document
    validation = "strict | lax | preserve | strip"
    type = "строка">
    <!-- Content: sequence-constructor -->
</xsl:document>

Атрибуты

  • typeнеобязательный атрибут, определят тип данных корневого узла элемента, создаваемого этим элементом. Чтобы узел документа прошел проверку на действительность, его единственным дочерним элементом должен быть один узел элемента, без текстовых узлов и с нулем или более узлами комментариев и инструкций по обработке. Если структура узла документа не соответствует этому описанию, процессор XSLT выдает ошибку. Атрибуты type и validation являются взаимоисключающими.
  • validationнеобязательный атрибут, определяет способ проверки значения нового атрибута. Атрибут validation имеет четыре допустимых значения: strict, lax, preserve и strip. Чтобы узел документа прошел проверку на действительность в режимах strict и lax, его единственным дочерним элементом должен быть один узел элемента, без текстовых узлов и с нулем или более узлами комментариев и инструкций по обработке. Если в режиме strict или lax структура узла документа не соответствует этому описанию, процессор XSLT выдает ошибку. Атрибут validation="strict" означает, что процессор XSLT должен искать во всех объявленных схемах глобальное объявление элемента (<xs:element>) с таким же именем, как у единственного узла элемента, являющегося дочерним узлом этого узла документа. Если процессору не удается найти подходящее объявление <xs:element>, происходит фатальная ошибка. Если же процессор находит объявление узла элемента, он проверяет по нему сгенерированное значение. Значение validation="lax" работает аналогично validation="strict", но если процессору не удается найти объявление элемента ни в одной из объявленных схем, ошибка не происходит. В этом случае элемент имеет обозначение типа xs:untyped. Со значением validation="preserve" обозначения типов единственного узла элемента и всех его дочерних элементов и атрибутов сохраняются без изменений. Проверка по схеме не выполняется. Значение validation="strip" назначает единственному узлу элемента обозначение типа xs:untyped. Всем дочерним элементам и атрибутам задаются обозначения типов xs:untyped и xs:untypedAtomic соответственно. Проверка по схеме не выполняется. Атрибуты validation и type являются взаимоисключающими.

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

Пример

В следующем примере мы создадим узел документа и зададим его содержимое. Согласно определению из схемы документа с заказами этим узлом будет элемент <name>:

<?xml version="1.0" encoding="UTF-8"?>
<!-- po.xsd -->
<xs:schema xmlns="http://www.oreilly.com/xslt" targetNamespace="http://www.oreilly.com/xslt" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="purchase-order">
        ...
    </xs:element>
    ...
    <xs:element name="name">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="title" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="first-name" minOccurs="1" maxOccurs="1"/>
                <xs:element ref="last-name" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="title" type="xs:string"/>
    <xs:element name="first-name" type="xs:string"/>
    <xs:element name="last-name" type="xs:string"/>
</xs:schema>

Таблица стилей:

<?xml version="1.0"?>
<!-- document.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.oreilly.com/xslt" xmlns:po="http://www.oreilly.com/xslt">
    <xsl:output method="xml" indent="yes"/>
    <xsl:import-schema namespace="http://www.oreilly.com/xslt" schema-location="po.xsd" />
    <xsl:template match="/">
        <xsl:document validation="lax">
            <xsl:element name="name">
                <xsl:element name="title">
                    <xsl:text>Mr.</xsl:text>
                </xsl:element>
                <xsl:element name="first-name">
                    <xsl:text>Kent Lyle</xsl:text>
                </xsl:element>
                <xsl:element name="last-name">
                    <xsl:text>Birdley</xsl:text>
                </xsl:element>
            </xsl:element>
        </xsl:document>
    </xsl:template>
</xsl:stylesheet>

В этом примере используется режим validation="lax". Это означает, что процессор XSLT подтвердит действительность узла документа, содержащего элемент <name>, если ему удастся найти схему XML с определением элемента <name>. Если убрать элемент <xsl:import-schema>, элемент <xsl:document> все равно будет работать. Но если убрать элемент <xsl:import-schema> и перевести <xsl:document> в режим validation="strict", попытка выполнения таблицы стилей завершится неудачей, потому что процессор не находит объявление <name>.

Результаты применения таблицы стилей:

<?xml version="1.0" encoding="UTF-8"?>
<name xmlns="http://www.oreilly.com/xslt">
    <title>Mr.</title>
    <first-name>Kent Lyle</first-name>
    <last-name>Birdley</last-name>
</name>

В данном случае содержимое элемента <xsl:document> просто записывается в выходной поток. В более стандартном варианте использования <xsl:document> узел документа сохраняется в переменной, а затем эта переменная, прошедшая проверку действительности, используется в другом месте таблицы стилей.

Элемент <xsl:document> может использоваться для создания узла документа, который не является корректным (well-formed). Пример соответствующей таблицы стилей:

<?xml version="1.0"?>
<!-- document2.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:variable name="ill-formed" as="node()*">
        <xsl:document>
            <xsl:element name="title">
                <xsl:text>Mr.</xsl:text>
            </xsl:element>
            <xsl:element name="first-name">
                <xsl:text>Kent Lyle</xsl:text>
            </xsl:element>
            <xsl:element name="last-name">
                <xsl:text>Birdley</xsl:text>
            </xsl:element>
        </xsl:document>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:text>A document node that isn't well formed:</xsl:text>
        <xsl:text> Is this a document node? </xsl:text>
        <xsl:value-of select="if ($ill-formed instance of document-node()) then 'Yes!' else 'No!'"/>
        <xsl:text> Number of child elements: </xsl:text>
        <xsl:value-of select="count($ill-formed/*)"/>
        <xsl:result-document method="xml" href="ill-formed.xml">
            <xsl:copy-of select="$ill-formed"/>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

Таблица стилей создает переменную с именем $ill-formed, содержащую три элемента в корне документа. При помощи теста узла document-node() мы убеждаемся в том, что узел действительно является узлом документа, а затем выводим количество его дочерних элементов:

A document node that isn't well formed:
Is this a document node? Yes!
Number of child elements: 3

Наконец, элемент <xsl:result-document> записывает недействительную разметку в файл. Файл ill-formed.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<title>Mr.</title>
<first-name>Kent Lyle</first-name>
<last-name>Birdley</last-name>

Обычно узел документа имеет один дочерний узел, который представляет элемент документа; в данном случае недопустимая разметка создается в обход парсера XML. Хотя такая ситуация не типична, следует помнить, что таблица стилей может сгенерировать узел документа, имеющий более одного дочернего узла.