Гораздо сложнее написать шаблон, делающий обратную операцию, — замену символов переноса строки на элементы 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>

Данные, разделенные запятыми (CSV)

Рекурсивную методику замены, которую мы представили выше, можно использовать для того, чтобы разметить данные, разделенные запятыми (или CSV, comma-separated values). CSV — это старый простой формат представления данных, в котором они просто перечисляются через запятую, например:

a, b, с, d, e, f, g

и так далее. Формат CSV был одним из первых шагов к созданию языков разметки: данные в нем уже размечались запятыми.

Покажем на простом примере, как можно преобразовать CSV-данные в XML-документ. Пусть входящий документ выглядит как:

<data>a, b, с, d, e, f</data>

Для того чтобы решение было как можно более общим, вынесем создание XML-разметки для каждого из элементов этой последовательности в отдельный шаблон:

<xsl:template name='item'>

 <xsl:param name='item'/>

 <item><xsl:copy-of select='$item'/></item>

</xsl:template>

Тогда головной размечающий шаблон запишется в виде.

Листинг 11.18. Шаблон, размечающий данные в строковом формате

<xsl:template name='markup' match='text()' mode='CSV'>

 <xsl:param name='str' select='.'/>

 <xsl:param name='delimiter' select='',''/>

 <xsl:choose>

  <xsl:when test='contains($str,$delimiter)'>

   <xsl:call-template name='item'>

    <xsl:with-param name='item'

     select='substring-before($str, $delimiter)'/>

   </xsl:call-template>

   <xsl:call-template name='markup'>

    <xsl:with-param name='str'

Вы читаете Технология XSLT
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату