将秒转换为持续时间XPATH

时间:2014-03-11 23:34:11

标签: xml xpath

如何将时间(以秒为单位)转换为持续时间字符串,例如:

2 Days 10 Hours 10 Seconds

3 个答案:

答案 0 :(得分:3)

你真的需要说明你是使用XPath 1.0还是2.0 - 答案会有很大差异。

在XPath 2.0中,您可以使用

转换为持续时间
$seconds * xs:dayTimeDuration('PT1S')

然后你可以使用

提取持续时间的部分
days-from-duration($d)
hours-from-duration($d)

答案 1 :(得分:1)

如果您不介意在输出中看到零,则可以使用整数除法和模运算将值分为小时,分钟,秒和天:

秒数是模数为60的输入值。(丢弃除"秒针&#34之外的所有内容;)

分钟数是输入值除以60,截断为整数,然后取模60.(将秒数重新缩放至分钟,丢弃除"分针&#34之外的所有内容;)

小时数是输入值除以3600(60 * 60),截断为整数,然后取模24(将秒数重新缩放为小时等)

天数......你现在应该看到模式...除以86400(24 * 60 * 60)并截断为整数。由于我们不打算将其划分为数月和数年,我们可以在此停止。

未经测试但应该有效:

concat(floor($NUMSEC div 86400),' Days ',floor($NUMSEC div 3600) mod 24,' Hours ',
  floor($NUMSEC div 60) mod 60,' Minutes ',$NUMSEC mod 60,' Seconds'

其中$ NUMSEC是包含总秒数的XPath变量或返回该整数的XPath表达式。是的,后者效率低下,但这就是你尝试将其作为单个表达式所获得的。

如果你想要压制出零的部分并完全在XPath 1.0中完成......我认为这是可能的,但坦率地说,这比我想要处理的更糟糕所以我&# 39;留下它作为读者的练习。

(XPath 2.0将持续时间识别为数据类型,并具有访问持续时间组件的功能,因此这是另一种选择。要将整数转换为持续时间,请将其乘以隐含的时间单位,例如PTS1。)

但是:可能不等于好主意。除非有理由你必须在XPath中执行此操作(尝试使其作为更通用的宏语言运行,或许?)我通常建议只使用XPath来检索值和使用您从中启动XPath的任何语言进行转换。

如果你确实需要一种擅长格式化数据以及从XML中检索数据的表达式语言,我建议你看看你是否可以在XQuery上找到你的爪子。 XQuery在某种意义上是XPath 2.0的超集,它增加了与XSLT 2.0相同的大部分功能,但是以查询表达式的形式而不是XML语法。

答案 2 :(得分:0)

您无法直接使用XML和XPath执行此操作,这是您的问题似乎建议的内容。但是,假设您将自己限制在XML技术上,可以使用XSL来实现:

<xsl:template name="duration">
  <xsl:param name="seconds" />
  <xsl:choose>
    <xsl:when test="number($seconds) >= 86400">
      <xsl:value-of select="floor(number($seconds) div 86400)" />
      <xsl:text> day(s) </xsl:text>
      <xsl:call-template name="duration">
        <xsl:with-param name="seconds" select="number($seconds) mod 86400" />       
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="number($seconds) >= 3600">
      <xsl:value-of select="floor(number($seconds) div 3600)" />
      <xsl:text> hour(s) </xsl:text>
      <xsl:call-template name="duration">
        <xsl:with-param name="seconds" select="number($seconds) mod 3600" />
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="number($seconds) >= 60">
      <xsl:value-of select="floor(number($seconds) div 60)" />
      <xsl:text> minute(s) </xsl:text>
      <xsl:call-template name="duration">
        <xsl:with-param name="seconds" select="number($seconds) mod 60" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="number($seconds)" />
      <xsl:text> second(s) </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

(XSLT 2.0有个性,所以你可以取消发言权(。)。)