XML и сопутствующие технологии
О рассылке
Сайт рассылки: http://www.frnet.narod.ru/. На нем вы найдете все выпуски рассылки, а также полезную информацию по web-дизайну и web-программированию.
Выпуск №4: Bведение в XSLT. Преобразование в HTML
Inside XSLT, S. Holsner

Предположим, web-узел вашей компании использует основанное на XML программное обеспечение фирмы Commerce One, в котором для безопасной коммуникации через Интернет применяется Java Message Service (JMS). Ваша деятельность была настолько успешной, что вы только что поглотили своего конкурента. К сожалению, для своего узла в Интернете ваш бывший конкурент использует другой основанный на XML продукт, RosettaNet. Как вам теперь преобразовать заказ на покупку xCBL Commerce One, написанный на XML, в заказ на покупку RosettaNet, также написанный на XML, но совершенно на другом диалекте?

Разумеется, применить XSLT. Такого рода XML-XML преобразования становятся все более и более распространенными. Все больше компаний применяют JMS для безопасных коммуникаций через Интернет, и поскольку JMS выполняется в Java, будет разумным связать JMS с основанными на Java процессорами XSLT, такими, как Xalan или Saxon.

Основная задача XSLT состоит не просто в замене одного элемента на другой, но в полной реорганизации содержимого XML-документа. Например, вам может потребоваться реорганизовать planets.xml в терминах плотности планет при помощи XSLT для создания нового 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>

Мы рассмотрим преобразование, которое полностью меняет содержимое planets. xml, оставляя только небольшой код HTML и код JavaScript для отображения нескольких кнопок в браузере.

До сих пор мы создавали новые элементы только при помощи элементов буквального результата, то есть рассматривая новые элементы как текст и встраивая их в таблицу стилей. Но, как мы увидим в этой главе, не всегда возможно знать имена создаваемых новых элементов. Можно состыковать вместе создаваемые элементы по ходу дела, рассматривая их как сырой текст, но это явная недоработка, поскольку разметка трактуется как текст. В этой главе мы начнем применять элементы XSLT <xsl:element>, <xsl:attribute>, <xsl:processing-instruction> и <xsl:comment> для создания новых элементов, атрибутов, инструкций обработки и комментариев на этапе выполнения. Хорошее знание этих элементов необходимо при реорганизации содержимого XML.

Мы также рассмотрим использование режимов XSLT для осуществления нескольких преобразований с документом и сориентируемся, как применять только один из нескольких подходящих шаблонов.

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

Элемент <xsl:output>

С элементом <xsl:output>, элемент мы впервые познакомились в главе 2 и использовали его, главным образом, для задания типа результирующего документа. Этот тип может задать, например, будет ли процессор XSLT записывать инструкцию обработки XML, <?xml version="1.0"?>, в начале документа, а также задать тип MIME (такой, как "text/xml" или "text/html") документов, отправляемых процессором XSLT из web-сервера браузеру. Кроме того, если вы установите выходной тип в HTML, большинство процессоров XSLT смогут распознать, что не всем элементам HTML необходимы закрывающие или открывающие теги и т. п.

В следующем списке перечислены атрибуты <xsl:output>:

  • cdata-section-elements (необязательный). Задает имена тех элементов, чье содержимое должно выводиться как разделы CDATA. Принимает значения списка QName, разделенного символами-разделителями;
  • doctype-public (необязательный). Задает открытый идентификатор, который будет использован в объявлении <!DOCTYPE> в выходных данных. Устанавливается в строковое значение;
  • doctype-system (необязательный). Задает системный идентификатор, который будет использован в объявлении <!DOCTYPE> в выходных данных. Устанавливается в строковое значение;
  • encoding (необязательный). Задает кодировку символов. Устанавливается в строковое значение;
  • indent (необязательный). Определяет, будет ли выходной документ выровнен с отражением структуры вложенности. Устанавливается в yes или no;
  • media-type (необязательный). Задает тип MIME вывода. Устанавливается в строковое значение;
  • method (необязательный). Задает формат вывода. Принимает значения "xml", "html", "text" или допустимое имя QName;
  • omit-xml-declaration (необязательный) Определяет, будет ли включено в вывод объявление XML. Устанавливается в "yes" или "no";
  • standalone (необязательный). Определяет, будет ли включено в вывод отдельное объявление XML, и если да - устанавливает его значение. Устанавливается в yes или no;
  • version (необязательный). Задает версию вывода. Принимает значение допустимого NMToken.

Чаще всего используется атрибут method, поскольку именно он определяет требуемый тип выходного дерева. Официально методом выводаметод вывода по умолчанию является HTML, при условии, что выполняются все три следующих условия:

  • корневой узел результирующего дерева имеет дочерний элемент;
  • в названии элемента документа результирующего дерева присутствует часть "html" (в любой комбинации верхнего и нижнего регистров) и пустой URI пространства имен;
  • все текстовые узлы перед первым дочерним элементом корневого узла содержат только символы-разделители.

Если выполняются все три этих условия, то по умолчанию метод вывода устанавливается в HTML. В ином случае методом вывода по умолчанию является XML.

Тем не менее, не стоит полагаться на установки метода вывода по умолчанию, лучше явно присвоить этому атрибуту значение. Три распространенных значения атрибута method - "html", "xml" и "text", и мы познакомимся с ними в следующих разделах.

Метод вывода: HTML

Для метода вывода HTMLметод вывода;HTML процессор XSLT должен предпринять определенные действия. Например, для этого метода атрибут version определяет версию HTML. Значение по умолчанию - 4.0.

Этот метод не должен добавлять завершающий тег для пустых элементов. (Для HTML 4.0 пустыми элементами являются <AREA>, <BASE>, <BASEFONT>,<BR>, <COL>, <FRAME>, <HR>, <IMG>, <INPUT>, <ISINDEX>, <LINK>, <META> и <PARAM>.) Метод вывода HTML должен распознавать названия элементов HTML независимо от регистра.

В соответствии с W3C, метод вывода HTML не должен скрывать содержимое элементов <SCRIPT> или <STYLE>. Например, следующий элемент буквального результата:

<SCRIPT>
if (x < y)
</SCRIPT>

или следующий, использующий раздел CDATA:

<SCRIPT>
<![CDATA[if (x < y) ]]>
</SCRIPT>

должен быть преобразован в:

<SCRIPT>
if (x < y)
</SCRIPT>

Метод вывода HTML не должен также подавлять символы <, встречающиеся в значениях атрибутов.

При установке метода вывода в HTML процессор может учесть атрибут выравнивания. Если этот атрибут установлен в yes, процессор XSLT может добавить (или удалить) символы-разделители для выравнивания результирующего документа, поскольку это не влияет на отображение документа в браузере. Для метода вывода HTML значением по умолчанию является "yes".

Как вы могли предположить, метод вывода HTML завершает инструкции обработки при помощи >, а не ?>, а также поддерживает отдельные атрибуты, как и HTML. Например, тег

<TD NOWRAP="NOWRAP">

будет преобразован в:

<TD NOWRAP>

Для этого метода можно установить атрибут media-type, значением по умолчанию для которого является "text/html". Метод HTML не должен убирать символ &, который появляется в значении атрибута, если сразу за ним следует фигурная скобка. Атрибут encoding задает используемую кодировку. Если присутствует элемент <HEAD>, этот метод вывода должен добавить элемент <META> сразу же после тега <HEAD>, определяя кодировку символов:

<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">

При помощи атрибутов doctype-public или doctype-system можно вывести объявление типа документа непосредственно перед первым элементом, как мы увидим при преобразовании XML в XHTML.

Таковы правила вывода HTML. Ниже приведен пример преобразования из XML в HTML с небольшими отклонениями. В этом случае таблица стилей будет фактически генерировать код JavaScriptJavaScript;генерация из XML, демонстрируя создания JavaScript при помощи XSLT. В частности, мы прочитаем planets.xml и создадим новый документ HTML, отображающий три кнопки - по одной для каждой из трех планет в planets.xml. При щелчке на кнопке на странице будет выведена масса соответствующей планеты.

Все, что нам понадобится (листинг 6.1), - это два элемента <xsl:for-each>: один для прохода в цикле по трем планетам и создания для каждой кнопки HTML; и один для прохода по планетам и создания для каждой функции JavaScript. В качестве имен функций JavaScript я воспользуюсь названием планет; при вызове функция выведет массу соответствующей планеты. Заметьте, что для создания нужного кода JavaScript нужно всего лишь применить элемент <xsl:value-of> для получения названий и масс планет. Я также применю два новых элемента XSLT, <xsl:element> и <xsl:attribute-set>, которые мы рассмотрим позже в этой главе, для создания нового элемента и задания для него набора атрибутов.

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

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template match="/PLANETS">
<HTML>

<HEAD>
<TITLE>
The Mass Page
</TITLE>

<SCRIPT LANGUAGE='javascript'>

<xsl:for-each select="PLANET">
<xsl:text>
function </xsl:text><xsl:value-of select="NAME"/><xsl:text>()
{
display.innerHTML = 'The mass of </xsl:text>
<xsl:value-of select="NAME"/>
<xsl:text> equals </xsl:text>
<xsl:value-of select="MASS"/>
<xsl:text> Earth masses.'</xsl:text>
}
</xsl:for-each>
</SCRIPT>
</HEAD>

<BODY>
<CENTER>
<H1>The Mass Page</H1>
</CENTER>
<xsl:for-each select="PLANET">
<P/>
<xsl:element name="input" use-attribute-sets="attribs"/>
</xsl:for-each>
<P/>
<P/>
<DIV ID='display'></DIV>
</BODY>

</HTML>
</xsl:template>

<xsl:attribute-set name="attribs">
<xsl:attribute name="type">BUTTON</xsl:attribute>
<xsl:attribute name="value"><xsl:value-of select="NAME"/></xsl:attribute>
<xsl:attribute name="onclick"><xsl:value-of select="NAME"/>()</xsl:attribute>
</xsl:attribute-set> </xsl:stylesheet>

Результат, включая элемент <SCRIPT> для нового кода JavaScript (листинг 2).

Листинг 2. Результирующий документ с JavaScript

<HTML>
<HEAD>
<TITLE>
The Mass Page
</TITLE>

<SCRIPT LANGUAGE="javascript">
function Mercury()
{
display.innerHTML =
'The mass of Mercury equals .0553 Earth masses.'
}

function Venus()
{
display.innerHTML = 'The mass of Venus equals .815 Earth masses.
' }
function Earth()
{
display.innerHTML = 'The mass of Earth equals 1 Earth masses.'
}
</SCRIPT>
</HEAD>
<BODY>
<CENTER>
<H1>The Mass Page</H1>
</CENTER>

<P></P>
<input type="BUTTON" value="Mercury" onclick="Mercury()">
<P></P>
<input type="BUTTON" value="Venus" onclick="Venus()">
<P></P>
<input type="BUTTON" value="Earth" onclick="Earth()">
<P></P>
<P></P>
<DIV ID="display"></DIV>
</BODY>
</HTML>
Архив
Архив рассылок сайта: http://www.frnet.narod.ru/subscribe.html.
Спасибо за внимание. С уважением, Алексей Голубев.
Hosted by uCoz