KnigaRead.com/

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

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

Элемент <xsl:element>: создание новых элементов на этапе выполнения

Новые элементы можно создавать при помощи элемента <xsl:element>, который очень удобен для задания имени нового элемента на этапе выполнения.

У этого элемента три атрибута:

• name (обязательный). Имя создаваемого элемента. Принимает значение шаблона значений атрибута, возвращающего QName;

• namespace (необязательный). URI пространства имен нового элемента. Принимает значение шаблона значений атрибута, возвращающего URI;

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

Элемент <xsl:element> содержит тело шаблона.

Пусть, например, мне нужно хранить названия планет в атрибутах NAME, а не в элементе <NAME> в planets.xml:

<?xml version="1.0"?>

<?xml-stylesheet type="text/xml" href="planets.xsl"?>

<PLANETS>

 <PLANET NAME="Mercury">

  <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><!--В перигелии-->

 </PLANET>

 .

 .

 .

Предположим теперь, что при помощи значений этого атрибута мне нужно создать имена новых элементов в результирующем документе — такие, как <Mercury>, <Venus> и <Earth>: 

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

<?xml-stylesheet type="text/xml" href="planets.xsl"?>

<PLANETS>

 <Mercury>

  <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><!--В перигелии-->

 </Mercury>

 .

 .

 .

В этом случае я не знаю имени выходного элемента до времени выполнения, потому и не могу просто применить элемент буквального результата. Я мог бы скомпоновать новый элемент, трактуя его как текст (что и показано в примере ниже, где я вывожу символы, подобные «<», при помощи атрибута disable-output-escaping элемента <xsl:text>): 

<?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="@*|node()">

  <xsl:copy>

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

  </xsl:copy>

 </xsl:template>


 <xsl:template match="PLANET">

  <xsl:text disable-output-escaping="yes">&lt;</xsl:text>

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

  <xsl:text disable-output-escaping="yes">&gt;</xsl:text>

  <xsl:apply-templates/>

  <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>

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

  <xsl:text disable-output-escaping="yes">&gt;</xsl:text>

 </xsl:template>

</xsl:stylesheet> 

Но это грубый способ, при котором разметка рассматривается как простой текст. С другой стороны, зная название планеты, я могу создать новый элемент при помощи <xsl:element> (листинг 6.6), получив название новой планеты из атрибута NAME следующим образом.

Листинг 6.6. Применение <xsl:element>

<?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="@*|node()">

  <xsl:copy>

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

  </xsl:copy>

 </xsl:template>


 <xsl:template match="PLANET">

  <xsl:element name="{@NAME}">

   <xsl:apply-templates/>

  </xsl:element>

 </xsl:template>

</xsl:stylesheet>

Этот способ намного чище и проще. Ниже показан результат, в котором на этапе выполнения созданы новые элементы с именами различных планет:

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

<?xml-stylesheet type="text/xml" href="planets.xsl"?>

<PLANETS>

 <Mercury>

  <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 перигелии-->

 </Mercury>

 <Venus>

  <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 перигелии-->

 </Venus>

 <Earth>

  <MASS UNITS="(Earth = 1)">1</MASS>

  <DAY UNITS="days">1</DAY>

  <RADIUS UNITS="miles">2107</RADIUS>

  <DENSITY UNITS="(Earth = 1)">1</DENSITY>

  <DISTANCE UNITS="million miles">128.4</DISTANCE><!--B перигелии-->

 </Earth>

</PLANETS>

Таким способом можно создавать новые элементы и задавать им имя во время преобразования XSLT.

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

Аналогично тому, как вы можете создавать новые элементы при помощи <xsl:element> и устанавливать имя и содержимое элемента на этапе выполнения, при помощи элемента <xsl:attribute> это можно делать для атрибутов. 

У элемента два атрибута:

• name (обязательный). Имя нового атрибута. Принимает значение шаблона значений атрибута, возвращающего QName;

• namespace (необязательный). Пространство имен нового атрибута. Устанавливается в URI.

Этот элемент содержит в себе тело шаблона, которое устанавливает значение атрибута.

В листинге 6.7 я создаю новые элементы <PLANET> с атрибутами, которые соответствуют различным названиям планет (значения берутся из атрибута COLOR исходных элементов <PLANET>).

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

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

     Planets

    </TITLE>

   </HEAD>

   <BODY>

    <xsl:apply-templates select="PLANET"/>

   </BODY>

  </HTML>

 </xsl:template>


 <xsl:template match="PLANET">

  <PLANET>

   <xsl:attribute name="{NAME}">

    <xsl:value-of select="@COLOR"/>

   </xsl:attribute>

  </PLANET>

 </xsl:template>

</xsl:stylesheet>

Как можно видеть в приведенном ниже результате, я создал новые атрибуты «с ходу», используя названия планет:

<НТМL>

 <HEAD>

  <TITLE>

   Planets

  </TITLE>

 </HEAD>

 <BODY>

  <PLANET Mercury="RED">

  </PLANET>

  <PLANET Venus="WHITE">

  </PLANET>

  <PLANET Earth="BLUE">

  </PLANET>

 </BODY>

</HTML>

Элемент <xsl:comment>: создание комментариев

По ходу дела можно также создавать и комментарии при помощи элемента <xsl:comment>. Этот элемент не имеет атрибутов и содержит тело шаблона, задающего текст комментария.

В листинге 6.8 я создаю комментарии для замены элементов <PLANET>; текст комментария включает название планеты.

Листинг 6.8. Применение <xsl:comment>

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

     Planets

    </TITLE>

   </HEAD>

   <BODY>

    <xsl:apply-templates select="PLANET"/>

   </BODY>

  </HTML>

 </xsl:template>


 <xsl:template match="PLANET">

  <xsl:comment>This was the <xsl:value-of select="NAME"/> element</xsl:comment>

 </xsl:template>

</xsl:stylesheet>

Вот результат:

<HTML>

 <HEAD>

  <TITLE>

   Planets

  </TITLE>

 </HEAD>

 <BODY>

  <!--This was the Mercury element-->

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