views:

42

answers:

1

I am using some code to subtract one date from another using XSLT 2.0:

<xsl:template match="moveInDate">
    <xsl:value-of select="current-date() - xs:date(.)"/>
</xsl:template>

This works, however it leaves me with an answer of P2243D, which I assume corresponds to a "Period of 2243 Days" (which is correct in terms of the math).

Since I only need the number of days, not the P and the D, I know I could use substring or something similar, but as a newbie to XSLT, I'm curious if there is a better, more elegant way to do this than simple string manipulation.

+5  A: 

You could simply use fn:days-from-duration() to get the duration as a xs:integer:

days-from-duration($arg as xs:duration?) as xs:integer?

Returns an xs:integer representing the days component in the canonical lexical representation of the value of $arg. The result may be negative.

See the XQuery 1.0 and XPath 2.0 Functions and Operators specification for more information.

In your case:

<xsl:template match="moveInDate">
    <xsl:value-of select="days-from-duration(current-date() - xs:date(.))"/>
</xsl:template>

Hope this helps!

EDIT: You could also do it the way you say, with substring processing. But as you point out, it's not prefered. If you for some reason would like to do something similar you need to think of the data types. The result of current-date() - xs:date(.) is returned as xs:duration which cannot be processed by the substring functions without being casted:

<xsl:template match="moveInDate">
  <xsl:variable name="dur" select="(current-date() - xs:date(.)) cast as xs:string"/>
  <xsl:value-of select="substring-before(substring-after($dur, 'P'), 'D')"/>
</xsl:template>
Per T
@Per T: +1 Good and extend answer! Also for linking specs.
Alejandro
Lovely answer, thanks a lot. Now, if I can just figure out my next question: How to answer this myself next time...
mlissner