Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

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

select="substring-after($str, $delimiter)"/>

</xsl:call-template>

<xsl:with-param name="delimiter" select="$delimiter"/>

</xsl:when>

<xsl:otherwise>

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

<xsl:with-param name="item" select="$str"/>

</xsl:call-template>

</xsl:otherwise>

Поделиться с друзьями: