xslt - subtracting days

前端 未结 5 1896
醉话见心
醉话见心 2020-12-15 09:26

Is it possible with xslt to take a date field and subtract N number of days from it? If so, can you please provide me an example?

相关标签:
5条回答
  • 2020-12-15 10:08

    Yes, with XSLT 2.0 it is possible, and very easy to do.

    There are a lot of Date/Time/Duration functions in XPATH 2.0, which are part of XSLT 2.0.

    This example subtracts 1 day from the date 2010-01-01 to produce 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>
    
    0 讨论(0)
  • 2020-12-15 10:13

    Here is a demonstration how to do this in 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>
    

    when this transformation is applied on any XML document (not used), the wanted, correct result is produced:

      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
    
    0 讨论(0)
  • 2020-12-15 10:20
    <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>
    
    0 讨论(0)
  • 2020-12-15 10:21

    Well, XSLT can split strings and parse numbers, so yes, it would be "possible".

    However, it would be much easier and efficient if you could use extension functions and implement that in another language. If and how that works depends on the XSLT engine used, however.

    EXSLT may have everything you need: http://www.exslt.org/date/functions/add/index.html

    0 讨论(0)
  • 2020-12-15 10:23

    I can see that all the mentioned solutions are for XSLT 2.0. I have similar solution for XSLT 1.0 using EXSLT date:add

    Example: Consider that the number of days to be subtracted is 365 and we need it as the default start date. In this case, we have to provide the duration 365 days in xs:dayTimeDuration format i.e. '-P365D'.

    Please find below the code.

    <?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>
    
    0 讨论(0)
提交回复
热议问题