2010-06-25 55 views
6

我想我的生成輸出文件包含指向相對於樣式表的路徑的文件路徑。樣式表的位置可以改變,我不想爲樣式表使用參數。我對這個解決方案是得到充分的樣式表的URI:在XSLT中做文件路徑操作

<xsl:variable name="stylesheetURI" select="document-uri(document(''))" /> 

現在我只需要從$stylesheetURI切斷文件名。這啓發了我寫XSLT的PHP函數basenamedirname 2.0克隆:

<xsl:function name="de:basename"> 
    <xsl:param name="file"></xsl:param> 
    <xsl:sequence select="tokenize($file, '/')[last()]" /> 
</xsl:function> 

<xsl:function name="de:dirname"> 
    <xsl:param name="file"></xsl:param> 
    <xsl:sequence 
     select="string-join(tokenize($file, '/')[position() != last()], '/')" /> 
</xsl:function> 

現在我可以做這樣的事情在我的模板:

<img src="{concat(de:dirname($stylesheetURI),'/img/myimage,png')}" /> 

我的問題是:有沒有更好的/用本機XSLT 2.0實現這一點的更快方法?

+0

我很喜歡在這個問題上工作(+1)。看到我的答案似乎快了25%。 :) – 2010-06-25 13:18:49

回答

7

我測試(不太廣泛)這些功能和它們似乎更快地執行25%比提供。當然,結果取決於字符串長度和限定符的數量:

<xsl:function name="de:basename" as="xs:string"> 
    <xsl:param name="pfile" as="xs:string"/> 
    <xsl:sequence select= 
    "de:reverseStr(substring-before(de:reverseStr($pfile), '/')) 
    " /> 
    </xsl:function> 

    <xsl:function name="de:dirname" as="xs:string"> 
    <xsl:param name="pfile" as="xs:string"/> 
    <xsl:sequence select= 
    "de:reverseStr(substring-after(de:reverseStr($pfile), '/')) 
    " /> 
    </xsl:function> 

    <xsl:function name="de:reverseStr" as="xs:string"> 
    <xsl:param name="pStr" as="xs:string"/> 

    <xsl:sequence select= 
    "codepoints-to-string(reverse(string-to-codepoints($pStr)))"/> 
    </xsl:function> 
+0

哇!難道這是因爲序列實現(使用標記化和字符串連接)比字符串操作具有更多的porform成本?但是,string-to-codeponits也不會返回一個序列嗎? – 2010-06-25 23:31:18

+0

@Alejandro:tokenize()做了很多工作 - 按字符掃描char並將每個標記放置在單獨的項目中。 substring-before()或substring-after()僅掃描到第一次發生的位置。 – 2010-06-26 01:33:51