Удаление последних символов в строке 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.