<NAME>Mercury</NAME> <MASS UNITS="(Earth = 1)">.0553</MASS>
<DAY UNITS="days">58.65</DAY>
<RADIUS UNITS="miles">1516</RADIUS>
<DENSITY UNITS="(Earth = 1)">.983</DENSITY>
<DISTANCE UNITS="million miles">43.4</DISTANCE><!--В перигелии-->
</PLANET>
<PLANET>
<NAME>Venus</NAME>
<MASS UNITS="(Earth = 1)">.815</MASS>
<DAY UNITS="days">116.75</DAY>
<RADIUS UNITS="miles">3716</RADIUS>
<DENSITY UNITS="(Earth = 1)">.943</DENSITY>
<DISTANCE UNITS="million miles">66.8</DISTANCE><!--B перигелии-->
</PLANET>
.
.
.
Для преобразования таблицы стилей kilometers.xsl для работы в IE 5.5 или младше я воспользовался пространством имен XSL, которое использует IE, и добавил элемент <xsclass="underline" script>, показав, что я собираюсь писать сценарии на JavaScript. Заметьте, однако, что элемент <xsclass="underline" script> в Internet Explorer не поддерживает атрибут префикса реализации, поэтому я не могу связать функции, определенные в пространстве имен:
<xsclass="underline" stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsclass="underline" script language="javascript">
.
.
.
</xsclass="underline" script>
.
.
.
В соответствии с требованиями Internet Explorer, код должен быть заключен в раздел CDATA. Здесь я определил функцию milesToKilometers, которая принимает узел, читает текст узла в свойстве text и преобразует текст в число миль при помощи функции JavaScript parseInt. Далее я умножаю число миль на 1,6, чтобы получить километры, и возвращаю результат:
<xsclass="underline" stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsclass="underline" script language="javascript">
<![CDATA[
function milesToKilometers(e) {
miles = parseInt(e.text);
return miles * 1.6;
}
]]>
</xsclass="underline" script>
.
.
.
Поскольку пока в Internet Explorer нельзя связать пространство имен с функцией расширения, для их вызова используется специальный элемент Microsoft <xsclass="underline" eval>. Ниже показано, как это выглядит в таблице стилей kilometers.xsl, где я передаю в функцию milesToKilometers текущий узел <RADIUS> для преобразования миль в километры. Поскольку IE 5.5 и младше не поддерживают правила по умолчанию (хотя версия 6.0, вышедшая одновременно с подписанием этой книги в печать, поддерживает их, и вам не нужно ничего менять), для этих браузеров я предоставил правило для корневого узла (листинг 5.16).
Листинг 5.16. kilometers.xsl<xsclass="underline" stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsclass="underline" script language="javascript">
<![CDATA[
function milesToKilometers(e) {
miles = parseInt(e.text);
return miles * 1.6;
}
]]>
</xsclass="underline" script>
<xsclass="underline" template match="/">
<HTML>
<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>
<xsclass="underline" apply-templates/>
</TABLE>
</BODY>
</HTML>
</xsclass="underline" template>
<xsclass="underline" template match="PLANETS">
<xsclass="underline" apply-templates/>
</xsclass="underline" template>
<xsclass="underline" template match="PLANET">
<TR>
<TD><xsclass="underline" value-of select="NAME"/></TD>
<TD><xsclass="underline" value-of select="MASS"/></TD>
<TD><xsclass="underline" apply-templates match="RADIUS"/></TD>
<TD><xsclass="underline" value-of select="DAY"/></TD>
</TR>
</xsclass="underline" template>
<xsclass="underline" template match="RADIUS">
<xsclass="underline" eval>milesToKilometers(this)</xsclass="underline" eval>
</xsclass="underline" template>
</xsclass="underline" stylesheet>
Вот и все, результат этого преобразования приведен на рис. 5.4.
Рис. 5.4. Применение функции расширения в Internet Explorer
Со временем производители будут поставлять все больше и больше функций расширения. Как можно определить, доступна ли заданная функция расширения? Для этого служит функция function-available.
Применение функции function-available
Функция XSLT 1.0 function-available служит для проверки доступности функции. В следующем примере я хочу воспользоваться функцией расширения starpowder:calculate для математических вычислений, а если она недоступна, я отправляю в результирующий документ текст «Sorry, can't do math today.» (Извините, сегодня математические вычисления не работают.), хотя можно, конечно, прекратить обработку и вывести сообщение об ошибке при помощи элемента <xsclass="underline" message>:
<xsclass="underline" choose xmlns:starpowder="http://www.starpowder.com">
<xsclass="underline" when test="function-available('starpowder:calculate')">
<xsclass="underline" value-of select="starpowder:calculate('2+2')"/>
</xsclass="underline" when>
<xsclass="underline" otherwise>
<xsclass="underline" text>Sorry, can't do math today.</xsclass="underline" text>
</xsclass="underline" otherwise>
</xsclass="underline" choose>
Внешние объекты
В рабочем проекте XSLT 1.1 для поддержки функций расширения появился новый тип данных — внешний объект (external object). Переменной XSLT, о которой пойдет речь в главе 9, может быть присвоен внешний объект — так же, как и один из четырех типов данных XPath, поддерживаемых в XSLT (строка, число, логическое значение, набор узлов). Внешний объект представляет объект, который создается внешним языком программирования, возвращается функцией расширения и не может быть преобразован в один из четырех типов данных XPath. Тип данных «external object» был добавлен в XSLT для того, чтобы предоставить вам безопасную «оболочку» для таких данных. Пока еще никто не реализовал поддержку внешних объектов, но это ожидается в скором времени.