2010-06-05 55 views
7

仅使用XSLT 1.0的字符串函数,我将如何去切掉url的结尾?是否可以使用XSLT 1.0切断URL的末尾?

所以从

http://stackoverflow.com/questions/2981175/is-it-possible-to-slice-the-end-of-a-url-with-xslt-1- 0

我想提取

是-IT-可能对切片的端对的一-URL与 - XSLT-1-0

这可能吗?

+0

好问题(+1)。看到我的答案有两种不同的完整解决方案 – 2010-06-05 18:28:04

回答

7

不幸的是,在XSLT/XPath 1.0中没有substring-after-last函数。因此,要获得一个网址的最后一部分,你必须写一个递归模板explained by Jeni Tenisson

<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> 
2

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 

待办事项:

  1. 模板iterUntil有三个参数:

    - pCond - 函数(模板参考),检查关于当前结果的条件和潜在的发出“停止信号”(1)。

    - pFun - 用于从当前结果(或最初从输入参数$ arg1)生成下一个当前结果的函数(模板引用)。

    - arg1 - 最初应用pFun函数的输入参数。

  2. 我们的pCond函数是匹配my:condition的模板。只有当传递的字符串$arg1不包含任何'/'字符时,才会发出“停止信号”(输出1)。

  3. 我们的pFun函数是匹配my:skipSlash的模板。它丢弃所有字符直到并包括字符串$arg1

  4. 初始输入参数在$arg1定义且是从该后只有文本的最后一个“/”必须产生的字符串值在第一“/”。

  5. 使用FXSL的主要优点是,这避免了编码显式递归的必要性以及执行此操作的错误的可能性。此外,模板/功能非常通用且功能强大,可以重新用于解决大量类似的问题。

+0

'my:'命名空间是做什么的? – Eric 2010-06-05 18:19:32

+0

@Eric:使用名为''的子元素的名称空间元素是一种众所周知的技术,它允许开发人员定义可以访问的全局常量(使用'document('')/ * /前缀:名称'XPath表达式)的XSLT代码。 – 2010-06-05 18:27:23