Замена специальных символов

Замена специальных символов

Как мы уже знаем, в XML есть несколько специальных символов, которые, как правило, заменяются процессором при выводе документа на соответствующие символьные или встроенные сущности. К примеру, для того, чтобы вывод был корректным XML-документом, процессор обязан заменять символы "<" и "&" на встроенные (&lt; и &amp;) или символьные (&#60; и &#38;) сущности.

Между тем довольно часто бывает необходимым выводить в выходящем документе символы разметки.

Пример

Пусть входящий документ содержит описание товара, заданное в секции CDATA:

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

<product>

 <title>An elephant</title>

 <description><![CDATA[This is a <em>big</em> and <b>grey</b> animal!]]></description>

</product>

Если мы будем преобразовывать этот документ с использованием шаблона

<xsl:template match="product">

 <p>

  <xsl:value-of select="title"/><xsl:text>&#xA;</xsl:text><br/>

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

</p>

</xsl:template>

то в выходящем документе специальные символы будут заменены:

<p>An elephant

<br/>This is a &lt;em&gt;big&lt;/em&gt; and &lt;b&gt;grey&lt;/b&gt; animal!</p>

Для того чтобы избежать замены, можно воспользоваться атрибутом disable-output-escaping (отменить замену символов) элементов xsl:value-of и xsl:text. Этот атрибут может принимать значения "yes" и "no" ("no" — значение по умолчанию). Значение "yes" означает, что процессор при выводе текста, создаваемого xsl:text или xsl:value-of не должен заменять специальные символы. Если бы в предыдущем примере мы использовали преобразование.

Листинг 8.56. Преобразование, содержащее disable-output-escaping

<xsl:stylesheet version="1.0"

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

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

 <xsl:template match="product">

  <p>

   <xsl:value-of select="title"/><xsl:text>&#xA;</xsl:text><br/>

   <xsl:value-of disable-output-escaping="yes" select="description"/>

  </p>

 </xsl:template>

</xsl:stylesheet>

то на выходе мы бы получили документ

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

<p>An elephant

<br/>This is a <em>big</em> and <b>grey</b> animal!</p>

Атрибут disable-output-escaping налагает ряд ограничений на использование текстовых узлов, генерируемых элементами xsl:text и xsl:value-of: эти узлы не могут входить в качестве текстового содержимого в узлы атрибутов, комментариев или инструкций по обработке. Кроме того, дерево, содержащее текстовые узлы, для которых была отменена замена специальных символов, не может быть приведено к строке или числу. И в том и в другом случае процессор может либо выдать ошибку преобразования, либо проигнорировать отмену замены специальных символов.

Атрибут disable-output-escaping имеет также и более концептуальное ограничение. Процессор сможет отменить замену символов только в том случае, когда он сам будет контролировать процесс вывода. Как мы уже обсуждали в предыдущем разделе, ситуации, когда процесс вывода не будет выполняться самим процессором, не такая уж и редкость. Поэтому следует использовать disable-output-escaping только в тех случаях, когда другой альтернативы нет или когда имеется полная уверенность, что этот метод будет работать.

Атрибут disable-output-escaping работает с методами вывода "xml" и "html", но не оказывает никакого влияния на метод "text", поскольку при этом методе все специальные символы и так выводятся без замены.