Удаление последних символов в строке XSLT

в моей CMS можно создать новую статью и выбрать изображение, которое будет показано на этой статье. Когда изображение выбрано, миниатюра изображения также будет автоматически создана.

если загруженное изображение называется изображения.формат JPG, то соответствующий эскиз будет автоматически называться image_thumbnail.формат JPG.

теперь я хотел бы использовать эскиз, везде на сайте, где упоминается статья , за исключением самой статьи (где должно быть показано исходное большое изображение).

но как я могу это сделать?

Я представляю, если бы я мог получить исходное имя изображения, а затем разделить его перед суффиксом (.jpg, .png, .jpeg etc.) и забить _thumbnail после имени, тогда этого было бы достаточно.

другими словами, Я хочу взять полное имя файла и разрезать его на две части, чтобы я мог вставить строку _thumbnail между двумя части.

может быть, это сработает, но что если изображение под названием изображения.2horses.формат JPG (файл с более чем одной точкой в имени файла) загружается? Наивный порез перед ".- здесь это не сработает.

есть ли способ обойти это? Возможно, разрезав имя файла до последних 4 (.jpg, .png) или 5 (.jpeg) персонажей?

6 ответов


учитывая имя файла изображения в $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>

С макушки моей головы:

<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

общее решение, включающее только стандартный 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>

вы можете использовать такой шаблон (при условии, что переменная $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>

посмотреть обзор функций XPath в W3Schools, в частности substring-before метод.


Я считаю XPath функции, работающие на string может помочь вам. Я бы попробовал с некоторыми простыми replace или translate.


решение XSLT 2 с использованием regexp:

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

оригинальный ответ (также XSLT 2): Это удаляет все после последнего разделителя (включая разделитель). Таким образом, ниже $separatorRegexp может быть '\.JPG' или просто '\.'and the $separator'.jpg "или".- в другом случае.

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

В конце концов ' _thumbnail.jpg ' можно добавить с помощью concat.