Удаление последних символов в строке XSLT - PullRequest
9 голосов
/ 13 июля 2009

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

Если загруженное изображение называется image.jpg , соответствующая миниатюра автоматически получит имя image_thumbnail.jpg .

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

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

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

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

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

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

Ответы [ 6 ]

20 голосов
/ 13 июля 2009

с макушки головы:

<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
9 голосов
/ 13 июля 2009

Учитывая имя файла изображения в $ 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 голосов
/ 13 июля 2009

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

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

0 голосов
/ 01 июня 2017

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.

0 голосов
/ 13 июля 2009

Я думаю, Функции XPath, работающие со строкой , могут вам помочь. Я бы попробовал с некоторыми простыми replace или translate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...