Для того же, чтобы заменить все вхождения, достаточно рекурсивно повторить операцию замены первого вхождения с той частью строки, которая следует за ним. Приведем шаблон, который выполняет эту операцию.
Листинг 11.17. Шаблон для замены подстроки в строке
приведенный в этом листинге, может быть вызван двумя способами: элементом
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. Шаблон, размечающий данные в строковом формате