Книга: 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.

Оглавление книги


Генерация: 1.923. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз