I. Использование рекурсивно названного именованного шаблона :
Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:call-template name="eatAllSlashes">
<xsl:with-param name="pText" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="eatAllSlashes">
<xsl:param name="pText"/>
<xsl:choose>
<xsl:when test="not(contains($pText,'/'))">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="eatAllSlashes">
<xsl:with-param name="pText"
select="substring-after($pText, '/')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
при применении к этому документу XML :
<t>/2134607/mozhno-li-otrezat-konets-url-s-pomoschy-xslt-1-0</t>
производит требуемый, правильный вывод :
is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
II. Использование библиотеки FXSL :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="xsl my">
<xsl:import href="iter.xsl"/>
<xsl:output method="text"/>
<my:condition/>
<my:skipSlash/>
<xsl:variable name="vfunCondition"
select="document('')/*/my:condition"/>
<xsl:variable name="vfunSkipSlash"
select="document('')/*/my:skipSlash"/>
<xsl:template match="/">
<xsl:call-template name="iterUntil">
<xsl:with-param name="pCond" select="$vfunCondition"/>
<xsl:with-param name="pFun" select="$vfunSkipSlash"/>
<xsl:with-param name="arg1" select="string(/)"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="my:condition">
<xsl:param name="arg1"/>
<xsl:value-of select="number(not(contains($arg1, '/')))"/>
</xsl:template>
<xsl:template match="my:skipSlash">
<xsl:param name="arg1"/>
<xsl:value-of select="substring-after($arg1, '/')"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к этому документу XML:
<t>/2134607/mozhno-li-otrezat-konets-url-s-pomoschy-xslt-1-0</t>
желаемый результат получен :
is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
Примечание:
Шаблон iterUntil
имеет три параметра:
- pCond
- функция (ссылка на шаблон), которая проверяет условие текущего результата и потенциально выдает «сигнал остановки» (1).
- pFun
- функция (ссылка на шаблон), которая используется для получения следующего текущего результата из текущего результата (или первоначально из входного аргумента $ arg1).
- arg1
- входной аргумент, к которому изначально применяется функция pFun
.
Наша функция pCond
- это шаблон, соответствующий my:condition
. Он выдает «сигнал остановки» (вывод 1), только если строка, переданная как $arg1
, не содержит символов '/'.
Наша pFun
функция - это шаблон, соответствующий my:skipSlash
. Отбрасывает все символы до и включая первый символ '/' в строке $arg1
Начальный входной аргумент определен в $arg1
и является строковым значением, из которого должен быть получен только текст после последнего '/'.
Основным преимуществом использования FXSL является то, что это избавляет от необходимости кодировать явную рекурсию и вероятность ошибок при этом. Кроме того, шаблон / функции являются очень общими и мощными и могут быть повторно использованы для решения огромных классов подобных задач.