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

Рис. 10.2. Обработка ошибки разбора

Пока что я преобразовывал при помощи процессора MSXML только документ целиком, но здесь у вас существует значительно больше возможностей. Например, в следующем разделе я воспользуюсь XSLT в Internet Explorer для сортировки данных планет в HTML-таблицы по нажатию кнопок. Для этого я буду обращаться к отдельным узлам внутри таблицы стилей.

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

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

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

Для сортировки таблицы я, как легко догадаться, применяю таблицу стилей с элементом <xsclass="underline" sort> (листинг 10.2). По умолчанию я сортирую планеты по названию.

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

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

<xsclass="underline" stylesheet

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

 <xsclass="underline" 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>

     <xsclass="underline" apply-templates select="/PLANETS/PLANET">

      <xsclass="underline" sort select="NAME" order="ascending"/>

     </xsclass="underline" apply-templates>

    </TABLE>

   </BODY>

  </HTML>

 </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" value-of select="RADIUS"/></TD>

   <TD><xsclass="underline" value-of select="DAY"/></TD>

  </TR>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Эта таблица стилей сортирует планеты в алфавитном порядке по их названиям; но есть и другие возможности: можно позволить пользователю осуществлять сортировку и по другому критерию. Для этого выберите в данной таблице стилей атрибут select элемента <xsclass="underline" 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»), по которому нужно провести сортировку. Вот как создаются различные кнопки, показанные на рис. 10.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 элемента <xsclass="underline" sort> на имя нового узла, по которому нужно сортировать. Вот как теперь выглядит атрибут select.

<xsclass="underline" apply-templates select="/PLANETS/PLANET">

 <xsclass="underline" sort select="NAME" order="ascending"/>

</xsclass="underline" apply-templates>

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