KnigaRead.com/

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Стивен Холзнер, "XSLT" бесплатно, без регистрации.
Перейти на страницу:

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

   </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> следующим образом.

Листинг 5.8. Второй пример <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="PLANETS">

  <PLANETS>

   <xsl:for-each select="PLANET">

    <PLANET>

     <xsl:for-each select="*">

      <DATA>

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

      </DATA>

     </xsl:for-each>

    </PLANET>

   </xsl:for-each>

  </PLANETS>

 </xsl:template>

</xsl:stylesheet>

И вот результат:

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

<PLANETS>

 <PLANET>

  <DATA>Mercury</DATA>

  <DATA>.0553</DATA>

  <DATA>58.65</DATA>

  <DATA>1516</DATA>

  <DATA>.983</DATA>

  <DATA>43.4</DATA>

 </PLANET>

 <PLANET>

  <DATA>Venus</DATA>

  <DATA>.815</DATA>

  <DATA>116.75</DATA>

  <DATA>3716</DATA>

  <DATA>.943</DATA>

  <DATA>66.8</DATA>

 </PLANET>

 <PLANET>

  <DATA>Earth</DATA>

  <DATA>1</DATA>

  <DATA>1</DATA>

  <DATA>2107</DATA>

  <DATA>1</DATA>

  <DATA>128.4</DATA>

 </PLANET>

</PLANETS>

Сортирующие элементы

При помощи элемента <xsl:sort> можно сортировать узлы. Этот элемент устанавливает порядок обработки узлов для <xsl:apply-templates> и <xsl:for-each>. В следующем списке перечислены атрибуты <xsl:sort>:

• select (необязательный). Принимает значение выражения XPath, возвращающего набор узлов для сортировки. По умолчанию — «string(.)»;

• order (необязательный). Задает порядок сортировки, устанавливается в «ascending» (по возрастанию) или «descending» (по убыванию);

• case-order (необязательный). Определяет, будут ли буквы в верхнем регистре располагаться перед буквами в нижнем регистре. Устанавливается в «upper-first» (сначала верхний) или «lower-first» (сначала нижний);

• lang (необязательный). Задает язык, чьи соглашения о сортировке будут применяться. Устанавливается в код языка, допустимый в атрибуте xml:lang;

• data-type (необязательный). Определяет, будет ли сортировка вестись в алфавитном или числовом порядке. Устанавливается в «text» (текст), «number» (число) или в QName.

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

В листинге 5.9 я только отсортирую элементы <PLANET> в planets.xml в возрастающем алфавитном порядке по их именам, используя <xsl:for-each> в упрощенной таблице стилей.

Листинг 5.9. Сортировка данных

<HTML xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="1.0">

 <HEAD>

  <TITLE>

   The Sorted Planets Table

  </TITLE>

 </HEAD>

 <BODY>

  <H1>

   The Sorted 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">

    <xsl:sort/>

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

А вот результат. Обратите внимание на то, что планеты действительно отсортированы как Earth, Mercury и затем Venus:

<HTML>

 <HEAD>

  <TITLE>

   The Sorted Planets Table

  </TITLE>

 </HEAD>

 <BODY>

  <H1>

   The Sorted Planets Table

  </H1>

  <TABLE BORDER="2">

   <TR>

    <TD>Name</TD>

    <TD>Mass</TD>

    <TD>Radius</TD>

    <TD>Day</TD>

   </TR>

   <TR>

    <TD>Earth</TD>

    <TD>1</TD>

    <TD>2107</TD>

    <TD>1</TD>

   </TR>

   <TR>

    <TD>Mercury</TD>

    <TD>.0553</TD>

    <TD>1516</TD>

    <TD>58.65</TD>

   </TR>

   <TR>

    <TD>Venus</TD>

    <TD>.815</TD>

    <TD>3716</TD>

    <TD>116.75</TD>

   </TR>

  </TABLE>

 </BODY>

</HTML>

Вид документа показан на рис. 5.1.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*