Выбрать главу

  <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 для того, чтобы предоставить вам безопасную «оболочку» для таких данных. Пока еще никто не реализовал поддержку внешних объектов, но это ожидается в скором времени.