My question is similar to Finding last occurence
However i need to output the whole string, just before the last occurence of the delimiter. So the out put in the example should be ABC_12345
Must be XSLT 1.0
My question is similar to Finding last occurence
However i need to output the whole string, just before the last occurence of the delimiter. So the out put in the example should be ABC_12345
Must be XSLT 1.0
Look at the substring-before-last
template I implemented for another question.
Removing the last characters in an XSLT string
It seems to be exactly what you need.
This is essentially the same solution, but in order to preserve the intermediate delimiters in the result, the following three lines must be added:
<xsl:if test="contains(substring-after($pText, $pDelim), $pDelim)">
<xsl:value-of select="$pDelim"/>
</xsl:if>
The whole transformation now becomes:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:variable name="s" select="'ABC_12345_Q-10'"/>
<xsl:template match="/">
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select="$s"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="stripLast">
<xsl:param name="pText"/>
<xsl:param name="pDelim" select="'_'"/>
<xsl:if test="contains($pText, $pDelim)">
<xsl:value-of select="substring-before($pText, $pDelim)"/>
<xsl:if test="contains(substring-after($pText, $pDelim), $pDelim)">
<xsl:value-of select="$pDelim"/>
</xsl:if>
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select=
"substring-after($pText, $pDelim)"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on any XML document (not used), the wanted, correct result is produced:
ABC_12345
<xsl:variable name="s">string_to_cut_no_matter_how_many_underscores</xsl:variable>
<xsl:variable name="s-tokenized" select="tokenize($s, '_')"/>
<xsl:variable name="s_final" select="string-join(remove($s-tokenized, count($s-tokenized)),'_')"/>
as a function :
<xsl:function name="mynamespace:before-last-delimeter">
<xsl:param name="s" />
<xsl:param name="d" />
<xsl:variable name="s-tokenized" select="tokenize($s, $d)"/>
<xsl:value-of select="string-join(remove($s-tokenized, count($s-tokenized)),$d)"/>
</xsl:function>
<xsl:variable name="output" select="mynamespace:before-last-delimeter('I-only-want-before-the-last-dash','-')"/>
okay XSLT 1.0 a lot more challenging :
Took me two templates
2.after-delim (outputs next value and calls itself if another delim) 3.before-last-delim ( starts the process, )
<xsl:template name="after-delim">
<xsl:param name="s"/>
<xsl:param name="d"/>
<xsl:choose>
<xsl:when test="contains($s,$d)">
<xsl:value-of select="concat($d,substring-before($s,$d))"/>
<xsl:call-template name="after-delim">
<xsl:with-param name="s" select="substring-after($s,$d)"/>
<xsl:with-param name="d" select="$d"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="before-last-delim">
<xsl:param name="s"/>
<xsl:param name="d"/>
<xsl:choose>
<xsl:when test="contains($s,$d)">
<xsl:value-of select="substring-before($s,$d)"/>
<xsl:call-template name="after-delim">
<xsl:with-param name="s" select="substring-after($s,$d)"/>
<xsl:with-param name="d" select="$d"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$s"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:call-template name="before-last-delim">
<xsl:with-param name="s" select="'string_to_cut_with_delim'"/>
<xsl:with-param name="d" select="'_'"/>
</xsl:call-template>