2010-06-05 54 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