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

У элемента <xsclass="underline" otherwise> нет атрибутов, и он содержит тело шаблона. Вот как это выглядит в листинге 5.4.

Листинг 5.4. Применение <xsclass="underline" choose>

<?xml version="1.0"?>

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

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

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

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

  <DOCUMENT>

   <TITLE>

    The Planets

   </TITLE>

   <PLANETS>

    The first three planets are: <xsclass="underline" apply-templates select="PLANET"/>

   </PLANETS>

  </DOCUMENT>

 </xsclass="underline" template>

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

  <xsclass="underline" if test="NAME[not(text())]">

   <xsclass="underline" message terminate="yes">

    Each planet must have a name!

   </xsclass="underline" message>

  </xsclass="underline" if>

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

  <xsclass="underline" choose>

   <xsclass="underline" when test="position()!=last()">, </xsclass="underline" when>

   <xsclass="underline" when test="position()=last()-1">and </xsclass="underline" when>

   <xsclass="underline" otherwise>.</xsclass="underline" otherwise>

  </xsclass="underline" choose>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Вот как это работает; этот код дает тот же результат, что и код, проверяющий позицию элементов <PLANET> при помощи <xsclass="underline" if>:

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

<DOCUMENT>

 <TITLE>

  The Planets

 </TITLE>

 <PLANETS>

  The first three planets are: Mercury, Venus, and Earth.

 </PLANETS>

</DOCUMENT>

Вот еще один пример преобразования XML-XML. В этом случае я преобразую planets.xml в новый XML-документ, сохраняя только название каждой планеты и добавляя описание:

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

<DOCUMENT>

 <TITLE>

  The Planets

 </TITLE>

 <PLANETS>

  <PLANET>

   <NAME>Mercury</NAME>

   <DESCRIPTION>Hottest</DESCRIPTION>

  </PLANET>

  <PLANET>

   <NAME>Venus</NAME>

   <DESCRIPTION>Hot</DESCRIPTION>

  </PLANET>

  <PLANET>

   <NAME>Earth</NAME>

   <DESCRIPTION>OK</DESCRIPTION>

  </PLANET>

 </PLANETS>

</DOCUMENT>

Это преобразование можно реализовать, выбирая значение каждого элемента <NAME>, то есть заключенный в нем текст (заметьте, что такого рода строки в XSLT учитывают регистр) (листинг 5.5).

Листинг 5.5. Второй пример <xsclass="underline" choose>

<?xml version="1.0"?>

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

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

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

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

  <DOCUMENT>

   <TITLE>

    The Planets

   </TITLE>

   <PLANETS>

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

   </PLANETS>

  </DOCUMENT>

 </xsclass="underline" template>

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

  <xsclass="underline" if test="NAME[not(text())]">

   <xsclass="underline" message terminate="yes">

    Each planet must have a name!

   </xsclass="underline" message>

  </xsclass="underline" if>

  <PLANET>

   <NAME>

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

   </NAME>

   <DESCRIPTION>

    <xsclass="underline" choose>

     <xsclass="underline" when test="NAME='Mercury'">Hottest</xsclass="underline" when>

     <xsclass="underline" when test="NAME='Venus'">Hot</xsclass="underline" when>

     <xsclass="underline" when test="NAME='Earth'">OK</xsclass="underline" when>

    </xsclass="underline" choose>

   </DESCRIPTION>

  </PLANET>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Вот и все.

Предположим теперь, что нам нужно добавить в каждый элемент <PLANET> атрибут COLOR:

<?xml version="1.0"?>

<?xml-stylesheet type="text/xml" href="planets.xsl"?>

<PLANETS>

 <PLANET COLOR="RED">

  <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><!--B перигелии-->

 </PLANET>

 <PLANET COLOR="WHITE">

  <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>

 <PLANET COLOR="BLUE">

  <NAME>Earth</NAME>

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

  <DAY UNITS="days">1</DAY>

  <RADIUS UNITS="miles">2107</RADIUS>

  <DENSITY UNITS="(Earth = 1)">1</DENSITY>

  <DISTANCE UNITS="million miles">128.4</DISTANCE><!--B перигелии-->

 </PLANET>

</PLANETS>

Отобразить названия различных планет при помощи элемента <xsclass="underline" choose>, отформатированные по-разному при помощи тегов HTML <В>, <I> и <U> в зависимости от значения атрибута COLOR, можно следующим образом (листинг 5.6).

Листинг 5.6. Форматирование при помощи <xsclass="underline" choose>

<?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>

     Planets

    </TITLE>

   </HEAD>

   <BODY>

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

   </BODY>

  </HTML>

 </xsclass="underline" template>

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

  <xsclass="underline" choose>

   <xsclass="underline" when test="@COLOR = 'RED'">

    <В>

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

    </B>

   </xsclass="underline" when>

   <xsclass="underline" when test="@COLOR = 'WHITE'">

    <I>

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

    </I>

   </xsclass="underline" when>

   <xsclass="underline" when test="@COLOR = 'BLUE'">

    <U>

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

    </U>

   </xsclass="underline" when>

   <xsclass="underline" otherwise>

   <PRE>

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

   </PRE>

  </xsclass="underline" otherwise>

 </xsclass="underline" choose>

</xsclass="underline" template>

</xsclass="underline" stylesheet>

Вот результирующий документ:

<HTML>

 <HEAD>

  <TITLE>

   Planets

  </TITLE>

 </HEAD>

 <BODY>

  <B>Mercury</B>

  <I>Venus</I>

  <U>Earth</U>

 </BODY>

</HTML>

Как вы видели, при помощи <xsclass="underline" if> можно проверять единственное условие, а при помощи <xsclass="underline" choose> — несколько; аналогичные конструкции присутствуют в большинстве языков программирования. Кроме подобных этим условных операторов, в большей части языков программирования существуют также операторы цикла, и в XSLT содержится нечто похожее — элемент <xsclass="underline" for-each>.