Чтение онлайн

ЖАНРЫ

Холзнер Стивен

Шрифт:

Предположим, нам нужно отформатировать все названия планет, заключив их в элементы HTML

<Р>
, — это можно сделать следующим образом:

<xsl:template match="PLANET">

 <Р>

<xsl:value-of select="NAME"/>

 

</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).

Листинг 5.7. Применение <xsl:for-each>

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

<xsl:value-of select="."/>

</xsl:for-each>

 </xsl:template>

</xsl:stylesheet>

Эта таблица стилей охватывает все элементы

<NAME>
, помещает их значения в элемент
<Р>
и добавляет их в выходной документ следующим образом:

<HTML>

 Mercury

 Closest planet to the sun

 Venus

 Earth

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

</xsl:for-each>

</TABLE>

 </BODY>

</HTML>

Эта упрощенная таблица стилей форматирует

planets.xml
в
planets.html
практически так же хорошо, как и шаблон, использующий
<xsl:apply-templates>
, в связи с чем появляется интересный вопрос: когда следует для прохода по узлам применять
<xsl:for-each>
, а когда
<xsl:apply-templates>
?

Как правило,

<xsl:apply-templates>
хорошо применять в тех случаях, когда организация дочерних узлов неизвестна, и вы хотите применить различные шаблоны к потомкам разных видов — независимо от количества уровней, на которые углубляется их структура. С другой стороны, если дочерние узлы обладают регулярной, хорошо определенной организацией, можно задать
<xsl:for-each>
для обработки всех этих узлов.

Элемент

<xsl:for-each>
работает во многом так же, как и
<xsl:apply-templates>
; можно даже вкладывать шаблоны при помощи
<xsl:for-each>
, как это делается при помощи последовательных элементов
<xsl:apply-templates>
. В листинге 5.8 я прохожу в цикле по каждому элементу
<PLANET>
, а затем во вложенном в него цикле по всем элементам, содержащимся в элементе
<PLANET>
, перечисляя их данные из элементов <
DATA>
следующим образом.

Поделиться с друзьями: