 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

November 30th, 2009, 01:22 AM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 33
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Add DateTime and duration confused
Hi,
I'm using xslt 2.0
How can I add dateTime and duration?
I would like to check if the data start for example at 15:00:00.
my idea was to add the start and data duration.
my xml data
Code:
<mydatacollection>
<data_header>
<start>2010-02-11T00:00:00</start>
<data_header>
<data id="ABC123">
<duration>00:01:00:00</duration>
</data>
</mydatacollection>
so far I have this and try to add the duration with exslt and it's show me an error "unknown function".
I think I'm a bit (maybe more) confused  .
Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:str="http://exslt.org/strings"
version="2.0">
...
<xsl:template match="data">
<xsl:element name="test">
<xsl:variable name="dur" select="/duration"></xsl:variable>
<xsl:variable name="tokens"><xsl:value-of select="str:split($dur)"/></xsl:variable>
<xsl:variable name="hour"><xsl:value-of select="tokens/token"/></xsl:variable>
<xsl:variable name="minute"><xsl:value-of select="tokens/token"/></xsl:variable>
<xsl:variable name="second"><xsl:value-of select="tokens/token"/></xsl:variable>
<xsl:value-of select="date:add(//data_header/start,$hour)"></xsl:value-of>
</xsl:element>
</xsl:template>
Can someone point me on how can I add duration and timedate.
Thanks,
|
|

November 30th, 2009, 08:16 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
The arithmetic operations on dateTime/durations that XPath 2.0 allows are defined here: http://www.w3.org/TR/xquery-operator...ime-arithmetic
So you can add a dayTime duration to a dateTime, and you can add a yearMonthDuration to a dateTime.
An example would be
Code:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0"
exclude-result-prefixes="xs">
<xsl:template name="main">
<xsl:value-of select="xs:dateTime('2010-02-11T00:00:00') + xs:dayTimeDuration('P0DT1H')"/>
</xsl:template>
</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

November 30th, 2009, 09:37 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
You don't need EXSLT for this if you're using XSLT 2.0 - you can just use the "+" operator, so long as the operands are the right type.
Note that the format for durations is PT1H, not 00:01:00:00. If your input has to be in this format, you could treat 01:00:00 as an xs:time value, and then subtract xs:time('00:00:00') to get the interval as a duration.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

November 30th, 2009, 11:38 AM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 33
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Thanks for the tips :)
Unfortunately I can't change the duration format, it has to be "00:00:00:00"
So I will try to truncate the last ":00"
|
|

November 30th, 2009, 05:55 PM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 33
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Code:
<xsl:element name="dur">
<xsl:variable name="dur" select="fn:substring(duration,0,9)"/>
<xsl:value-of select="xs:time($dur) - xs:time('00:00:00')"></xsl:value-of>
</xsl:element>
but the xs:time($dur) result as an error "Error in XPath 2.0 expression Cast failed, invalid lexical value - xs:time"
Is it because fn:substring return as a string with " ?
When I tried with for example <xsl:value-of select="xs:time('00:04:00') - xs:time('00:00:00')"></xsl:value-of>
it was ok. Is " ' " make a difference in xs:time?
Thanks so much.
|
|

November 30th, 2009, 06:19 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I think you're guessing that substring() in XPath behaves like substring() in Java. It doesn't. You want 8 characters starting at position 1, which is substring(x, 1, 8). (Or do you? I don't know your data, but my guess would have been 8 characters starting at position 4).
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

November 30th, 2009, 07:01 PM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 33
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Yes, I missed that detail that xpath start the character from 1. Thanks for that.
but It still show the same error.
My duration is for example "00:40:00:00", so I was thinking to remove the last ":00" and cast as xs:time as your tips before. I've checked the output of $dur is "00:40:00" just as I wanted. but when I cast to xs:time($dur) it came out as "Error in XPath 2.0 expression Cast failed, invalid lexical value - xs:time"
|
|

November 30th, 2009, 07:07 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Can't see the reason for this error from the information provided. Please post a complete (but minimal) XML and XSLT that illustrate the problem.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

November 30th, 2009, 07:14 PM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 33
Thanks: 2
Thanked 0 Times in 0 Posts
|
|
Here is my data
Code:
<mydatacollection>
<data_header>
<start>2010-02-11T00:00:00</start>
<data_header>
<data id="ABC123">
<duration>00:01:00:00</duration>
</data>
</mydatacollection>
Here is my xslt
Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
version="2.0">
<xsl:template match="data">
<xsl:element name="dur">
<xsl:variable name="dur" select="fn:substring(duration,1,8)"/>
<xsl:value-of select="xs:time($dur)"></xsl:value-of> <!-- the error came up here -->
</xsl:element>
<xsl:element name="test">
<xsl:variable name="dur" select="fn:substring(duration,0,9)"/>
<xsl:value-of select="xs:dateTime(ancestor-or-self::node()/mydatacollection/data_header/start) + xs:time($dur)"></xsl:value-of>
</xsl:element>
</xsl:template>
Thanks,
|
|

November 30th, 2009, 07:30 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Neither your XML nor your XSLT is well-formed, which doesn't create a very favourable impression. When I make the obvious corrections, and run with Saxon, I get a different error from yours:
XPTY0004: Arithmetic operator is not defined for arguments of types (xs:dateTime, xs:time)
I thought we had already explained to you that you need to convert the time to a duration by subtracting xs:time('00:00:00'). So I changed the expression to
Code:
<xsl:value-of select="xs:dateTime(ancestor-or-self::node()/mydatacollection/data_header/start) + (xs:time($dur) - xs:time('00:00:00'))">
and it now runs correctly. I can't explain the error you reported - check that you are using the latest version of your XSLT processor and if it still fails, raise the problem with the vendor.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|
The Following User Says Thank You to mhkay For This Useful Post:
|
|
|
 |