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

+6
xml xslt
source share
4 answers


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.

+6
source share


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 
+3
source share


  <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','-')"/> 
0
source share


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> 
0
source share

Source: https://habr.com/ru/post/918814/


All Articles