У элемента <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>.