删除XSLT字符串中的最后一个字符

时间:2009-07-13 13:26:53

标签: image xslt

在我的CMS中,可以创建新文章,并选择要在该文章上显示的图像。选择图像后,也会自动创建图像的缩略图。

如果上传的图片名为 image.jpg ,则相应的缩略图会自动命名为 image_thumbnail.jpg

我现在想在提到文章的网站上的任何地方使用缩略图,除了文章本身(应该显示原始大图像)。

但我怎么能这样做?

我想如果我能得到图像的原始名称,然后在后缀(.jpg.png.jpeg等)之前将其拆分并硬编码{{1在名称之后,那就足够了。

换句话说,我想获取完整的文件名,并将其分成两部分,以便我可以在两部分之间插入字符串_thumbnail

也许这样可行,但是如果上传了一张名为 image.2horses.jpg 的图像(文件名中包含多个点的文件)呢? '。'之前的天真切口。不会在这里工作。

有没有办法解决这个问题?也许在最后4个(_thumbnail.jpg)或5个(.png)字符之前剪切文件名?

6 个答案:

答案 0 :(得分:20)

脱离我的头顶:

<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

答案 1 :(得分:9)

鉴于$ filename中的图像文件名,

如果你可以假设所有图像都以“.jpg”结尾,并且文件名中的其他地方没有“.jpg”,那么这应该有效:

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

如果您不知道图像类型(例如,您也想要处理gif和png),或者您认为扩展名可能在文件名中多次出现(“image.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>

答案 2 :(得分:2)

仅涉及标准XSLT的一般解决方案有点难,因为您必须从末尾搜索字符串。您可以使用两个函数拆分文件名,substring-before-last和substring-after-last。不幸的是,这些函数不是XSLT的一部分。您可以在Google上尝试查找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>

您可以使用这样的模板(假设变量$ file-name包含图像的名称):

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

答案 3 :(得分:1)

查看XPath functions overview at W3Schools,特别是substring-before方法。

答案 4 :(得分:0)

我相信XPath functions operating on string可能会对您有所帮助。我会尝试一些简单的replacetranslate

答案 5 :(得分:0)

使用regexp的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。