-----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
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--