"Regular expression" -style replaced in XSLT 1.0

I need to search and replace with XSLT 1.0, which is really suitable for regular expressions. Unfortunately, they are not available in version 1.0, and I also cannot use any extension libraries such as EXSLT due to security settings that I cannot change.

The line I'm working with is as follows:

19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson

I need to replace numbers and characters ; # ; # on,. For example, the above would change to:

John Smith, Ben Reynolds, Terry Jackson

I know that a recursive string function is required, possibly using substring and translation, but I'm not sure where to start.

Does anyone have directions on how to do this? Here is what I started with:

 <xsl:template name="TrimMulti"> <xsl:param name="FullString" /> <xsl:variable name="NormalizedString"> <xsl:value-of select="normalize-space($FullString)" /> </xsl:variable> <xsl:variable name="Hash">#</xsl:variable> <xsl:choose> <xsl:when test="contains($NormalizedString, $Hash)"> <!-- Do something and call TrimMulti --> </xsl:when> </xsl:choose> </xsl:template> 
+4
source share
2 answers

I hope that you did not simplify the problem too much to ask about it, because it should not be a big problem.

You can define a template and call it recursively as long as you keep the input line format consistent.

For instance,

 <xsl:template name="TrimMulti"> <xsl:param name="InputString"/> <xsl:variable name="RemainingString" select="substring-after($InputString,';#')"/> <xsl:choose> <xsl:when test="contains($RemainingString,';#')"> <xsl:value-of select="substring-before($RemainingString,';#')"/> <xsl:text>, </xsl:text> <xsl:call-template name="TrimMulti"> <xsl:with-param name="InputString" select="substring-after($RemainingString,';#')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$RemainingString"/> </xsl:otherwise> </xsl:choose> </xsl:template> 

I checked this template with the following call:

 <xsl:template match="/"> <xsl:call-template name="TrimMulti"> <xsl:with-param name="InputString">19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson</xsl:with-param> </xsl:call-template> </xsl:template> 

And I got the following conclusion:

 John Smith, Ben Reynolds, Terry Jackson 

It seems that you need to.

The explanation of what he does is easy to explain if you are familiar with functional programming. The InputString parameter is always in the form [number];#[name];#[rest of string] . Each call to the TrimMulti template TrimMulti [number];# part and imprints the [name] , and then passes the remaining expression to itself recursively.

In the base case, the InputString is in the form [number];#[name] , in which case the RemainingString variable will not contain ;# . Since we know that this is the end of the input, this time we do not output a comma.

+8
source

If ';' and '#' are invalid at the input because they are delimiters, why not translate the function? This may be ugly (you must specify all valid characters in the second argument and repeat them in the third argument), but it would be easier to debug.

 translate($InputString, ';#abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ', ', abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUZ0123456789,- ') 
-1
source

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


All Articles