KnigaRead.com/

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

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

Рис. 3.2. Вывод значений атрибутов, второй вариант 


Как видите, элемент <xsl:text> весьма удобен. Тем не менее вам следует знать вот что: по умолчанию элементы <xsl:text> заменяют символы, которые могут входить в разметку, на эскейп-последовательности. Например, <xsl:text>Here is а greater-than sign: ></xsl:text> будет выведено как «Here is a greater-than sign: &gt;,», а не как «Herе is a greater-than sign: >». А если попытаться использовать < внутри элемента <xsl:text>, процессор XSLT посчитает, что вы пытаетесь открыть элемент внутри элемента <xsl:text>, что неверно. Как же вывести значащие символы, такие как < и >, если есть необходимость? Это можно сделать путем отключения вывода ESC-последовательностей (disabling output escaping).

УСОВЕРШЕНСТВОВАНИЯ В XSLT 2.0

Один из вопросов, которые призван решить XSLT 2.0, это упрощение импорта подобного текста без разбора из других файлов.

Отключение вывода эскейп-последовательностей

При помощи <xsl:text> можно включать в выходной документ непосредственно символы < и &, а не последовательности &lt; и &amp;. Для этого следует установить атрибут disable-output-escaping элемента <xsl:text> в yes («да», по умолчанию он установлен в no, «нет»). В приведенном ниже примере я при помощи <xsl:text> непосредственно пишу текст "<PLANET/>" в выходной документ:

<?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:text disable-output-escaping="yes">

   &lt;PLANET/&gt;

  </xsl:text>

 </xsl:template>

</xsl:stylesheet>

Результат следующий:

<HTML>

 <HEAD>

  <TITLE>

   Planets

  </TITLE>

 </HEAD>

 <BODY>

  <PLANET/>

  <PLANET/>

  <PLANET/>

 </BODY>

</HTML>

Разумеется, не обязательно выводить <PLANET/> при помощи <xsl:text>: этот элемент можно было поместить непосредственно в элемент буквального результата. Но что делать в тех случаях, когда процессор XSLT не сможет распознать нужный нам в выходном документе элемент как фактический элемент? Например, в преобразованных документах XHTML вам потребуется <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">, но процессор XSLT сочтет, что это не хорошо сформированный XML. Как поместить этот элемент в выходные данные?

Можно попробовать поместить этот элемент в раздел <!CDATA[ ]>, как мы увидим в главе 6, и попытаться трактовать его как простые символьные данные, но процессоры XSLT все равно заменят < на &lt;, а > на &gt;.

Правильный способ добавить в вывод элемент <!DOCTYPE> — использовать атрибут doctype-public элемента <xsl:output>, как мы увидим в главе 6, но в качестве демонстрации для этих целей здесь я отключу вывод ESC-последовательностей в элементе <xsl:text> (хотя этот способ не рекомендован для создания элементов <!DOCTYPE>). Вот как это выглядит:

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

  <xsl:text disab1e-output-escaping="yes">

   &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"&gt;

  </xsl:text>

  <HTML>

   <HEAD>

    <TITLE>

     The Planets Table

    </TITLE>

   </HEAD>

   <BODY>

    <H1>

     The Planets Table

    </H1>

    <TABLE BORDER="2">

     <TD>Name</TD>

     <TD>Mass</TD>

     <TD>Radius</TD>

     <TD>Day</TD>

     <xsl:apply-templates/>

    </TABLE>

   </BODY>

  </HTML>

 </xsl:template>


 <xsl:template match="PLANET">

  <TR>

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

   <TD><xsl:apply-templates select="MASS"/></TD>

   <TD><xsl:apply-templates select="RADIUS"/></TD>

   <TD><xsl:apply-templates select="DAY"/></TD>

  </TR>

 </xsl:template>


 <xsl:template match="MASS">

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

  <xsl:text> </xsl:text>

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

 </xsl:template>


 <xsl:template match="RADIUS">

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

  <xsl:text> </xsl:text>

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

 </xsl:template>


 <xsl:template match="DAY">

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

  <xsl:text> </xsl:text>

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

 </xsl:template>

</xsl:stylesheet> 

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

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">

<HTML>

 <HEAD>

  <TITLE>

   The Planets Table

  </TITLE>

 </HEAD>

 <BODY>

  <H1>

   The Planets Table

   .

   .

   .

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

Написание значений атрибутов

В XSLT есть несколько способов написать значения атрибутов в выходные документы, и наиболее мощный — это создать атрибуты с нуля при помощи элемента <xsl:attribute>, как мы увидим в главе 6.

Однако можно также во многих случаях использовать шаблоны значений атрибутов, с которыми мы познакомимся в этой главе.

Предположим, например, что нам требуется преобразовать текст в таких элементах, как <MASS>, <DAY> и <NAME>, в атрибуты элементов <PLANET>, преобразуя planets.xml в следующий вид:

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

<PLANETS>

 <PLANET DAY="58.65 days" RADIUS="1516 miles"

  MASS=".0553 (Earth = 1)" NAME="Mercury"/>

 <PLANET DAY="116.75 days" RADIUS="3716 miles"

  MASS=".815 (Earth = 1)" NAME="Venus"/>

 <PLANET DAY="1 days" RADIUS="2107 miles"

  MASS="1 (Earth = 1)" NAME="Earth"/>

</PLANETS>

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

<xsl:template match="PLANET">

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

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

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

/>

Это не будет работать, поскольку нельзя использовать < внутри значений атрибутов, как я сделал в предыдущем примере. В XSLT для этого есть несколько способов. Один из них — использовать шаблоны значений атрибутов. 

Шаблоны значений атрибутов

Шаблон имени значения атрибута не имеет ничего общего с теми шаблонами, с которыми мы до сих пор работали, — то есть с шаблонами для создания правил таблицы стилей. Напротив, применение шаблона значения атрибута (attribute value template) означает лишь, что значение атрибута может быть установлено во время выполнения.

В этом случае атрибут можно установить в значение выражения XPath (более подробно эта тема изучается в главе 4), если заключить выражение в фигурные скобки. Например, чтобы установить атрибут NAME в строковое значение элемента <DESCRIPTION>, дочернего элемента контекстного узла, это значение можно присвоить следующим образом: NAME={DESCRIPTION}.

В листинге 3.5 приведен правильный код XSLT, в котором значения элементов <NAME>, <MASS>, <RADIUS> и <DAY> присваиваются атрибутам элемента <PLANET> с теми же именами.

Листинг 3.5. Работа с шаблонами значений атрибутов

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

  <xsl:copy>

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

  </xsl:copy>

 </xsl:template>


 <xsl:template match="PLANET">

  <PLANET NAME="{NAME}" MASS="{MASS}" RADIUS="{RADIUS}" DAY="{DAY}"/>

 </xsl:template>

</xsl:stylesheet>

Вот как это делается; посмотрите теперь на результирующий документ, в котором значения в различных элементах были преобразованы в атрибуты:

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