I have an XML
file which includes some date in it as starting and ending point as:
我有一个XML文件,其中包含一些日期作为起点和终点:
<start time="2016-02-21T00:59:06+02:00"/>
.....
.....
<end time="2016-02-22T02:24:38+02:00"/>
My aim is to fing the difference between two attributes times
in XSLT
file. May I ask your helps. I new to XSLT
.
我的目标是在XSLT文件中找出两个属性时间之间的差异。我可以问你的帮助吗?我是XSLT的新手。
Thanks in advance!!
提前致谢!!
Update:
Thanks a lot for the answers which you have provided here. May I ask you if I want to use XSLT 1.0 then what would be the answer?
非常感谢您在这里提供的答案。我可以问你是否要使用XSLT 1.0那么答案是什么?
4 个解决方案
#1
3
I am getting the error: ...
xsl:version: only 1.0 features are supported
我收到错误:... xsl:version:仅支持1.0个功能
Here's a purely XSLT 1.0 solution:
这是一个纯粹的XSLT 1.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="event">
<xsl:variable name="start">
<xsl:call-template name="dateTime-to-seconds">
<xsl:with-param name="dateTime" select="start/@time" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="end">
<xsl:call-template name="dateTime-to-seconds">
<xsl:with-param name="dateTime" select="end/@time" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="duration" select="$end - $start" />
<xsl:variable name="d" select="floor($duration div 86400)"/>
<xsl:variable name="t" select="$duration mod 86400"/>
<xsl:variable name="h" select="floor($t div 3600)"/>
<xsl:variable name="r" select="$t mod 3600"/>
<xsl:variable name="m" select="floor($r div 60)"/>
<xsl:variable name="s" select="$r mod 60"/>
<xsl:copy>
<xsl:copy-of select="name"/>
<duration>
<xsl:value-of select="$d"/>
<xsl:text> days, </xsl:text>
<xsl:value-of select="$h"/>
<xsl:text> hours, </xsl:text>
<xsl:value-of select="$m"/>
<xsl:text> minutes and </xsl:text>
<xsl:value-of select="$s"/>
<xsl:text> seconds</xsl:text>
</duration>
</xsl:copy>
</xsl:template>
<xsl:template name="dateTime-to-seconds">
<xsl:param name="dateTime"/>
<xsl:variable name="date" select="substring-before($dateTime, 'T')" />
<xsl:variable name="time" select="substring-after($dateTime, 'T')" />
<xsl:variable name="local-time" select="substring($time, 1, string-length($time) - 6)" />
<xsl:variable name="offset" select="substring-after($time, $local-time)" />
<xsl:variable name="year" select="substring($date, 1, 4)" />
<xsl:variable name="month" select="substring($date, 6, 2)" />
<xsl:variable name="day" select="substring($date, 9, 2)" />
<xsl:variable name="hour" select="substring($local-time, 1, 2)" />
<xsl:variable name="minute" select="substring($local-time, 4, 2)" />
<xsl:variable name="second" select="substring($local-time, 7)" />
<xsl:variable name="offset-sign" select="1 - 2 * starts-with($offset, '-')" />
<xsl:variable name="offset-hour" select="substring($offset, 2, 2) * $offset-sign" />
<xsl:variable name="offset-minute" select="substring($offset, 5, 2) * $offset-sign" />
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12*$a - 3"/>
<xsl:variable name="jd" select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
<xsl:value-of select="86400*$jd + 3600*$hour + 60*$minute + $second - 3600*$offset-hour - 60*$offset-minute" />
</xsl:template>
</xsl:stylesheet>
#2
2
I checked and found out that I can use XSLT version 2. Also by times/dates I meant different in dates, which means how many days, hours, minutes ans seconds.
我检查并发现我可以使用XSLT版本2.此外,按时间/日期我的日期不同,这意味着多少天,小时,分钟和秒。
Then I would suggest you do it along the lines of:
然后我建议你按照以下方式去做:
<xsl:variable name="duration" select="xs:dateTime(end/@time) - xs:dateTime(start/@time)" />
<xsl:value-of select="days-from-duration($duration)"/>
<xsl:text> days, </xsl:text>
<xsl:value-of select="hours-from-duration($duration)"/>
<xsl:text> hours, </xsl:text>
<xsl:value-of select="minutes-from-duration($duration)"/>
<xsl:text> minutes and </xsl:text>
<xsl:value-of select="seconds-from-duration($duration)"/>
<xsl:text> seconds</xsl:text>
Full demo: http://xsltransform.net/jz1PuNG
完整演示:http://xsltransform.net/jz1PuNG
#3
1
Your dates are in ISO format so in XSLT 2.0 you can do
您的日期是ISO格式,所以在XSLT 2.0中你可以做到
xs:dateTime(end/@time) - xs:dateTime(start/@time)
The result is an xs:dayTimeDuration
, which you can convert to seconds (for example) by doing
结果是xs:dayTimeDuration,您可以通过执行转换为秒(例如)
(xs:dateTime(end/@time) - xs:dateTime(start/@time)) div xs:dayTimeDuration('PT1S')
#4
0
Using XSLT3.0 compliant Saxon processor, I use this (should work for 2.0 also):- xs is xsd schema
使用符合XSLT3.0的Saxon处理器,我使用它(也适用于2.0): - xs是xsd schema
<xsl:variable name="to" select="...to node value"/>
<xsl:variable name="from" select"...from node value"/>
<xsl:value-of select="days-from-duration(xs:dayTimeDuration(xs:date($to) - xs:date($from)))"/>
#1
3
I am getting the error: ...
xsl:version: only 1.0 features are supported
我收到错误:... xsl:version:仅支持1.0个功能
Here's a purely XSLT 1.0 solution:
这是一个纯粹的XSLT 1.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="event">
<xsl:variable name="start">
<xsl:call-template name="dateTime-to-seconds">
<xsl:with-param name="dateTime" select="start/@time" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="end">
<xsl:call-template name="dateTime-to-seconds">
<xsl:with-param name="dateTime" select="end/@time" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="duration" select="$end - $start" />
<xsl:variable name="d" select="floor($duration div 86400)"/>
<xsl:variable name="t" select="$duration mod 86400"/>
<xsl:variable name="h" select="floor($t div 3600)"/>
<xsl:variable name="r" select="$t mod 3600"/>
<xsl:variable name="m" select="floor($r div 60)"/>
<xsl:variable name="s" select="$r mod 60"/>
<xsl:copy>
<xsl:copy-of select="name"/>
<duration>
<xsl:value-of select="$d"/>
<xsl:text> days, </xsl:text>
<xsl:value-of select="$h"/>
<xsl:text> hours, </xsl:text>
<xsl:value-of select="$m"/>
<xsl:text> minutes and </xsl:text>
<xsl:value-of select="$s"/>
<xsl:text> seconds</xsl:text>
</duration>
</xsl:copy>
</xsl:template>
<xsl:template name="dateTime-to-seconds">
<xsl:param name="dateTime"/>
<xsl:variable name="date" select="substring-before($dateTime, 'T')" />
<xsl:variable name="time" select="substring-after($dateTime, 'T')" />
<xsl:variable name="local-time" select="substring($time, 1, string-length($time) - 6)" />
<xsl:variable name="offset" select="substring-after($time, $local-time)" />
<xsl:variable name="year" select="substring($date, 1, 4)" />
<xsl:variable name="month" select="substring($date, 6, 2)" />
<xsl:variable name="day" select="substring($date, 9, 2)" />
<xsl:variable name="hour" select="substring($local-time, 1, 2)" />
<xsl:variable name="minute" select="substring($local-time, 4, 2)" />
<xsl:variable name="second" select="substring($local-time, 7)" />
<xsl:variable name="offset-sign" select="1 - 2 * starts-with($offset, '-')" />
<xsl:variable name="offset-hour" select="substring($offset, 2, 2) * $offset-sign" />
<xsl:variable name="offset-minute" select="substring($offset, 5, 2) * $offset-sign" />
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12*$a - 3"/>
<xsl:variable name="jd" select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
<xsl:value-of select="86400*$jd + 3600*$hour + 60*$minute + $second - 3600*$offset-hour - 60*$offset-minute" />
</xsl:template>
</xsl:stylesheet>
#2
2
I checked and found out that I can use XSLT version 2. Also by times/dates I meant different in dates, which means how many days, hours, minutes ans seconds.
我检查并发现我可以使用XSLT版本2.此外,按时间/日期我的日期不同,这意味着多少天,小时,分钟和秒。
Then I would suggest you do it along the lines of:
然后我建议你按照以下方式去做:
<xsl:variable name="duration" select="xs:dateTime(end/@time) - xs:dateTime(start/@time)" />
<xsl:value-of select="days-from-duration($duration)"/>
<xsl:text> days, </xsl:text>
<xsl:value-of select="hours-from-duration($duration)"/>
<xsl:text> hours, </xsl:text>
<xsl:value-of select="minutes-from-duration($duration)"/>
<xsl:text> minutes and </xsl:text>
<xsl:value-of select="seconds-from-duration($duration)"/>
<xsl:text> seconds</xsl:text>
Full demo: http://xsltransform.net/jz1PuNG
完整演示:http://xsltransform.net/jz1PuNG
#3
1
Your dates are in ISO format so in XSLT 2.0 you can do
您的日期是ISO格式,所以在XSLT 2.0中你可以做到
xs:dateTime(end/@time) - xs:dateTime(start/@time)
The result is an xs:dayTimeDuration
, which you can convert to seconds (for example) by doing
结果是xs:dayTimeDuration,您可以通过执行转换为秒(例如)
(xs:dateTime(end/@time) - xs:dateTime(start/@time)) div xs:dayTimeDuration('PT1S')
#4
0
Using XSLT3.0 compliant Saxon processor, I use this (should work for 2.0 also):- xs is xsd schema
使用符合XSLT3.0的Saxon处理器,我使用它(也适用于2.0): - xs是xsd schema
<xsl:variable name="to" select="...to node value"/>
<xsl:variable name="from" select"...from node value"/>
<xsl:value-of select="days-from-duration(xs:dayTimeDuration(xs:date($to) - xs:date($from)))"/>