Subject: RE: [xsl] Date Difference From: "Haarman, Michael" <mhaarman@xxxxxxxxx> Date: Mon, 19 Dec 2005 18:15:29 -0600 |
> -----Original Message----- > From: Wendell Piez > If you want your dates to have "dateness", XPath 2.0 is the way to > go, and Mike H has shown the way forward. As much as to say "over yonder". Wendell reminds me that I failed to account for single digit days, as well. It matters because the cast to xs:date demands a normalized, standardized and reliable lexical form: YYYY-MM-DD FWIW, the following stylesheet, much revised, does just what is required and nothing more, over the following instance XML: testDate2.xml ------------- <?xml version="1.0"?> <data> <dateRange> <date>9/1/2004</date> <date>10/25/2005</date> </dateRange> </data> testDate2.xsl ------------- <?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:fn="http://www.w3.org/2005/xpath-functions" version="2.0" exclude-result-prefixes="xs fn"> <xsl:template match="/"> <output> <xsl:apply-templates/> </output> </xsl:template> <xsl:template match="*/dateRange"> <xsl:variable name="dateOne"> <xsl:call-template name="correctDate"> <xsl:with-param name="dateParts" select="fn:tokenize(date[1], '/')"/> </xsl:call-template> </xsl:variable> <xsl:variable name="dateTwo"> <xsl:call-template name="correctDate"> <xsl:with-param name="dateParts" select="fn:tokenize(date[2], '/')"/> </xsl:call-template> </xsl:variable> <duration> <xsl:value-of select="xs:date($dateOne) - xs:date($dateTwo)"/> </duration> </xsl:template> <xsl:template name="correctDate"> <xsl:param name="dateParts"/> <xsl:value-of select="$dateParts[3]"/> <xsl:text>-</xsl:text> <xsl:call-template name="pad"> <xsl:with-param name="digits" select="$dateParts[1]"/> </xsl:call-template> <xsl:text>-</xsl:text> <xsl:call-template name="pad"> <xsl:with-param name="digits" select="$dateParts[2]"/> </xsl:call-template> </xsl:template> <xsl:template name="pad"> <xsl:param name="digits"/> <xsl:choose> <xsl:when test="fn:string-length($digits) = 1"> <xsl:value-of select="concat('0', $digits)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$digits"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> Producing this output with Saxon 8: <?xml version="1.0" encoding="UTF-8"?> <output> <duration>-P419D</duration> </output> I have broken out two parameterized templates: one to correct a supplied date in 'Merkin grade-school form to ISO form and another pre-padding a zero to any supplied string if a single digit. All very instructive. The machines are simple and have correspondingly strict lexical requirements. fn:replace() no longer made sense when each token of the string needed touched. And fn:tokenize() is slick as snot. The result carries a leading minus when the first supplied date temporally precedes the second. Mike
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Date Difference, Haarman, Michael | Thread | Re: [xsl] Date Difference, Chris Burdess |
Re: [xsl] Date Difference, David Carlisle | Date | Re: [xsl] Date Difference, David Carlisle |
Month |