</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>.
Элемент <xsclass="underline" for-each>
Элемент <xsclass="underline" for-each> позволяет применять тело шаблона в цикле снова и снова для всех элементов набора узлов. С технической точки зрения, он работает с набором узлов, который возвращает выражение XPath и выполняет одно и то же действие с каждым узлом в наборе. При каждом шаге цикла тело шаблона применяется к следующему узлу из набора узлов, что дает возможность легко обрабатывать несколько узлов.
<XSL:FOR-EACH> ПРОТИВ <XSL:APPLY-TEMPLATES>
Вы могли заметить, что это описание практически такое же, как и у элемента <xsclass="underline" apply-templates>, и я сравню элементы <xsclass="underline" for-each> и <xsclass="underline" apply-templates> через несколько страниц.
У элемента <xsclass="underline" for-each> один атрибут:
• select (обязательный). Принимает значение выражения XPath, возвращающее набор узлов, который нужно обработать в цикле.
Элемент может содержать ноль или более элементов <xsclass="underline" sort>, за которыми следует тело шаблона. Работу с элементом <xsclass="underline" sort> мы изучим позже в этой главе.
В теле шаблона функция position возвращает позицию текущего узла в наборе узлов, a last возвращает число узлов в наборе. Если <xsclass="underline" sort> не используется, узлы обрабатываются в порядке документа (в порядке, в котором они перечислены в документе); если же используется элемент <xsclass="underline" sort>, набор узлов будет сначала отсортирован в порядке, заданном этим элементом.
Предположим, нам нужно отформатировать все названия планет, заключив их в элементы HTML <Р>, — это можно сделать следующим образом:
<xsclass="underline" template match="PLANET">
<Р>
<xsclass="underline" value-of select="NAME"/>
</P>
</xsclass="underline" template>
Но что делать, если у некоторых планет по два названия, как, например:
<PLANET>
<NAME>Mercury</NAME>
<NAME>Closest planet to the sun</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>
Это проблема, поскольку атрибут select элемента <xsclass="underline" value-of> сам по себе выберет только первый элемент <NAME>. Чтобы пройти в цикле все возможные варианты, вместо него следует применить элемент <xsclass="underline" for-each> (листинг 5.7).
Листинг 5.7. Применение <xsclass="underline" for-each><?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>
<xsclass="underline" apply-templates/>
</HTML>
</xsclass="underline" template>
<xsclass="underline" template match="PLANET">
<xsclass="underline" for-each select="NAME">
<P>
<xsclass="underline" value-of select="."/>
</P>
</xsclass="underline" for-each>
</xsclass="underline" template>
</xsclass="underline" stylesheet>
Эта таблица стилей охватывает все элементы <NAME>, помещает их значения в элемент <Р> и добавляет их в выходной документ следующим образом:
<HTML>
<P>Mercury</P>
<P>Closest planet to the sun</P>
<P>Venus</P>
<P>Earth</P>
</HTML>
Вот еще один пример, впервые появившийся в главе 3, «Создание и применение шаблонов», где при помощи элемента <xsclass="underline" for-each> в цикле перебирались все атрибуты элемента:
<?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="*">
<xsclass="underline" copy>
<xsclass="underline" for-each select="@*">
<xsclass="underline" copy/>
</xsclass="underline" for-each>
<xsclass="underline" apply-templates/>
</xsclass="underline" copy>
</xsclass="underline" template>
</xsclass="underline" stylesheet>
Следующий пример появился в главе 2, «Создание и применение таблиц стилей». Это упрощенная таблица стилей, в которой нельзя использовать какие-либо элементы высокого уровня, то есть нельзя использовать <xsclass="underline" template> или <xsclass="underline" apply-templates>, однако можно пройти по узлам в цикле при помощи <xsclass="underline" for-each>:
<HTML xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsclass="underline" version="1.0">
<HEAD>
<TITLE>
The Planets Table
</TITLE>