I. Utilizando una llamada recursiva plantilla llamada:
Esta transformación:
<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>
cuando se aplica en este documento XML:
<t>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0</t>
produce el deseado, salida correcta:
is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
II. Utilizando el FXSL biblioteca:
<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>
Cuando se aplica esta transformación en este documento XML:
<t>http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0</t>
el resultado deseado se produce:
is-it-possible-to-slice-the-end-of-a-url-with-xslt-1-0
hacer la nota :
La plantilla iterUntil
tiene tres parámetros:
- pCond
- una función (de referencia plantilla) que comprueba una condición sobre el resultado actual y potencialmente emite una "señal de parada" (1).
- pFun
- una función (referencia de plantilla) que se utiliza para producir el siguiente resultado actual del resultado actual (o inicialmente del argumento de entrada $ arg1).
- arg1
- el argumento de entrada en el que se aplica inicialmente la función pFun
.
Nuestra función pCond
es la plantilla que coincide con my:condition
. Emite la "señal de parada" (salidas 1) solo si la cadena pasada como $arg1
no contiene ningún '/' caracteres.
Nuestra función pFun
es la plantilla que coincide con my:skipSlash
. Descarta todos los caracteres hasta e incluyendo el primer '/' en la cadena $arg1
El argumento de entrada inicial se define en $arg1
y es el valor de la cadena de la que sólo el texto después de la última '/' debe ser producido.
La principal ventaja de usar FXSL es que esto evita la necesidad de codificar la recursión explícita y las posibilidades de errores al hacerlo. Además, la plantilla/funciones son muy genéricas y potentes y pueden reutilizarse para resolver grandes clases de problemas similares.
Buena pregunta (+1). Vea mi respuesta para dos soluciones completas diferentes. –