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

时间:2022-03-14 17:14:54

In my CMS it is possible to create a new article, and choose an image to be shown on that article. When an image is chosen, a thumbnail of the image will automatically be created as well.

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

If the uploaded image is called image.jpg, then the corresponding thumbnail will automatically be named image_thumbnail.jpg.

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

I would now like to use the thumbnail image, everywhere on the website where the article is mentioned, except in the article itself (where the original big image should be shown).

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

But how can I do that?

但是我该怎么做呢?

I imagine if I could get the original name of the image, and then split it up before the suffix (.jpg, .png, .jpeg etc.) and hardcode _thumbnail after the name, then that would be sufficient.

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

In other words, I want to take the complete filename, and cut it into two parts, so that I can insert the string _thumbnail between the two parts.

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

Maybe that would work, but what if an image called image.2horses.jpg (a file with more than one dot in the filename) is uploaded? A naive cut before the '.' wouldn't work here.

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

Is there a way to get around this? Perhaps by cutting the filename up before the last 4 (.jpg, .png) or 5 (.jpeg) characters?

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

6 个解决方案

#1


Given the image's filename in $filename,

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

If you can assume that all images will end in ".jpg" and won't have ".jpg" elsewhere in the filename, then this should work:

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

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

If you don't know the image type (like, you want to handle gif and png as well), or if you think the extension may occur multiple times in the filename ("image.jpg.jpg"), then you will want a template to help you:

如果您不知道图像类型(例如,您也想要处理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


Off the top of my head:

脱离我的头顶:

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

Called as:

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

Yields:

image.2horses

#3


A general solution involving only standard XSLT is somewhat hard since you have to search the string from the end. You can split your filename usings two functions, substring-before-last and substring-after-last. Unfortunately, these functions are not part of XSLT. You can Google and try to find implementations. Assuming you have these two functions implemented as XSLT templates you can then use the following template to generate thumbnail names:

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

You can use the template like this (assuming the variable $file-name contains the name of the image):

您可以使用这样的模板(假设变量$ 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>

#4


Have a look at the XPath functions overview at W3Schools, specifically the substring-before method.

查看W3Schools的XPath函数概述,特别是substring-before方法。

#5


I believe XPath functions operating on string might help you. I would try with some simple replace or translate.

我相信在字符串上运行的XPath函数可能对你有帮助。我会尝试一些简单的替换或翻译。

#6


XSLT 2 solution using regexp:

使用regexp的XSLT 2解决方案:

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

Original answer (also XSLT 2): This removes all after the last separator (including the separator). So below the $separatorRegexp could be '\.jpg' or just '\.' and the $separator '.jpg' or '.' in the other case.

原始答案(也是XSLT 2):这将删除最后一个分隔符(包括分隔符)之后的所有分隔符。所以在$ separatorRegexp下面可能是'\ .jpg'或只是'\。'和$分隔符'.jpg'或'。'在另一种情况下。

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

Eventually the '_thumbnail.jpg' can be appended with concat.

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

#1


Given the image's filename in $filename,

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

If you can assume that all images will end in ".jpg" and won't have ".jpg" elsewhere in the filename, then this should work:

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

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

If you don't know the image type (like, you want to handle gif and png as well), or if you think the extension may occur multiple times in the filename ("image.jpg.jpg"), then you will want a template to help you:

如果您不知道图像类型(例如,您也想要处理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


Off the top of my head:

脱离我的头顶:

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

Called as:

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

Yields:

image.2horses

#3


A general solution involving only standard XSLT is somewhat hard since you have to search the string from the end. You can split your filename usings two functions, substring-before-last and substring-after-last. Unfortunately, these functions are not part of XSLT. You can Google and try to find implementations. Assuming you have these two functions implemented as XSLT templates you can then use the following template to generate thumbnail names:

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

You can use the template like this (assuming the variable $file-name contains the name of the image):

您可以使用这样的模板(假设变量$ 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>

#4


Have a look at the XPath functions overview at W3Schools, specifically the substring-before method.

查看W3Schools的XPath函数概述,特别是substring-before方法。

#5


I believe XPath functions operating on string might help you. I would try with some simple replace or translate.

我相信在字符串上运行的XPath函数可能对你有帮助。我会尝试一些简单的替换或翻译。

#6


XSLT 2 solution using regexp:

使用regexp的XSLT 2解决方案:

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

Original answer (also XSLT 2): This removes all after the last separator (including the separator). So below the $separatorRegexp could be '\.jpg' or just '\.' and the $separator '.jpg' or '.' in the other case.

原始答案(也是XSLT 2):这将删除最后一个分隔符(包括分隔符)之后的所有分隔符。所以在$ separatorRegexp下面可能是'\ .jpg'或只是'\。'和$分隔符'.jpg'或'。'在另一种情况下。

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

Eventually the '_thumbnail.jpg' can be appended with concat.

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