Метод вывода: XML
Метод вывода: XML
Формально при использовании метода вывода XML процессор XSLT создает хорошо сформированный внешний объект XML, который можно разобрать на общих условиях. Если корневой узел результирующего дерева имеет единственный дочерний узел-элемент и не имеет текстовых дочерних узлов. Тогда объект будет также хорошо сформированным документом XML.
При использовании метода вывода XML атрибут version устанавливает версию XML результата. Заметьте, что если процессор XSLT не поддерживает эту версию XML, он будет использовать ту версию XML, которую поддерживает. По умолчанию установлено значение 1.0.
Атрибут encoding устанавливает кодировку для результирующего документа. Процессоры XSLT должны поддерживать, по крайней мере, значения «UTF-8» и «UTF-16». Если процессор XSLT работает с другими значениями и не поддерживает указанную кодировку, он может сгенерировать ошибку. Если он этого не сделает, процессор должен использовать вместо нее UTF-8 иди UTF-16. Процессор XSLT не должен использовать кодировку, которая не была принята консорциумом W3C (см. www.ww3.org/TR/REC-xml). Если никакой атрибут кодировки не указан, по умолчанию процессор XSLT должен выбрать «UTF-8» или «UTF-16».
ОБРАБОТКА НЕИЗВЕСТНЫХ СИМВОЛОВ
Если результирующий документ содержит символ, который не может быть представлен в кодировке, используемой процессором XSLT для вывода, символ допустимо вывести как ссылку на символ. Если это невозможно, процессор XSLT должен сгенерировать ошибку.
Как и в случае с методом вывода HTML, если атрибут indent установлен в «yes», метод вывода XML может добавить или удалить символы-разделители в результирующее дерево для того, чтобы выровнять результат. Значение по умолчанию — no. Заметьте, что если символы-разделители отбрасываются, информационное множество результирующего XML-документа должно быть таким же, как если бы символы-разделители вообще не добавлялись и не удалялись для выравнивания документа.
ВЫРАВНИВАНИЕ ДОКУМЕНТОВ СО СМЕШАННЫМ СОДЕРЖИМЫМ
Для документов со смешанным содержимым лучше не устанавливать атрибут indent в «yes», поскольку это вносит путаницу в работу процессора XSLT.
При помощи атрибута cdata-section-elements можно задать разделенный символами-разделителями список имен элементов, чье содержимое должно трактоваться как разделы CDATA. Например, если установить атрибут cdata-section-elements в «DATA»:
<xsl:output cdata-section-elements="DATA"/>
то следующий элемент буквального результата:
<DATA><:DOCUMENT></DATA>
будет преобразован в:
<DATA><![CDATA<[DOCUMENT>]]></DATA>
Кроме того, метод вывода XML будет выводить в результирующий документ объявление XML, если только атрибут omit-xml-declaration не будет установлен в yes. Как правило, объявление XML, помещаемое в результирующий документ, обычно включает версию XML (что обязательно) и информацию о кодировке (хотя формально информация о кодировке в документах XML не обязательна). Если задан атрибут standalone, результирующий документ должен включать объявление отдельного документа с тем же значением, что и значение у атрибута standalone.
При использовании атрибута doctype-system процессор создает объявление типа документа непосредственно перед первым элементом. В этом случае имя, следующее за <!DOCTYPE>, будет именем корневого элемента. Заметьте, что если вы также используете атрибут doctype-public, процессор XSLT выведет «PUBLIC», вслед за ним открытый идентификатор и затем системный идентификатор. Если вы не используете атрибут doctype-public, процессор выведет «SYSTEM» и вслед за ним системный идентификатор. Теоретически атрибут doctype-public должен игнорироваться, если не задан также атрибут doctype-system, хотя большинство процессоров, кажется, не следуют этому правилу. Мы увидим, как работать с атрибутами doctype-public и doctype-system в этой главе при преобразовании XML в XHTML.
Наконец, для метода вывода XML значением по умолчанию для атрибута media-type является «text/xml».
Вы уже встречали в этой книге многие XML-XML преобразования. Например, преобразование из главы 4 просто копировало один документ XML в другой. Обратите внимание на метод вывода, который установлен в XML:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Этот пример был приведен в начале главы, в нем planets.xml реорганизован на основе плотности планет:
<?xml version="1.0" encoding="UTF-8"?>
<DATA>
<DENSITY>
<VALUE>.983</VALUE>
<NAME>Mercury</NAME>
<MASS>.0553</MASS>
<DAY>58.65</DAY>
<RADIUS>1516</RADIUS>
</DENSITY>
<DENSITY>
<VALUE>.943</VALUE>
<NAME>Venus</NAME>
<MASS>.815</MASS>
<DAY>116.75</DAY>
<RADIUS>3716</RADIUS>
</DENSITY>
<DENSITY>
<VALUE>1</VALUE>
<NAME>Earth</NAME>
<MASS>1</MASS>
<DAY>1</DAY>
<RADIUS>2107</RADIUS>
</DENSITY>
</DATA>
Вот таблица стилей (листинг 6.3), создающая это преобразование.
Листинг 6.3. Реорганизация planets.xml на основе плотности
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="PLANETS">
<DATA>
<xsl:apply-templates/>
</DATA>
</xsl:template>
<xsl:template match="PLANET">
<DENSITY>
<VALUE>
<xsl:value-of select="DENSITY"/>
</VALUE>
<xsl:apply-templates/>
</DENSITY>
</xsl:template>
<xsl:template match="NAME">
<NAME>
<xsl:value-of select="."/>
</NAME>
</xsl:template>
<xsl:template match="MASS">
<MASS>
<xsl:value-of select="."/>
</MASS>
</xsl:template>
<xsl:template match="RADIUS">
<RADIUS>
<xsl:value-of select="."/>
</RADIUS>
</xsl:template>
<xsl:template match="DAY">
<DAY>
<xsl:value-of select="."/>
</DAY>
</xsl:template>
<xsl:template match="DENSITY">
</xsl:template>
<xsl:template match="DISTANCE">
</xsl:template>
</xsl:stylesheet>
Следующий пример впервые был приведен в главе 5. В этом случае я только перечислил планеты из planets.xml, но в выходном документе я хотел видеть не просто фразу «The first three planets are: Mercury Venus Earth» (первые три планеты: Меркурий Венера Земля), a «The first three planets are: Mercury, Venus, and Earth.». Для этого я применил элементы <xsl:if>:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="PLANETS">
<DOCUMENT>
<TITLE>
The Planets
</TITLE>
<PLANETS>
The first three planets are: <xsl:apply-templates select="PLANET"/>
</PLANETS>
</DOCUMENT>
</xsl:template>
<xsl:template match="PLANET">
<xsl:value-of select="NAME"/>
<xsl:if test="position()!=last()">. </xsl:if>
<xsl:if test="position()=last()-1">and </xsl:if>
<xsl:if test="position()=last()">.</xsl:if>
</xsl:template>
</xsl:stylesheet>
И вот результат:
<?xml version="1.0" encoding="UTF-8"?>
<DOCUMENT>
<TITLE>
The Planets
</TITLE>
<PLANETS>
The first three planets are: Mercury, Venus, and Earth.
</PLANETS>
</DOCUMENT>
Хотя многие книги рассматривают главным образом преобразования из XML в HTML, важно понять, что преобразования XML-XML завоевывают все большую популярность, поэтому на них я также останавливаю ваше внимание.