'XSLT 3.0 Convert String data type to Date type and apply translate to remove characters

Here is my source XML

<?xml version="1.0" encoding="UTF-8"?>
<Compensation>
    <Salary>
        <BasePay>$18600.1299</BasePay>
        <PayDate>15-Mar-2022</PayDate>
        <Bonus>$3500.99</Bonus>
        <Gym>$670</Gym>
        <Tax>$30,000.9912</Tax>
        
    </Salary>
    <Salary>
        <BasePay>$28600.12</BasePay>
        <PayDate>15-Mar-2022</PayDate>
        <Bonus>$1500.99</Bonus>
        <Gym/>
        <Tax>$50,000</Tax>        
    </Salary> 
</Compensation>

I am trying do following on my XML document

  1. Format date to YYYY-MM-DD format. Currently date on my source XML is of string data type
  2. Remove all currency and commas from whole document.

Here is my XSLT 3.0 solution which is working fine.

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:this="urn:this-stylesheet"
        exclude-result-prefixes="xs this"
        version="3.0">
        <xsl:output method="xml" indent="yes"/>
        
        <xsl:function name="this:fromatDate" as="xs:string">            
            <xsl:param name="dateString"/>              
            <xsl:variable name="month"
                select="('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')"/>
            <xsl:variable name="dd" select="substring($dateString,1,2)"/>
            <xsl:variable name="mm"
                select="format-number(index-of($month,substring($dateString,4,3)),'00')"/>
            <xsl:variable name="yy" select="substring($dateString,8,4)"/>
            <xsl:value-of select="format-date(xs:date( string-join(($yy, $mm, $dd), '-')),'[Y0001]-[M01]-[D01]')"/>
        </xsl:function>
        
        <xsl:mode on-no-match="shallow-copy"/>      
        
              
       <!-- Removes $ symbol and commas --> 

        <xsl:template match="text()">
            <xsl:value-of select="translate(.,'$,', '')"/>
        </xsl:template> 

<!-- Convert string to date --> 
        
        <xsl:template match="PayDate">
            <FormattedPayDate>
                <xsl:value-of select="this:fromatDate(.)"/>
            </FormattedPayDate>
        </xsl:template>
        
    </xsl:stylesheet>

I'm getting the expected result as below. However, I'd like to use anyone's help to know if there is any efficient way to write this code since I want to use XSLT 3.0.

I'm not sure if there is any functions in xpath 3.0 to handle string conversions to date and character removal.

<?xml version="1.0" encoding="UTF-8"?>
<Compensation>
   <Salary>
      <BasePay>18600.1299</BasePay>
      <FormattedPayDate>2022-03-15</FormattedPayDate>
      <Bonus>3500.99</Bonus>
      <Gym>670</Gym>
      <Tax>30000.9912</Tax>
   </Salary>
   <Salary>
      <BasePay>28600.12</BasePay>
      <FormattedPayDate>2022-03-15</FormattedPayDate>
      <Bonus>1500.99</Bonus>
      <Gym/>
      <Tax>50000</Tax>
   </Salary>
</Compensation>


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source