【问题标题】:xslt - subtracting daysxslt - 减去天数
【发布时间】:2023-04-03 07:49:02
【问题描述】:

xslt 是否可以获取一个日期字段并从中减去 N 天?如果有,可以举个例子吗?

【问题讨论】:

  • 您使用的是什么 XSLT 处理器?
  • XSLT 1.0 还是 XSLT 2.0?日期格式是什么?
  • 好问题,+1。请参阅我的答案以获得完整的 XSLT 2.0 解决方案。

标签: xslt date math


【解决方案1】:

这是一个演示如何在 XSLT 2.0 中执行此操作:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:variable name="vToday" select="current-date()"/>

  Today is: <xsl:sequence select="$vToday"/>
  30 days ago it was: <xsl:sequence select=
    "$vToday -30*xs:dayTimeDuration('P1D')"/>
  365 days ago it was: <xsl:sequence select=
    "$vToday -365*xs:dayTimeDuration('P1D')"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 XML 文档(未使用)时,会产生所需的正确结果:

  Today is: 2010-10-07-07:00
  30 days ago it was: 2010-09-07-07:00
  365 days ago it was: 2009-10-07-07:00

【讨论】:

  • FYI...&lt;xsl:variable name="vToday" select="current-date()"/&gt; 导致 Firefox 25 和 Chrome 30 中出现空白页。Firefox 给出Component returned failure code: 0x80600005 [nsIXSLTProcessor.importStylesheet] 的控制台错误。糟糕,显然您必须在 xsl:stylesheet 中指定 version="2.0"。我使用的是 1.0 版。
  • FYI2... 即使指定了version=2.0,Chrome 30 也会生成一个空白页。不过,Firefox 25 确实显示了结果。
  • @double,没有浏览器支持 XSLT 2.0。您可以尝试使用 SaxonCE 1.1
【解决方案2】:

是的,使用 XSLT 2.0 是可能的,而且非常容易做到。

有很多Date/Time/Duration functions in XPATH 2.0,它们是XSLT 2.0的一部分。

此示例从日期 2010-01-01 中减去 1 天以生成 2009-12-31:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
  <xsl:value-of select="xs:date('2010-01-01') - xs:dayTimeDuration('P1D')" />
</xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案3】:

    嗯,XSLT 可以拆分字符串和解析数字,所以是的,这将是“可能的”。

    但是,如果您可以使用扩展功能并用另一种语言实现它,那将更加容易和高效。但是,它是否以及如何工作取决于所使用的 XSLT 引擎。

    EXSLT 可能有你需要的一切:http://www.exslt.org/date/functions/add/index.html

    【讨论】:

      【解决方案4】:

      我可以看到所有提到的解决方案都适用于 XSLT 2.0。我对使用 EXSLT date:add

      的 XSLT 1.0 有类似的解决方案

      示例:考虑要减去的天数是 365,我们需要它作为默认开始日期。在这种情况下,我们必须以 xs:dayTimeDuration 格式提供 365 天的持续时间,即“-P365D”。

      请在下面找到代码。

      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:date="http://exslt.org/dates-and-times"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      extension-element-prefixes="date xs"
      exclude-result-prefixes="date xs" version="1.0">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" />
      
          <xsl:template match="/">
            <xsl:variable name="vCurrDate" select="date:date-time()"/>
            <xsl:variable name="vDefaultStDate" select="(date:add($vCurrDate, '-P365D'))"/>
          </xsl:template>
      </xsl:stylesheet>
      

      【讨论】:

      【解决方案5】:
      <xsl:template name="dim" >
      
        <xsl:param name="y" />
        <xsl:param name="m"/>
      
        <xsl:choose>
           <xsl:when test="($m=1 or $m=3 or $m=5 or $m=7 or $m=8 or $m=10 or $m=12)" >
                31  
          </xsl:when>
          <xsl:when test="$m&gt;2">
               30 
         </xsl:when>
          <xsl:when test="($m=2) and (not($y mod 4=0)) or ($y mod 100=0) and (not($y mod 400=0))">
            28  
          </xsl:when>
          <xsl:otherwise>
             29
          </xsl:otherwise>
        </xsl:choose>
      
      </xsl:template>
      
      
      <xsl:template name="minusdays">
      <xsl:param name="year" />
      <xsl:param name="month" />
      <xsl:param name="day"/>
      <xsl:param name="days"/>
      <xsl:variable name="lm" select="number($month)-1+number($month=1)*12"/>
      
      <xsl:variable name="lmdays">
          <xsl:call-template name="dim">
             <xsl:with-param name="y" select="$year"/>
             <xsl:with-param name="m" select="$lm"/>
          </xsl:call-template>
      </xsl:variable>
      
      <xsl:choose>
          <xsl:when test="$days&lt;$day">
              <xsl:value-of select="$year"/>
             <xsl:if test="number($month)&lt;10">0</xsl:if>
             <xsl:value-of select="$month"/>
             <xsl:if test="($day - $days)&lt;10">0</xsl:if>
             <xsl:value-of select="$day - $days"/>
          </xsl:when>
          <xsl:otherwise>
              <xsl:call-template name="minusdays">
                 <xsl:with-param name="year" 
                 select="number($year)-number($month=1)"/>
               <xsl:with-param name="month" select="$lm" />
               <xsl:with-param name="day" select="$lmdays"/>
               <xsl:with-param name="days" select="$days - $day" />    
             </xsl:call-template>
          </xsl:otherwise>
      </xsl:choose> 
      
      </xsl:template>
      

      【讨论】:

        猜你喜欢
        • 2021-01-10
        • 1970-01-01
        • 1970-01-01
        • 2017-09-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多