RobertFrenette
RobertFrenette

Reputation: 627

XSLT: Replace multiple chars in a string

I have the following String, which represents days of the week:

1, 2, 3, 4, 5

I'd like to replace those values with:

M, Tu, W, ...

I don't know that there is an XSLT 2.0 function that will handle that in one shot. Does anyone know of a way to accomplish this?

Thanks

Upvotes: 0

Views: 1002

Answers (2)

Daniel Haley
Daniel Haley

Reputation: 52848

Similar to C. M. Sperberg-McQueen's answer only using a sequence as the variable...

XML Input

<doc>
    <x>1, 2, 3, 4, 5</x>
    <x>1, 3, 5</x>
    <x>2, 4</x>
</doc>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="daysOfWeek" select="('M','Tu','W','Th','F','Sa','Su')"/>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="x">
        <x>
            <xsl:value-of select="for $n in tokenize(.,',') 
                return $daysOfWeek[position()=number(normalize-space($n))]" 
                separator=", "/>        
        </x>
    </xsl:template>

</xsl:stylesheet>

XML Output

<doc>
   <x>M, Tu, W, Th, F</x>
   <x>M, W, F</x>
   <x>Tu, Th</x>
</doc>

Upvotes: 3

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

Reputation: 25034

No, there is no built-in function in XSLT that will take a comma-delimited string with numerals in the range 1-7 (or 0-6) and return a comma-delimited sequence of the corresponding one- or two-character abbreviations of the days of the week. You'll have to use more than one function call.

Assuming for simplicity that you're in XSLT 2.0:

<xsl:variable name="daynames" as="element(day)*">
  <day n="1">M</day>
  <day n="2">Tu</day>
  <day n="3">W</day>
  <day n="4">Th</day>
  <day n="5">F</day>
  <day n="6">Sa</day>
  <day n="7">Su</day>
</

<xsl:variable name="string" value="'1, 2, 3, 4, 5'"/>

<xsl:value-of select="string-join(
  for $n in tokenize($string,', ') return $days[@n=$n]/string(),
  ', ')"/>

In XSLT 1.0, this will be a little more verbose, but can be done with a recursive named template.

Upvotes: 1

Related Questions