Метод вывода "xml"

Метод вывода "xml"

Для того чтобы вывести результирующее дерево в виде XML-документа, следует использовать в элементе xsl:output метод "xml". Ниже мы подробно опишем, каким образом на выход должны влиять другие атрибуты этого элемента.

Атрибут version

Этот атрибут определяет версию языка XML, которая должна использоваться для вывода результирующего документа. В случае если процессор не поддерживает указанную версию, он может либо выдать ошибку, либо использовать одну из поддерживаемых версий. На данный момент единственной действующей версией языка является версия 1.0 и потому, если в атрибуте в version будет указано другое значение, единственным эффектом от этого будет измененный параметр version в декларации XML.

Пример

Предположим, что в преобразовании версия выходящего документа задана как 1.2:

<xsl:output method="xml" version="1.2"/>

Тогда процессор может вывести декларацию XML в следующем виде:

<?xml version="1.2" encoding="utf-8"?>

Значением атрибута version по умолчанию является "1.0", то есть, для того, чтобы получить декларацию XML вида

<?xml version="1.0" и т. д. ?>

достаточно опустить определение атрибута version:

<xsl:output method="xml"/>

Атрибут encoding

Атрибут encoding указывает на то, какая кодировка предпочтительна для выходящего документа. Множество кодировок зависит от используемого процессора, но при этом в соответствии с технической рекомендацией все они обязаны поддерживать Unicode-формы кодировок UTF-8 и UTF-16.

В случае если процессор не поддерживает кодировку, указанную в атрибуте encoding, процессор может либо выдать ошибку, либо использовать UTF-8 или UTF-16.

Если атрибут encoding опущен, процессор должен по умолчанию использовать UTF-8 или UTF-16. На практике абсолютное большинство процессоров используют по умолчанию кодировку UTF-8.

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

Пример

Представим себе входящий документ в кодировке UTF-8, содержащий символ кириллицы "Э" с Unicode-кодом #x42d (или #1069 в десятичной системе счисления):

<?xml version="1.0" encoding="utf-8"?>

<page>Э</page>

Если преобразование будет использовать для вывода кодировку, которая не может отображать символы кириллического алфавита, например ISO-8859-1, то символ "Э" в выходящем документе должен быть заменен символьной сущностью.

Листинг 8.36. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output

  method="xml"

  encoding="ISO-8859-1"

  indent="yes"/>

 <xsl:template match="/">

  <xsl:copy-of select="/page"/>

 </xsl:template>

</xsl:stylesheet>

Листинг 8.37. Выходящий документ

<?xml version="1.0" encoding="ISO-8859-1"?>

<page>&#1069;</page>

Вместе с тем синтаксис XML не разрешает использовать символьные сущности в именах элементов и атрибутов, и наличие в них символов, не отображаемых кодировкой вывода, будет являться ошибкой. Если в предыдущем примере документ будет иметь вид

<?xml version="1.0" encoding="utf-8"?>

<страница>Э</страница>

то вывести результирующее дерево в кодировке ISO-8859-1 будет невозможно.

Атрибут indent

Индентацией называют форматирование исходного текста, не влияющее на семантику, но облегчающее читаемость. К примеру, один и тот же XML-документ можно написать как

<A><В><С/></В><С><В></В></С></А>

или

<A>

 <B>

  <C/>

 </B>

 <C>

  <B>

  </B>

 </C>

</A>

Очевидно, что второй случай гораздо легче для понимания, поскольку в нем легко можно видеть принадлежность элементов одного другому. Подобное форматирование можно использовать и при выводе преобразованного документа при помощи атрибута indent элемента xsl:output. Если этот атрибут имеет значение "yes", процессор может добавить один или несколько пробельных символов или символов перевода строки — в зависимости от реализации. Как правило, каждый дочерний элемент помещают на новой строке, добавляя впереди два пробела на каждый уровень вложенности.

Пример

Листинг 8.38. Входящий документ

<?xml version="1.0" encoding="utf-8"?>

<A><B><C/></B><C><B></В></C></A>

Листинг 8.39. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output indent="yes"/>

 <xsl:template match="/">

  <xsl:copy-of select="/"/>

 </xsl:template>

</xsl:stylesheet>

Листинг 8.40. Выходящий документ

<?xml version="1.0" encoding="utf-8"?>

<A>

 <B>

  <C/>

 </B>

 <C>

  <B/>

 </C>

</A>

Следует быть осторожными при использовании indent="yes" там, где в содержимом документа могут встречаться значащие пробелы. Индентация позволяет процессору при выводе документа добавлять пробельные символы по собственному усмотрению. В случаях, когда при последующей обработке преобразованного документа пробельные символы могут быть восприняты неадекватно, лучше индентацию не использовать.

Атрибут cdata-section-elements

Для того чтобы вывести текстовое содержимое некоторых элементов в виде секций CDATA, XSLT предлагает простой механизм — следует лишь перечислить в атрибуте cdata-section-elements элемента xsl:output элементы, которые на выходе должны содержать секции символьных данных.

Пример

Листинг 8.41. Входящий документ

<?xml version="1.0" encoding="utf-8"?>

<page>&lt;br/&gt;<br/></page>

Листинг 8.42. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output

  indent="yes"

  cdata-section-elements="page"/>

 <xsl:template match="/">

  <xsl:copy-of select="/"/>

 </xsl:template>

</xsl:stylesheet>

Листинг 8.43. Выходящий документ

<?xml version="1.0" encoding="utf-8"?>

<page><![CDATA[<br/>]]><br/>

</page>

В соответствии с синтаксисом XML, секции CDATA не могут содержать последовательности символов "]]>". Потому, встретив такую комбинацию в тексте элемента, имя которого включено в cdata-section-elements, процессор заменит ее двумя секциями CDATA. Одна будет содержать "]]", вторая – ">".

Пример

Листинг 8.44. Входящий документ

<?xml version="1.0" encoding="utf-8"?>

<page>

 <data>]]&gt;</data>

 <pre>&lt;!-- Comment --></pre>

</page>

Листинг 8.45. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output

 indent="yes"

 cdata-section-elements="data pre"/>

 <xsl:template match="/">

  <xsl:copy-of select="/"/>

 </xsl:template>

</xsl:stylesheet>

Листинг 8.46. Выходящий документ

<?xml version="1.0" encoding="utf-8"?>

<page>

 <data><![CDATA[]]]]><![CDATA[>]]></data>

 <pre><![CDATA[<!-- Comment -->]]></pre>

</page>

Атрибут doctype-system

Для определения логической структуры документов в XML используются DTD — определения типов документов. В большинстве случаев определения типов содержатся во внешних ресурсах, которые включаются в документ в виде системных или публичных идентификаторов.

XSLT позволяет создавать ссылки на внешние определения типов при помощи атрибута doctype-system элемента xsl:output.

Пример

Предположим, что мы создаем документ, логическая схема которого определена во внешнем файле по адресу "/dtds/document.dtd". Тогда, определив в преобразовании элемент xsl:output с атрибутом doctype-system, равным "/dtds/document.dtd", мы получим в выходящем документе определение типа в виде

<!DOCTYPE элемент SYSTEM "/dtds/document.dtd">

где элемент — первый элемент выходящего документа.

Листинг 8.47. Входящий документ

<?xml version="1.0" encoding="utf-8"?>

<page> content </page>

Листинг 8.48. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output indent="yes" doctype-system="/dtds/document.dtd"/>

 <xsl:template match="/"><xsl:copy-of select="/"/></xsl: template>

</xsl:stylesheet>

Листинг 8.49. Выходящий документ

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE page SYSTEM "/dtds/document.dtd">

<page> content </page>

Атрибут doctype-public

Если в преобразовании атрибутом doctype-system элемента xsl:output задано внешнее определение логического типа документа, это определение может быть расширено также и публичным идентификатором. Публичный идентификатор указывается в атрибуте doctype-public элемента xsl:output. Его использование может быть продемонстрировано следующим примером.

Листинг 8.50. Входящий документ

<?xml version="1.0" encoding="utf-8"?>

<page> content </page>

Листинг 8.51. Преобразование

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output indent="yes"

  doctype-system="/dtds/document.dtd"

  doctype-public="-//Document//Description" />

 <xsl:template match="/"><xsl:copy-of select="/"/></xsl:template>

</xsl:stylesheet>

Листинг 8.52. Выходящий документ

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE page

 PUBLIC "-//Document//Description" "/dtds/document.dtd">

<page> content </page>

Атрибут media-type

Атрибут media-type позволяет задавать медиа-тип содержимого выходящего документа. Для метода вывода "xml" значением media-type по умолчанию является "text/xml". Несмотря на то, что media-type не оказывает никакого влияния на содержимое самого документа, XSLT-процессоры, используемые на стороне сервера, могут в зависимости от значения этого атрибута изменять MIME-тип исходящих данных при использовании, к примеру, такого протокола, как HTTP.

Атрибут omit-xml-declaration

XML-документы, в принципе, могут быть корректными и без декларации XML. Поэтому XSLT позволяет опускать эту декларацию в выходящем документе, для чего значению атрибута omit-xml-declaration должно быть присвоено "yes":

<xsl:output

 omit-xml-declaration="yes"/>

В случае если значение атрибута omit-xml-declaration опущено или не равно "yes", процессор будет выводить в выходящем документе декларацию XML, которая включает информацию о версии (по умолчанию "1.0") и кодировке документа (по умолчанию "utf-8" или "utf-16" в зависимости от процессора).

Атрибут standalone

Для того чтобы объявить документ как самостоятельный или несамостоятельный (standalone или non-standalone соответственно), следует использовать атрибут standalone элемента xsl:output. Если этот атрибут будет присутствовать в xsl:output, то процессор включит в декларацию XML объявление standalone с соответствующим значением. Если атрибут standalone не указан, объявление standalone в декларацию XML выходящего документа включено не будет.