Элемент может содержать ноль или более элементов <xsl:sort>
, за которыми следует тело шаблона. Работу с элементом <xsl:sort>
мы изучим позже в этой главе.
В теле шаблона функция position
возвращает позицию текущего узла в наборе узлов, a last
возвращает число узлов в наборе. Если <xsl:sort>
не используется, узлы обрабатываются в порядке документа (в порядке, в котором они перечислены в документе); если же используется элемент <xsl:sort>
, набор узлов будет сначала отсортирован в порядке, заданном этим элементом.
Предположим, нам нужно отформатировать все названия планет, заключив их в элементы HTML <Р>
, — это можно сделать следующим образом:
<xsl:template match='PLANET'>
<Р>
<xsl:value-of select='NAME'/>
</P>
</xsl: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
элемента <xsl:value-of>
сам по себе выберет только первый элемент <NAME>
. Чтобы пройти в цикле все возможные варианты, вместо него следует применить элемент <xsl:for-each>
(листинг 5.7).
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='PLANETS'>
<HTML>
<xsl:apply-templates/>
</HTML>
</xsl:template>
<xsl:template match='PLANET'>
<xsl:for-each select='NAME'>
<P>
<xsl:value-of select='.'/>
</P>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Эта таблица стилей охватывает все элементы <NAME>
, помещает их значения в элемент <Р>
и добавляет их в выходной документ следующим образом:
<HTML>
<P>Mercury</P>
<P>Closest planet to the sun</P>
<P>Venus</P>
<P>Earth</P>
</HTML>
Вот еще один пример, впервые появившийся в главе 3, «Создание и применение шаблонов», где при помощи элемента <xsl:for-each>
в цикле перебирались все атрибуты элемента:
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:template match='*'>
<xsl:copy>
<xsl:for-each select='@*'>
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Следующий пример появился в главе 2, «Создание и применение таблиц стилей». Это упрощенная таблица стилей, в которой нельзя использовать какие-либо элементы высокого уровня, то есть нельзя использовать <xsl:template>
или <xsl:apply-templates>
, однако можно пройти по узлам в цикле при помощи <xsl:for-each>
:
<HTML xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xsl:version='1.0'>
<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>
<xsl:for-each select='//PLANET'>
<TR>
<TD><xsl:value-of select='NAME'/></TD>
<TD><xsl:value-of select='MASS'/></TD>
<TD><xsl:value-of select='RADIUS'/></TD>
<TD><xsl:value-of select='DAY'/></TD>
</TR>