KnigaRead.com/

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

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

Элемент <xsl:attribute-set>: создание наборов атрибутов

Иногда при создании нового элемента возникает потребность добавить в него сразу несколько атрибутов. Существует простой способ сделать это при помощи элемента <xsl:attribute-set>. У этого элемента два атрибута:

• name (обязательный). Имя набора атрибутов. Устанавливается в QName;

• use-attribute-sets (необязательный). Имена других наборов атрибутов, которые вы хотите включить в этот набор. Устанавливается в список QName, разделенных символами-разделителями.

Элемент <xsl:attribute-set> содержит элементы <xsl:attribute>, по одному для каждого нового создаваемого атрибута. При использовании <xsl:attribute-set> для создания нового набора атрибутов элемента нужно задать имя набору. Затем при создании нового элемента для использования набора атрибутов это имя можно присваивать атрибуту use-attribute-sets элементов <xsl:copy>, <xsl:element>, <xsl:for-each> и даже самого элемента <xsl:attribute-set>.

Ранее в текущей главе мы уже рассматривали один пример применения наборов атрибутов в JavaScript при создании шаблона. В том примере я при помощи набора атрибутов задавал все атрибуты HTML-кнопок планет и затем создавал их, используя этот набор атрибутов в элементе <xsl:element>:

  <BODY>

   <CENTER>

    <H1>The Mass Page</H1>

   </CENTER>

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

    <P/>

    <xsl:element name="input" use-attribute-sets="attribs"/>

   </xsl:for-each>

   <P/>

   <P/>

   <DIV ID='display'></DIV>

  </BODY>

 </HTML>

</xsl:template>


<xsl:attribute-set name="attribs">

 <xsl:attribute name="type">BUTTON</xsl:attribute>

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

 <xsl:attribute name="onclick"><xsl:value-of select="NAME"/>()</xslt:attribute>

</xsl:attribute-set>

В результирующем документе такой набор атрибутов был добавлен каждой кнопке HTML:

<Р></Р>

<input type="BUTTON"value="Mercury" onclick="Mercury()">

<P></P>

<input type="BUTTON" value="Venus" onclick="Venus()">

<P></P>

<input type='BUTTON" value="Earth" onclick="Earth()">

В листинге 6.11 я воспользуюсь набором атрибутов для нумерации планет в planets.xml. Каждому элементу <PLANET> я добавил два атрибута: number и total. В атрибуте number будет храниться номер планеты начиная с 1, а атрибут total будет содержать общее число планет в planets.xml, которое можно найти при помощи функции count (мы рассмотрим ее в главе 8).

Листинг 6.11. Применение <xsl:attribute-set>

<xsl:stylesheet

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

 <xsl:output method="xml" indent="yes"/>

 <xsl:template match="*">

  <xsl:copy>

   <xsl:apply-templates/>

  </xsl:copy>

 </xsl:template>


 <xsl:template match="PLANET">

  <xsl:copy use-attribute-sets="numbering">

   <xsl:apply-templates/>

  </xsl:copy>

 </xsl:template>


 <xsl:attribute-set name="numbering">

  <xsl:attribute name="number"><xsl:number/></xsl:attribute>

  <xsl:attribute name="total"><xsl:value-of select="count(//PLANET)"/>

 </xsl:attribute>

</xsl:attribute-set>


</xsl:stylesheet>

Обратите внимание на то, что в результирующем документе каждый элемент <PLANET> имеет атрибуты number и total: 

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

<PLANET number="1" total="3">

<NAME>Mercury</NAME> <MASS>.0553</MASS> <DAY>58.65</DAY> <RADIUS>1516</RADIUS> <DENSITY>.983</DENSITY> <DISTANCE>43.4</DISTANCE> </PLANET>

<PLANET number="2" total="3">

<NAME>Venus</NAME> <MASS>.815</MASS> <DAY>116.75</DAY> <RADIUS>3716</ RADIUS> <DENSITY>.943</DENSITY> <DISTANCE>66.8</DISTANCE> </PLANET>

<PLANET number="3" total="3"> <NAME>Earth</NAME> <MASS>1</MASS> <DAY>1</DAY> <RADIUS>2107</RADIUS> <DENSITY>1</DENSITY> <DISTANCE>128.4</DISTANCE> </PLANET>

</PLANETS>

Пропуск объявления XML и создание фрагментов XML

При знакомстве с XSLT многих смущает объявление XML, которое всегда появляется наверху их результирующих документов, особенно если они не отдают себе отчёт в том, что методом вывода по умолчанию является XML. Разумеется, существует способ избавиться от объявления XML, что может быть полезно при создании хорошо сформированных фрагментов XML, не обязательно являющихся законченными документами. Достаточно только установить атрибут omit-xml-declaration элемента <xsl:output> в «yes»: <xsl:output method="xml" omit-xml-declaration="yes"/>.

В следующем примере я только уберу из документа объявление XML, копируя при этом все остальное. Заметьте, что объявление XML не есть узел, поэтому ничего страшного, если оно будет удовлетворять копирующему шаблону:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output method="xml" omit-xml-declaration="yes"/>

 <xsl:template match="@*|node()">

  <xsl:copy>

   <xsl:apply-templates select="@*|node()"/>

  </xsl:copy>

 </xsl:template>

</xsl:stylesheet>

Эта таблица стилей преобразует planets.xml:

<?xml version="1.0"?>

<PLANETS>

 <PLANET>

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

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

 .

 .

 .

в новую версию без объявления XML:

<PLANETS>

 <PLANET>

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

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

 .

 .

 .

Полезно знать об этом при создании фрагментов XML или выполнении другой работы. Тем не менее, заметим, что во всех законченных документах XML — даже написанных самостоятельно при помощи разнообразных приложений XML, таких как WML — в начале обязательно должно быть объявление XML.

Создание уникальных идентификаторов при помощи generate-id

При существенном изменении структуры документов важно рассмотреть еще одну тему: как в результирующих документах создавать идентификаторы элементов для обращения к ним при необходимости. Представьте, например, что вам нужно при помощи таблицы стилей добавить в документ оглавление, записи в котором будут представлять собой гиперссылки, так чтобы пользователь по щелчку на них сразу переходил к нужному разделу. В этом случае потребуется какой-то способ идентификации элементов в результирующем документе, в чем поможет функция generate-id.

В следующем примере я добавляю составленное из гиперссылок оглавление в planets.html. Для создания оглавления я прохожу в цикле по всем планетам при помощи элемента <xsl:for-each>. На каждом шаге цикла я создаю гиперссылку и при помощи шаблона значений атрибута создаю атрибут HREF, который устанавливается в уникальный идентификатор для рассматриваемой планеты. Заметьте, что, несмотря на свое имя, функция generate-id создает только строковый идентификатор элемента, она не создает атрибуты ID:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="/PLANETS">

  <HTML>

   <HEAD>

    <TITLE>

     The Planets Table

    </TITLE>

   </HEAD>

   <BODY>

    <H1>

     The Planets Table

    </H1>

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

     <H2><A HREF="#{generate-id()}">

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