2009-07-13 215 views
9

在我的CMS中,可以創建一篇新文章,並選擇要在該文章中顯示的圖像。選擇圖像時,圖像的縮略圖也會自動創建。刪除XSLT字符串中的最後一個字符

如果上傳的圖像稱爲image.jpg的,則相應的縮略圖將自動被命名爲image_thumbnail.jpg

現在我想使用縮略圖圖像,除了文章本身(應顯示原始大圖像的地方)之外,網站上提及文章的位置。

但我該怎麼做?

我想如果我能得到的圖像的原始名稱,則將其分解後綴(.jpg.png.jpeg等)和前名後硬編碼_thumbnail,那麼這將是足夠的。

換句話說,我想獲取完整的文件名,並將其分成兩部分,以便我可以在兩部分之間插入字符串_thumbnail

也許這會起作用,但如果上傳一張名爲image.2horses.jpg(文件中有多個點的文件)會怎麼樣?在''之前的天真剪輯。在這裏不起作用。

有沒有辦法解決這個問題?也許通過在最後4個字符(.jpg,.png)或5個(.jpeg)字符之前刪除文件名?

回答

9

鑑於$文件名中的圖像的文件名,

如果你可以假定所有的圖像將在「.JPG」結束,不會有「.JPG」在別處在文件名,然後這應該工作:

<img src="{substring-before($filename, '.jpg')}_thumbnail.jpg" ... /> 

如果你不知道圖像類型(比如,你想處理GIF和PNG也一樣),或者如果你認爲可能會出現在擴展多次文件名(「ima ge.jpg.jpg「),那麼你會希望有一個模板,以幫助您:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image.jpg'"/> 
      </xsl:call-template> 
     </p> 

     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image.09.07.11.jpg'"/> 
      </xsl:call-template> 
     </p> 

     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image.gif'"/> 
      </xsl:call-template> 
     </p> 

     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image with spaces.jpg'"/> 
      </xsl:call-template> 
     </p> 

     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image with irregular spaces.jpg'"/> 
      </xsl:call-template> 
     </p> 

     <p> 
      <xsl:call-template name="image_thumbnail"> 
      <xsl:with-param name="filename" select="'image.jpg.again.jpg'"/> 
      </xsl:call-template> 
     </p> 

    </xsl:template> 

    <xsl:template name="image_thumbnail"> 
    <xsl:param name="filename"/> 
     <xsl:choose> 
     <xsl:when test="contains($filename, '.')"> 
      <xsl:variable name="before" select="substring-before($filename, '.')"/> 
      <xsl:variable name="after" select="substring-after($filename, '.')"/> 
      <xsl:choose> 
      <xsl:when test="contains($after, '.')"> 
       <xsl:variable name="recursive"> 
        <xsl:call-template name="image_thumbnail"> 
        <xsl:with-param name="filename" select="$after"/> 
        </xsl:call-template> 
       </xsl:variable> 
       <xsl:value-of select="concat($before, '.', $recursive)"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="concat($before, '_thumbnail.', $after)"/> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$filename"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 
1

看看XPath functions overview at W3Schools,特別是substring-before的方法。

+0

如果文件名多於一個點,該怎麼辦?例如。 Image.09.07.11.jpg,我做了一個substring-before('Image.09.07.11.jpg','。')? 我不會得到「圖像」,只是沒有更多? – 2009-07-13 13:36:51

+0

您可以通過遞歸或循環獲取字符串中的最後一個點。請參閱http://www.biglist.com/lists/xsl-list/archives/200102/msg00838.html – Scoregraphic 2009-07-13 13:53:02

2

僅涉及標準XSLT的通用解決方案有點難度,因爲您必須從末尾搜索字符串。您可以使用兩個函數分割文件名,即substring-before-last和substring-after-last。不幸的是,這些函數不是XSLT的一部分。你可以谷歌,並嘗試找到implementations。假設你已經作爲XSLT模板,那麼你可以使用下面的模板來生成縮略圖名實現這兩個函數:

<xsl:template name="thumbnail-name"> 
    <xsl:param name="file-name"/> 
    <xsl:call-template name="substring-before-last"> 
    <xsl:with-param name="text" select="$file-name"/> 
    <xsl:with-param name="chars" select="'.'"/> 
    </xsl:call-template> 
    <xsl:text>_thumbnail.</xsl:text> 
    <xsl:call-template name="substring-after-last"> 
    <xsl:with-param name="text" select="$file-name"/> 
    <xsl:with-param name="chars" select="'.'"/> 
    </xsl:call-template> 
</xsl:template> 

您可以使用這樣的模板(假設變量$文件名中包含圖像的名稱):

<img> 
    <xsl:attribute name="src"> 
    <xsl:call-template name="thumbnail-name"> 
     <xsl:with-param name="file-name" select="$file-name"/> 
    </xsl:call-template> 
    </xsl:attribute> 
</img> 
19

關閉我的頭頂:

<xsl:template name="substring-before-last"> 
    <xsl:param name="string1" select="''" /> 
    <xsl:param name="string2" select="''" /> 

    <xsl:if test="$string1 != '' and $string2 != ''"> 
    <xsl:variable name="head" select="substring-before($string1, $string2)" /> 
    <xsl:variable name="tail" select="substring-after($string1, $string2)" /> 
    <xsl:value-of select="$head" /> 
    <xsl:if test="contains($tail, $string2)"> 
     <xsl:value-of select="$string2" /> 
     <xsl:call-template name="substring-before-last"> 
     <xsl:with-param name="string1" select="$tail" /> 
     <xsl:with-param name="string2" select="$string2" /> 
     </xsl:call-template> 
    </xsl:if> 
    </xsl:if> 
</xsl:template> 

古稱:

<xsl:template match="/"> 

    <xsl:variable name="filename" select="'image.2horses.jpg'" /> 

    <xsl:variable name="basename"> 
    <xsl:call-template name="substring-before-last"> 
     <xsl:with-param name="string1" select="$filename" /> 
     <xsl:with-param name="string2" select="'.'" /> 
    </xsl:call-template> 
    </xsl:variable> 

    <xsl:value-of select="$basename" /> 

</xsl:template> 

產量:

image.2horses 
+0

您的代碼與Tomalak一起工作,但我必須將Chris Nielsen的答案標記爲正確答案,因爲它解決了我的問題問題發揮到極致。如果可以的話,我也會將你的標記標記爲:) – 2009-07-14 08:24:19

+0

+1;無論如何,我喜歡你的廣義解決方案。 – 2009-07-14 11:52:53

0

XSLT 2溶液使用正則表達式:

replace($filename, '(\.[^\.]*)$', concat('_thumbnail', '$1')) 

原來的答覆(也XSLT 2): 這將刪除所有在最後一個分隔符(包括分隔符)之後。所以在$ separatorRegexp下面可以是'\ .jpg'或者只是'\'。和$分隔符'.jpg'或'。'在另一種情況下。

string-join(reverse(remove(reverse(tokenize($filename, $separatorRegexp)),1)),$separator) 

最後'_thumbnail.jpg'可以附加concat。

相關問題