删除XSLT字符串中的最后一个字符
在我的CMS中,可以创建一篇新文章,并选择要在该文章中显示的图像。选择图像时,图像的缩略图也会自动创建。删除XSLT字符串中的最后一个字符
如果上传的图像称为image.jpg的,则相应的缩略图将自动被命名为image_thumbnail.jpg。
现在我想使用缩略图图像,除了文章本身(应显示原始大图像的地方)之外,网站上提及文章的位置。
但我该怎么做?
我想如果我能得到的图像的原始名称,则将其分解后缀(.jpg
,.png
,.jpeg
等)和前名后硬编码_thumbnail
,那么这将是足够的。
换句话说,我想获取完整的文件名,并将其分成两部分,以便我可以在两部分之间插入字符串_thumbnail
。
也许这会起作用,但如果上传一张名为image.2horses.jpg(文件中有多个点的文件)会怎么样?在''之前的天真剪辑。在这里不起作用。
有没有办法解决这个问题?也许通过在最后4个字符(.jpg
,.png
)或5个(.jpeg
)字符之前删除文件名?
鉴于$文件名中的图像的文件名,
如果你可以假定所有的图像将在“.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>
仅涉及标准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>
关闭我的头顶:
<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
您的代码与Tomalak一起工作,但我必须将Chris Nielsen的答案标记为正确答案,因为它解决了我的问题问题发挥到极致。如果可以的话,我也会将你的标记标记为:) – 2009-07-14 08:24:19
+1;无论如何,我喜欢你的广义解决方案。 – 2009-07-14 11:52:53
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。
如果文件名多于一个点,该怎么办?例如。 Image.09.07.11.jpg,我做了一个substring-before('Image.09.07.11.jpg','。')? 我不会得到“图像”,只是没有更多? – 2009-07-13 13:36:51
您可以通过递归或循环获取字符串中的最后一个点。请参阅http://www.biglist.com/lists/xsl-list/archives/200102/msg00838.html – Scoregraphic 2009-07-13 13:53:02