XSLT: search for the last event in a string

Given the form number, for example:

ABC_12345_Q-10

I want to end up with:

ABC12345

So I need to find the position of the second underline

Note that there is no standard template or length for any of the β€œsections” between underscores (so I cannot use a substring to just exclude the last section).

xPath 2.0 solutions ok

+6
xpath xslt
source share
4 answers
concat( substring-before($s, '_'), substring-before(substring-after($s, '_'), '_') ) 

As an alternative:

 string-join(tokenize($s, '_')[position() <= 2], '') 
+2
source share

@Pavel_Minaev provided XPath 1.0 amd XPath 2.0 solutions that work if it is known in advance that the number of underscores is 2.

Here are solutions for a more complex problem, where the number of undrscores is not statically known (can be any number):

XPath 2.0 :

 translate(substring($s, 1, index-of(string-to-codepoints($s), string-to-codepoints('_') )[last()] -1 ), '_', '' ) 

XSLT 1.0 :

 <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: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 :

 ABC12345 
+11
source share

Simple solution in XSLT 2.0:

 codepoints-to-string(reverse(string-to-codepoints( substring-before( codepoints-to-string(reverse(string-to-codepoints($s))), '_')))) 

This will give you everything until the last appearance of your separator (underscore).

+4
source share

Generalized -

 substring($string,1, string-length($string)-string-length(str:split($string, '_')[count(str:split($string, '_'))])) 

The idea is to get the index of the last occurrence by dividing the string.

Index of the last occurrence = string-length ($ string) - the length of the last line after splitting

0
source share

All Articles