Xslt 1.0 - Search for the last occurrence and capture of a line before
My question is similar to Last Event Search
However, I need to print the entire line, just before the last input of the delimiter. Thus, in the example should be ABC_12345
Must be XSLT 1.0
Take a look at the substring-before-last
pattern that I followed for another question.
Delete last characters in an XSLT string
This seems to be exactly what you need.
This is essentially the same solution, but to save intermediate delimiters as a result, you must add the following three lines :
<xsl:if test="contains(substring-after($pText, $pDelim), $pDelim)"> <xsl:value-of select="$pDelim"/> </xsl:if>
Now the whole transformation becomes the following:
<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 conversion is applied to any XML document (not used), the desired, correct result is obtained :
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 is much more complicated:
They brought me two patterns
2.after-delim (displays the 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>