Только Используя XSLT 1.0's строковые функции, как я пошел бы об отрезании конца URL?
Таким образом от
http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
Я хотел бы извлечь
is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
Действительно ли это возможно?
К сожалению, в XSLT / XPath 1.0 нет функции подстроки после последней. Итак, чтобы получить последнюю часть URL-адреса, вам нужно будет написать рекурсивный шаблон, как объяснил Джени Тениссон :
<xsl:template name="substring-after-last">
<xsl:param name="string" />
<xsl:param name="delimiter" />
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string"
select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiter" select="$delimiter" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$string" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
Этот шаблон будет вызываться, например, вот так:
<xsl:call-template name="substring-after-last">
<xsl:with-param name="string" select="$url" />
<xsl:with-param name="delimiter" select="'/'" />
</xsl:call-template>
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>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-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>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-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 заключается в том, что это избавляет от необходимости кодировать явную рекурсию и возможности ошибок при этом. Кроме того, шаблоны/функции являются очень общими и мощными и могут быть повторно использованы для решения огромных классов подобных задач.