Стивен Холзнер - XSLT
При использовании атрибута 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 завоевывают все большую популярность, поэтому на них я также останавливаю ваше внимание.
Метод вывода: текст
Этот метод вывода представляет простой текст. В данном случае выходной документ являет собой только простой текст дерева документа. То есть процессор XSLT создает результирующее дерево, выводя строковое значение каждого текстового узла, без каких-либо сокращений.
Значением по умолчанию для атрибута media-type является «text/plain». Атрибут encoding устанавливает кодировку, используемую процессором XSLT для преобразования последовательностей символов в последовательности байтов. Заметьте, что если результирующий документ содержит символ, который не может быть представлен в выходной кодировке, процессор XSLT должен сгенерировать ошибку.
В листинге 6.4 planets.xml преобразуется в простой текст при помощи метода текстового вывода.
Листинг 6.4. Преобразование в простой текст<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:template match="PLANET">
<xsl:value-of select="NAME"/>
<xsl:text>'s mass is </xsl:text>
<xsl:value-of select="MASS"/>
<xsl:text> Earth masses. Its radius is </xsl:text>
<xsl:value-of select="RADIUS"/>
<xsl:text> miles. Its day is </xsl:text>
<xsl:value-of select="DAY"/>
<xsl:text> Earth days long.</xsl:text>
</xsl:template>
</xsl:stylesheet>
И вот результат — просто чистый текст, никакой разметки, никаких пропущенных символов, никаких инструкций обработки:
Mercury's mass is .0553 Earth masses. Its radius is 1516 miles. Its day is 58.65 Earth days long.
Venus's mass is .815 Earth masses. Its radius is 3716 miles. Its day is 116.75 Earth days long.
Earth's mass is 1 Earth masses. Its radius is 2107 miles. Its day is 1 Earth days long.
С другой стороны, метод текстового вывода предназначен не только для создания простого текста, он также применяется для любых текстовых форматов, отличных от XML и HTML. Как мы видели в главе 2, с его помощью можно создавать форматированные документы в формате Rich Text Format (RTF). Rich Text Format использует встроенные текстовые коды, задающие формат документов, и при помощи метода текстового вывода вы можете самостоятельно поместить эти коды в документы.
Следующий пример таблицы стилей первоначально был приведен в главе 2, где она использовалась с целью перевода planets.xml в формат RTF, для понимания которого вы теперь лучше вооружены. В этом случае я преобразую planets.xml в planets.rtf, используя коды RTF как элементы буквального результата:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/PLANETS">{rtf1ansideff0{fonttbl
{\fcharset0 Courier New:}}
viewkind4uclpardlang1033b The Planets Tablepar
b0 Nametab Masstab Rad.tab Daypar
<xsl:apply-templates/>
par
}</xsl:template>
<xsl:template match="PLANET">
<xsl:value-of select="NAME"/>
tab
<xsl:value-of select="MASS"/>
tab
<xsl:value-of select="RADIUS"/>
tab
<xsl:value-of select="DAY"/>
tab
par
</xsl:template>
</xsl:stylesheet>
Результирующий документ RTF, planets.rtf, показан на рис. 6.2 в редакторе Microsoft Word 2000.
Рис. 6.2. Файл planets.rtf в Microsoft Word
Заметьте, что методом вывода является текст, а не что-нибудь наподобие «rtf»: