=> Главная База Знаний Xslt Internet explorer и динамические стили


Internet explorer и динамические стили

Internet Explorer и динамические стили

Для того чтобы продемонстрировать все возможности управления преобразованиями XSLT при использовании процессора MSXML, в этом примере я разрешу пользователю динамически сортировать таблицу Planets. Общая идея показана на 3. Пользователю достаточно щелкнуть на кнопку, чтобы отсортировать таблицу по названию, массе, радиусу или дню.

Internet Explorer и динамические стили

3. Поддержка динамических преобразований XSLT


Для сортировки таблицы я, как легко догадаться, применяю таблицу стилей с элементом

<xsl:sort>
(листинг 10.2). По умолчанию я сортирую планеты по названию.

Листинг 10.2. Применение динамических XSLT-преобразований

<?xml version="1.0" encoding="iso-8859-1"?>

<xsl:stylesheet

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">

 <xsl:template match="/">

  <HTML>

   <HEAD>

    <TITLE>

     The Sorted Planets Table

    </TITLE>

   </HEAD>

   <BODY>

    <H1>

     The Sorted Planets Table

    </H1>

    <TABLE BORDER="2">

     <TR>

      <TD>Name</TD>

      <TD>Mass</TD>

      <TD>Radius</TD>

      <TD>Day</TD>

     </TR>

     <xsl:apply-templates select="/PLANETS/PLANET">

      <xsl:sort select="NAME" order="ascending"/>

     </xsl:apply-templates>

    </TABLE>

   </BODY>

  </HTML>

 </xsl:template>


 <xsl:template match="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:template>

</xsl:stylesheet>

Эта таблица стилей сортирует планеты в алфавитном порядке по их названиям; но есть и другие возможности: можно позволить пользователю осуществлять сортировку и по другому критерию. Для этого выберите в данной таблице стилей атрибут

select
элемента
<xsl:sort>
и при помощи JavaScript измените его динамически с «NAME» на «MASS», «RADIUS» или на другой критерий по желанию пользователя, и затем снова выполните преобразование XSLT. При повторном осуществлении преобразования появится новая таблица с новым порядком сортировки.

В качестве первого шага в создании нужной нам HTML-страницы я загружу

planets.xml
и требуемую таблицу стилей и выполню сортировку по умолчанию, то есть по названию планет:

<HTML>

 <HEAD>

  <TITLE>

   Applying Dynamic Styles

  </TITLE>

  <SCRIPT LANGUAGE="JavaScript">

   var XMLDocument;

   var XSLDocument;

   var HTMLtarget;

   function initialize() {

    XMLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');

    XSLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');

    HTMLtarget = document.all['targetDIV'];

    XMLDocument.validateOnParse = true;

    XMLDocument.load('planets.xml');

    if (XMLDocument.parseError.errorCode != 0) {

     HTMLtarget.innerHTML = "Error!";

     return false;

    }

    XSLDocument.validateOnParse = true;

    XSLDocument.load('planets.xsl');

    if (XSLDocument.parseError.errorCode != 0) {

     HTMLtarget.innerHTML = "Error!";

     return false;

    }

    HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);

   }

   .

   .

   .

Эту часть вы уже видели раньше. Но пользователь теперь может отсортировать таблицу щелчком мыши по массе, радиусу и т.д. Для новой сортировки таблицы я написал функцию

sort
— ей при щелчке на кнопке передается имя узла (например, «MASS»), по которому нужно провести сортировку. Вот как создаются различные кнопки, показанные на 3:

<INPUT ТУРЕ="BUTTON" ONCLICK="sort('NAME')" VALUE="Sort by name"></INPUT>

<INPUT TYPE="BUTTON" ONCLICK="sort('MASS')" VALUE="Sort by mass"></INPUT>

<INPUT TYPE="BUTTON" ONCLICK="sort('RADIUS')" VALUE="Sort by radius"></INPUT>

<INPUT TYPE="BUTTON" ONCLICK="sort('DAY')" VALUE="Sort by day"></INPUT>

Затем в функции

sort
я хочу выполнить новую сортировку по имени переданного узла. Для этого я изменяю атрибут
select
элемента
<xsl:sort>
на имя нового узла, по которому нужно сортировать. Вот как теперь выглядит атрибут
select
.

<xsl:apply-templates select="/PLANETS/PLANET">

 <xsl:sort select="NAME" order="ascending"/>

</xsl:apply-templates>

Я могу обратиться к этому узлу из таблицы стилей, теперь хранимой в объекте

XSLDocument
, передав в метод
selectSingleNode
упомянутого объекта выражение XPath. Метод
selectSingleNode
возвращает объект
node
, и можно изменить текстовое значение узла при помощи свойства
nodeValue
объекта
node
. В таком случае я только устанавливаю атрибут select в имя нового узла, по которому будет вестись сортировка:

<HTML>

 <HEAD>

  <TITLE>

   Applying Dynamic Styles

  </TITLE>

  <SCRIPT LANGUAGE="JavaScript">

   function initialize() {

   .

   .

   .

  }


  function sort(sortNode) {

   (XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue

    = sortNode;

   .

   .

   .

  }

 </SCRIPT>

 .

 .


Теперь все, что осталось сделать, — снова выполнить преобразование и вывести результаты:

<HTML>

 <HEAD>

  <TITLE>

   Applying Dynamic Styles

  </TITLE>

  <SCRIPT LANGUAGE="JavaScript">

   function initialize() {

    .

    .

    .

   }


   function sort(sortNode) {

    (XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue

     = sortNode;

     HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);

    }

   </SCRIPT>

 </HEAD>

 .

 .

 .

Операция завершена. Результаты показаны на 3. При щелчке на кнопке таблица сортируется заново по выбранному значению узла (имейте в виду, что сортировка ведется по алфавиту; сортировка по числовым значениям обсуждается в главе 5, где описывается элемент

<xsl:sort>
) и отображается еще раз с новым порядком сортировки. Вот вся HTML-страница (листинг 10.3).

Листинг 10.3. Применение динамических XSLT-преобразований

<HTML>

 <HEAD>

  <TITLE>

   Applying Dynamic Styles

  </TITLE>

  <SCRIPT LANGUAGE="JavaScript">

   var XMLDocument;

   var XSLDocument;

   var HTMLtarget;

   function initialize() {

    XMLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');

    XSLDocument = new ActiveXObject('MSXML2.DOMDocument.3.0');

    HTMLtarget = document.all['targetDIV'];

    XMLDocument.validateOnParse = true;

    XMLDocument.load('planets.xml');

    if (XMLDocument.parseError.errorCode != 0) {

     HTMLtarget.innerHTML = "Error!";

     return false;

    }

    XSLDocument.validateOnParse = true;

    XSLDocument load('planets.xsl');

    if (XSLDocument.parseError.errorCode != 0) {

     HTMLtarget.innerHTML = "Error!";

     return false;

    }

    HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);

   }


   function sort(sortNode) {

    (XSLDocument.selectSingleNode("//xsl:sort/@select")).nodeValue

     = sortNode;

    HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);

   }

  </SCRIPT>

 </HEAD>

 <BODY ONLOAD="initialize()">

  <CENTER>

   <DIV ID="targetDIV"></DIV>

   <BR>

   <BR>

   <INPUT TYPE="BUTTON" ONCLICK="sort('NAME')" VALUE="Sort by name"></INPUT>

   <INPUT TYPE="BUTTON" ONCLICK="sort('MASS')" VALUE="Sort by mass"></INPUT>

   <INPUT TYPE="BUTTON" ONCLICK="sort('RADIUS')" VALUE="Sort by radius"></INPUT>

   <INPUT TYPE="BUTTON" ONCLICK="sort('DAY')" VALUE="Sort by day"></INPUT>

  </CENTER>

 </BODY>

</HTML>

На самом деле загрузить документы XML и XSL в Internet Explorer можно несколькими способами. Для создания объектов

XMLDocument
и
XSLDocument
я использовал класс ActiveXObject, но эти объекты можно создавать и непосредственно обращаясь к содержащим документы XML объектам ActiveX по идентификатору класса, хранимому в реестре Windows. В следующем примере я таким образом загружу
planets.xml
и
planets.xsl
в
XMLDocument
и
XSLDocument
:

XMLDocument = document.all['XMLdoc'];

XSLDocument = document.all['XSLdoc'];

XMLDocument.load('planets.xml');

XSLDocument.load(' planets.xsl');

.

.

.

<OBJECT ID="XMLdoc" WIDTH="0" HEIGHT="0"

 CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">

</OBJECT>

<OBJECT ID="XSLdoc" WIDTH="0" HEIGHT="0"

 CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">

</OBJECT>

Эта техника не так надежна, как использование класса

ActiveXObject
, поскольку идентификаторы классов могут различаться в разных версиях Internet Explorer. (Приведены идентификаторы классов для Internet Explorer 5.5). Но есть еще один способ загрузить документы XML и XSL в Internet Explorer — при помощи участков (island) XML.