Замена тегов <br> и xsl
Перенос строк и элементы BR
Большинству читателей, скорее всего, хорошо знаком такой элемент языка HTML,
как BR, который используется для обозначения разрыва строки. В обычных
текстовых файлах для той же самой цели используются символы с кодами #xA,
#xD или их комбинации в зависимости от платформы. При совместном
использовании неразмеченного текста и HTML часто возникает задача
преобразования символов перевода строки в элементы BR и наоборот.
Замену элемента BR на текстовый узел, содержащий перевод строки можно
проиллюстрировать следующим тривиальным шаблоном:
Листинг 11.16. Шаблон замены элементов BR на перенос строки
<xsl:template match="BR">
<xsl:text>
</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
aram name="str" select="."/>
<xsl
aram name="search-for" select="'
'"/>
<xsl
aram name="replace-with">
<xsl:element name="BR"/>
<xsl:text>
</xsl:text>
</xsl
aram>
<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
therwise>
<xsl:value-of select="$str"/>
</xsl
therwise>
</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>
Bye.
/lexi
От:Aleksei Valikov ([email protected])
Заголовок:Re: BR
Группы новостей:fido7.ru.xml
Перенос строк и элементы BR
Большинству читателей, скорее всего, хорошо знаком такой элемент языка HTML,
как BR, который используется для обозначения разрыва строки. В обычных
текстовых файлах для той же самой цели используются символы с кодами #xA,
#xD или их комбинации в зависимости от платформы. При совместном
использовании неразмеченного текста и HTML часто возникает задача
преобразования символов перевода строки в элементы BR и наоборот.
Замену элемента BR на текстовый узел, содержащий перевод строки можно
проиллюстрировать следующим тривиальным шаблоном:
Листинг 11.16. Шаблон замены элементов BR на перенос строки
<xsl:template match="BR">
<xsl:text>
</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

<xsl

<xsl

<xsl:element name="BR"/>
<xsl:text>
</xsl:text>
</xsl

<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

<xsl:value-of select="$str"/>
</xsl

</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>
Bye.
/lexi
От:Aleksei Valikov ([email protected])
Заголовок:Re: BR
Группы новостей:fido7.ru.xml