несколько элементов XSL невысокого уровня. W3C называет такую таблицу «элемент буквального результата как таблица».
В листинге 2.7 я осуществлю преобразование planets.xml
в planets.html
, но теперь я сделаю это при помощи упрощенной таблицы стилей. В упрощенных таблицах стилей вы не можете применять элементы высокого уровня, такие как <xsl:template>
, позволяющие рекурсивную обработку всех элементов в исходном документе. Поэтому здесь я зайду немного вперед и воспользуюсь элементом <xsl:for- each>
(рассматриваемым в главе 5), который, не являясь элементом высокого уровня, позволяет обработать в цикле сразу несколько узлов.
Мне также нужно каким-либо образом выбрать все элементы <PLANET>
в исходном документе, и вы можете подумать, что это невозможно без использования шаблонов нескольких уровней — например, один для корневого узла, затем один для выбора на следующем уровне вниз, корневом элементе <PLANETS>
, и затем еще один уровень вниз для самих элементов <PLANET>
. Однако, используя XPath, можно при помощи выражения '//PLANET
' найти все узлы элемента <PLANET>
, производные от корневого узла (см. главу 4). Это значит, что я могу написать упрощенную таблицу стилей следующим образом.
<HTML xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xsl:version='1.0'>
<HEAD>
<TITLE>
The Planets Table
</TITLE>
</HEAD>
<BODY>
<H1>
The Planets Table
</H1>
<TABLE BORDER='2'>
<TR>
<TD>Name</TD>
<TD>Mass</TD>
<TD>Radius</TD>
<TD>Day</TD>
</TR>
<xsl:for-each select='//PLANET'>
<TR>
<TD><xsl:value-of select='NAME'/></TD>
<TD><xsl:value-of select='MASS'/></TD>
<TD><xsl:value-of select='RADIUS'/></TD>
<TD><xsl:value-of select='DAY'/></TD>
</TR>
</xsl:for-each>
</TABLE>
</BODY>
</HTML>
Данная версия работает точно так же, как и предыдущая версия planets.xsl
, при этом совсем не используя элементы высокого уровня. Упрощенные таблицы стилей, такие как эта, были представлены в помощь авторам HTML при осуществлении преобразований в XSL, однако их применимость весьма ограничена. Очевидно, все равно нужно знать, как работать с элементами XSL, а отсутствие возможности использовать <xsl:template>
в данном случае только затруднило работу. Однако вы должны знать, что упрощенные таблицы стилей существуют и включены в спецификацию XSLT.
ОБРАБОТКА ПО УМОЛЧАНИЮ БЕЗ ЭЛЕМЕНТА <XSL:STYLESHEET>
Если процессор XSLT не может найти в таблице стилей элемент <xsl:stylesheet>, он трактует таблицу как упрощенную таблицу стилей.
Встроенные таблицы стилей
Рекомендация XSLT также поддерживает встроенные таблицы стилей, embedded stylesheets (вслед за использованием встроенных таблиц стилей и элементов стиля в HTML), но, как и упрощенные таблицы стилей, они не очень распространены.
Встроенные таблицы стилей могут обрабатывать не все процессоры XSLT, но некоторые — в частности, Saxon — могут. Давайте рассмотрим пример. В этом случае я включил весь элемент таблицы стилей целиком из planets.xsl
в planets.xml
для создания нового документа, embedded.xml
. В новом документе будут содержаться все данные и вся таблица стилей. Заметьте, что для того, чтобы быть хорошо сформированным XML, embedded.xml
должен иметь только один корневой элемент, поэтому я сделал таблицу стилей (то есть элемент <xsl:stylesheet>
) родительским элементом корневого элемента <PLANETS>
.
Чтобы указать, какой элемент будет трактоваться как встроенная таблица стилей, я задал элементу <xsl:stylesheet>
ID 'stylesheet', установив атрибут id
в это имя:
<xsl:stylesheet version='1.0' id='stylesheet'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
В начале документа я также присваиваю это имя, 'stylesheet', атрибуту href
элемента <?xml-stylesheet?>
:
<?xml-stylesheet type='text/xml' href='#stylesheet'?>
Теперь процессору XSLT известно, какой элемент я хочу использовать в качестве таблицы стилей — элемент с ID 'stylesheet'. Но что это за элемент? Элементы XML формируют элементы типа ID в объявлениях DTD или схемах XML, и, как вы помните, информация объявлений DTD и схем пока еще не передается процессору XSLT.
Некоторые процессоры XSLT, такие как Saxon, читают объявление DTD, если оно есть, для определения атрибутов, обладающих типом ID, поэтому я включил DTD в embedded.xml
(листинг 2.8).
<?xml version='1.0'?>
<?xml-stylesheet type='text/xml' href='#stylesheet'?>
<!DOCTYPE PLANETS [
<!ELEMENT PLANET (CUSTOMER)*>
<!ELEMENT CUSTOMER (NAME,MASS,RADIUS,DAY)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT MASS (#PCDATA)>
<!ELEMENT RADIUS (#PCDATA)>
<!ELEMENT DAY (#PCDATA)>
<!ELEMENT xsl:stylesheet (xsl:template)*>