|
Subject:
|
Date Validation from String
|
|
Posted By:
|
iceandrews
|
Post Date:
|
5/13/2008 12:11:09 PM
|
I have a template below for checking to see if a string is a valid date. The idea here I am getting a document containing a list of dates in string values like so.
<DATES> <DATE1>20080501</DATE1> <DATE2>20080901</DATE2> <DATE3>20080112</DATE3> .................... <DATE42>20081128</DATE42> </DATES>
I've written an template that will parse this incoming document and tell you if it is a valid string to represent a date in the YYYYMMDD format. Just so you no the only valid format for my incoming document should be 'YYYYMMDD'. It cannot contain any white space. I thought about using 'matches()' or <xsl:analyze-string>, but I thought this worked better. I just wanted to bounce it off the experts to see if you can spot any major holes. Thanks for your thoughts.
<xsl:template match="DATES/*" mode="YYYYMMDD" >
<xsl:variable name="FullDate">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length(.)=8">
<xsl:variable name="FullDateFormat">
<xsl:value-of select="concat(substring($FullDate, 1, 4),'-',substring($FullDate, 5, 2),'-',substring($FullDate, 7, 2))"/>
</xsl:variable>
<xsl:value-of select="if ($FullDateFormat castable as xs:date) then (concat(local-name(.),' is VALID')) else (concat(local-name(.), ' ***IS NOT A DATE***'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(local-name(.), ' ***IS NOT A DATE***')" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
|
|
Reply By:
|
Martin Honnen
|
Reply Date:
|
5/13/2008 12:21:46 PM
|
The XML with DATE1, DATE2 and so on looks awful to me. But the XSLT approach using castable as xs:date looks fine to me. There is no need however for the variable FullDate, you could as well use the dot
concat(substring(., 1, 4),'-',substring(., 5, 2),'-',substring(., 7, 2))
the same you do with string-length(.).
-- Martin Honnen Microsoft MVP - XML
|
|
Reply By:
|
iceandrews
|
Reply Date:
|
5/13/2008 12:51:28 PM
|
Well, the <DATES> XML isn't really what source file looks like. It is actually a XML file that contains various elements that should be in the YYYYMMDD format. This template is only going apply for those elements.
I realized that I really didn't need the variable. I more did it to keep things straight in my head as I worked through the logic. The '.' doesn't read well in my mind, so I just did that to be explicit with my thoughts. Thanks.
|
|
Reply By:
|
mhkay
|
Reply Date:
|
5/13/2008 4:49:59 PM
|
It's a really bad habit to use
<xsl:variable name="x"> <xsl:value-of select="y"/> </xsl:variable>
when you could have written
<xsl:variable name="x" select="y"/>
which is much shorter and much faster.
Apart from that, nothing very wrong with your code, except it can be shortened. I think I would have written it as:
<xsl:template match="DATES/*"> <xsl:value-of select="local-name()"/> <xsl:value-of select="if (replace(., '([0-9]{4})([0-9]{2})([0-9]{2})', '$1-$2-$3') castable as xs:date) then ' is VALID' else ' ***IS NOT A DATE***'"/> </xsl:template>
Michael Kay http://www.saxonica.com/ Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|
|
Reply By:
|
iceandrews
|
Reply Date:
|
5/14/2008 7:25:49 AM
|
quote: Originally posted by mhkay I think I would have written it as:
<xsl:template match="DATES/*"> <xsl:value-of select="local-name()"/> <xsl:value-of select="if (replace(., '([0-9]{4})([0-9]{2})([0-9]{2})', '$1-$2-$3') castable as xs:date) then ' is VALID' else ' ***IS NOT A DATE***'"/> </xsl:template>
Michael Kay http://www.saxonica.com/ Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Thanks! Having a different perspective is really helping. I don't think I would've thought of using replace that way. This is a great community.
|