Книга: Технология XSLT

Перенос строк и элементы BR

Перенос строк и элементы BR

Большинству читателей, скорее всего, хорошо знаком такой элемент языка HTML, как BR, который используется для обозначения разрыва строки. В обычных текстовых файлах для той же самой цели используются символы с кодами #xA, #xD или их комбинации в зависимости от платформы. При совместном использовании неразмеченного текста и HTML часто возникает задача преобразования символов перевода строки в элементы BR и наоборот.

Замену элемента BR на текстовый узел, содержащий перевод строки, можно проиллюстрировать следующим тривиальным шаблоном.

Листинг 11.16. Шаблон замены элементов BR на перенос строки

<xsl:template match="BR">
 <xsl:text>&#xA;</xsl:text>
</xsl:template>

Гораздо сложнее написать шаблон, делающий обратную операцию, — замену символов переноса строки на элементы BR. В XSLT нет встроенного механизма для замены подстроки в строке (тем более на элемент), поэтому нам придется создать для этой цели собственный шаблон.

Для этой цели мы можем воспользоваться функциями substring-before и substring-after. Функция substring-before($str, $search-for) возвратит часть строки str, которая предшествует первому вхождению в нее подстроки search-for, а функция substring-after($str, $search-for) — последующую часть. То есть заменить первое вхождение можно шаблоном вида

<!-- ... -->
<xsl:value-of select = "substring-before($str, $search-for)"/>
<xsl:copy-of select = "$replace-with"/>
<xsl:value-of select = "substring-after($str, $search-for)"/>
<!-- ... -->

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

Листинг 11.17. Шаблон для замены подстроки в строке

<xsl:template name="replace" match="text()" mode="replace">
 <xsl:param name="str" select="."/>
 <xsl:param name="search-for" select="'&#xA;'"/>
 <xsl:param name="replace-with">
  <xsl:element name="BR"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:param>
 <xsl:choose>
  <xsl:when test="contains($str, $search-for)">
   <xsl:value-of select="substring-before($str, $search-for)"/>
   <xsl:copy-of select="$replace-with"/>
   <xsl:call-template name="replace">
    <xsl:with-param name="str"
     select="substring-after($str, $search-for)"/>
    <xsl:with-param name="search-for" select="$search-for"/>
    <xsl:with-param name="replace-with " select="$replace-with"/>
   </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
   <xsl:value-of select="$str"/>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

Шаблон, приведенный в этом листинге, может быть вызван двумя способами: элементом xsl:apply-templates в режиме replace (в этом случае он будет обрабатывать текстовые узлы выбранного множества), или при помощи именного вызова элементом xsl:call-template. Шаблон принимает на вход три параметра.

? Параметр str, содержащий строку, в которой нужно произвести замену. По умолчанию этому параметру присваивается текстовое значение текущего узла.

? Параметр search-for, содержащий подстроку, которую требуется найти и заменить в строке str. По умолчанию замене будут подлежать символы переноса строки, "&#хА;".

? Параметр replace-with, содержащий объект, на который следует заменять подстроки search-for. По умолчанию эти подстроки будут заменяться на элемент BR и следующий за ним перенос строки, добавленный для лучшей читаемости.

В качестве примера отформатируем содержание следующего элемента:

<pre>One little rabbit
Two little rabbits
Three little rabbits</pre>

Запишем шаблон для обработки элемента pre:

<xsl:template match="pre">
 <xsl:copy>
  <xsl:apply-templates mode="replace"/>
 </xsl:copy>
</xsl:template>

Результат его выполнения будет иметь следующий вид:

<pre>One little rabbit<BR/>
Two little rabbits<BR/>
Three little rabbits</pre>

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


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