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

Одна из проблем при работе с XSLT в Internet Explorer 5.5 или младше состоит в том, что браузер не предоставляет никаких правил по умолчанию. Необходимо задавать все правила самостоятельно, если только не установлен процессор MSXML3 в режиме замены (подробнее см. главу 2) или вы не обновили браузер до Internet Explorer 6.0.

Кроме того, узлы-разделители исходного документа сохраняются, поэтому можно считать, что следующее правило также является правилом по умолчанию: <xsclass="underline" output preserve-space="*"/>.

Удаление содержимого

Если ваше правило для узла не работает, то есть оно пусто, содержимое выбранного узла не будет скопировано в выходной документ. Таким способом при создании выходного документа можно выборочно удалять содержимое из исходного документа.

Предположим, нам нужно удалить из planets.xml все данные о планетах, за исключением их названий и данных о массе. Следующая таблица стилей выполняет данную задачу.

Листинг 3.7. Удаление содержимого

<?xml versiоn="1.0"?>

<xsclass="underline" stylesheet version="1.0"

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

 <xsclass="underline" strip-space elements="*"/>

 <xsclass="underline" output method="xml" indent="yes"/>

 <xsclass="underline" template match="/">

  <xsclass="underline" apply-templates/>

 </xsclass="underline" template>

 <xsclass="underline" template match="PLANETS">

  <xsclass="underline" apply-templates/>

 </xsclass="underline" template>

 <xsclass="underline" template match="PLANET">

  <xsclass="underline" copy>

   <xsclass="underline" apply-templates/>

  </xsclass="underline" copy>

 </xsclass="underline" template>

 <xsclass="underline" template match="NAME">

  <xsclass="underline" copy>

   <xsclass="underline" apply-templates/>

  </xsclass="underline" copy>

 </xsclass="underline" template>

 <xsclass="underline" template match="MASS">

  <xsclass="underline" copy>

   <xsclass="underline" value-of select="."/>

   <xsclass="underline" value-of select="@UNITS"/>

  </xsclass="underline" copy>

 </xsclass="underline" template>

 <xsclass="underline" template match="RADIUS">

 </xsclass="underline" template>

 <xsclass="underline" template match="DAY">

 </xsclass="underline" template>

 <xsclass="underline" template match="DENSITY">

 </xsclass="underline" template>

 <xsclass="underline" template match="DISTANCE">

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

А вот результирующий документ (отметьте, что я сохранил только элементы <NAME> и <MASS>):

<?xml version="1.0" encoding="UTF-8"?>

<PLANET>

 <NAME>Mercury</NAME>

 <MASS>.0553(Earth = 1)</MASS>

</PLANET>

<PLANET>

 <NAME>Venus</NAME>

 <MASS>.815(Earth = 1)</MASS>

</PLANET>

<PLANET>

 <NAME>Earth</NAME>

 <MASS>1(Earth = 1)</MASS>

</PLANET>

Таким способом можно фильтровать XML-документы, создавая новые XML-документы только с требуемыми данными.

Разрешение конфликтов шаблонов

Еще одним важным аспектом работы с шаблонами является разрешение конфликтов. Если двум шаблонам удовлетворяют один и тот же узел или набор узлов, для определения применяемого шаблона XSLT учитывает их приоритет.

У каждого шаблона есть приоритет по умолчанию, основанный на значении атрибута select. Как правило, чем более сужающим является правило выбора или выражение (например, "PLANET" и "*"), тем выше его приоритет. В главе 4 мы рассмотрим, как процессор определяет приоритеты и как он работает с шаблонами, имеющими одинаковый приоритет.

Приоритет шаблона можно установить при помощи атрибута priority. В приведенном ниже листинге 3.8 правило, созданное элементом <xsclass="underline" template priority="1"/>, имеет меньший приоритет, чем правило, созданное элементом <xsclass="underline" template priority="2"/>.

Листинг 3.8. Установка приоритета шаблона

<?xml version="1.0"?>

<xsclass="underline" stylesheet version="1.0"

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

 <xsclass="underline" template match="/PLANETS">

  <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="PLANET">

  <TR>

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

   <TD><xsclass="underline" apply-templates select="MASS"/></TD>

   <TD><xsclass="underline" apply-templates select="RADIUS"/></TD>

   <TD><xsclass="underline" apply-templates select="DAY"/></TD>

  </TR>

 </xsclass="underline" template>

 <xsclass="underline" template match="MASS" priority="2">

  <xsclass="underline" value-of select="."/>

  (<I>Very</I> heavy)

 </xsclass="underline" template>

 <xsclass="underline" template match="MASS" priority="1">

  <xsclass="underline" value-of select="."/>

 </xsclass="underline" template>

 <xsclass="underline" template match="RADIUS">

  <xsclass="underline" value-of select="."/>

  <xsclass="underline" text> </xsclass="underline" text>

  <xsclass="underline" value-of select="@UNITS"/>

 </xsclass="underline" template>

 <xsclass="underline" template match="DAY">

  <xsclass="underline" value-of select="."/>

  <xsclass="underline" text> </xsclass="underline" text>

  <xsclass="underline" value-of select="@UNITS"/>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Процессор XSLT выбирает шаблон с наивысшим приоритетом, который добавляет текст "(<I>Very</I> heavy)" после каждого значения массы. В следующем примере использован шаблон с наивысшим приоритетом: