xml - XSLT Date Formatting -
i have had @ various suggestions on here none problem. due sources xml comes can receive dates in following 3 formats;
04-04-2014(dd-mm-yyyy) 04-apr-2014(dd-mmm-yyyy) 2014-04-04(yyyy-mm-dd)
i have function or simple command change of these (other third, yet able recognize third correct) yyyy-mm-dd
i have long winded when/when/when currently, there must easier way. current xslt following;
<xsl:choose> <xsl:when test="contains(date, 'jan')"> <xsl:value-of select="concat(substring(date,6),'-01-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'feb')"> <xsl:value-of select="concat(substring(date,6),'-02-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'mar')"> <xsl:value-of select="concat(substring(date,6),'-03-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'apr')"> <xsl:value-of select="concat(substring(date,6),'-04-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'may')"> <xsl:value-of select="concat(substring(date,6),'-05-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'jun')"> <xsl:value-of select="concat(substring(date,6),'-06-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'jul')"> <xsl:value-of select="concat(substring(date,6),'-07-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'aug')"> <xsl:value-of select="concat(substring(date,6),'-08-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'sep')"> <xsl:value-of select="concat(substring(date,6),'-09-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'oct')"> <xsl:value-of select="concat(substring(date,6),'-10-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'nov')"> <xsl:value-of select="concat(substring(date,6),'-11-',substring(date,1,2))" /> </xsl:when> <xsl:when test="contains(date, 'dec')"> <xsl:value-of select="concat(substring(date,6),'-12-',substring(date,1,2))" /> </xsl:when> <xsl:when test="string-length($datestart) = 2"> <xsl:value-of select="concat(substring(date,7),'-',substring(date,4,2),'-',substring(date,1,2))" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="date"/> </xsl:otherwise> </xsl:choose>
so check if date contains months jan,feb etc. , if not, check if first number - 2 characters (dd) , format, other wise assumes yyyy-mm-dd , outputs is.
i have tried - <xsl:value-of select = "format-datetime(date, '[y0001]-[mn]-[d01]')"/>
complains dates year not long enough (as date being treated datetime, should in format yyyy-mm-dd
thanks ian roberts answer below, created below deal few more scenarios , group outputs together;
<xsl:variable name="months" select="('jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec')" /> <xsl:analyze-string select="date" flags="x" regex="^( (\d\d)-(\d\d)-(\d\d\d\d) | (\d\d)-([a-za-z]{{3}})-(\d\d\d\d) | (\d\d\d\d)-(\d\d)-(\d\d) | (\d\d\d\d)-([a-za-z]{{3}})-(\d\d) | (\d\d)([a-za-z]{{3}})(\d\d\d\d) | (\d\d\d\d)([a-za-z]{{3}})(\d\d))$"> <xsl:matching-substring> <xsl:value-of select="if (regex-group(4)) concat(regex-group(4),'-',regex-group(3),'-',regex-group(2)) else ''"/> <xsl:value-of select="if (regex-group(7)) concat(regex-group(7),'-',format-number(index-of($months, regex-group(6)), '00'),'-',regex-group(5)) else ''"/> <xsl:value-of select="if (regex-group(8)) concat(regex-group(8),'-',regex-group(9),'-',regex-group(10)) else ''"/> <xsl:value-of select="if (regex-group(11)) concat(regex-group(11),'-',format-number(index-of($months, regex-group(12)), '00'),'-',regex-group(13)) else ''"/> <xsl:value-of select="if (regex-group(16)) concat(regex-group(16),'-',format-number(index-of($months, regex-group(15)), '00'),'-',regex-group(14)) else ''"/> <xsl:value-of select="if (regex-group(17)) concat(regex-group(17),'-',format-number(index-of($months, regex-group(18)), '00'),'-',regex-group(19)) else ''"/> </xsl:matching-substring> </xsl:analyze-string>
since refer format-datetime
must in xslt 2.0, approach using regular expressions. if know you'll have 1 of these 3 forms use analyze-string
:
<xsl:variable name="months" select="('jan', 'feb', 'mar', 'apr', ...)" /> <xsl:analyze-string select="date" flags="x" regex="^( (\d\d)-(\d\d)-(\d\d\d\d) | (\d\d)-([a-za-z]{{3}})-(\d\d\d\d) | (\d\d\d\d)-(\d\d)-(\d\d))$"> <xsl:matching-substring> <!-- year --> <xsl:value-of select="regex-group(4)"/> <xsl:value-of select="regex-group(7)"/> <xsl:value-of select="regex-group(8)"/> <xsl:text>-</xsl:text> <!-- month --> <xsl:value-of select="regex-group(3)"/> <xsl:value-of select="if (regex-group(6)) format-number(index-of($months, regex-group(6)), '00') else ''"/> <xsl:value-of select="regex-group(9)"/> <xsl:text>-</xsl:text> <!-- day --> <xsl:value-of select="regex-group(2)"/> <xsl:value-of select="regex-group(5)"/> <xsl:value-of select="regex-group(10)"/> </xsl:matching-substring> </xsl:analyze-string>
each of example formats match 1 of 3 alternatives in pattern, , regex-group
calls non-matching alternatives produce empty strings.
Comments
Post a Comment