开发者

XSLT 1.0 how increment a date

开发者 https://www.devze.com 2023-02-28 12:23 出处:网络
UPDATE: Cannot use any EXSLT extensions. Also I\'m using date in two different places and I only want to update one of them and not both.

UPDATE: Cannot use any EXSLT extensions. Also I'm using date in two different places and I only want to update one of them and not both.

I need to increment a date in my XSLT transformation. I'm using XSLT 1.0.

In source XML I have a date like this

<XML>
    <Date>4/22/2011 3:30:43 PM</Date>
</XML>

Then I need to add 10 years to the output. Like this

<Output>
   <Odate>4/22/2011 3:30:43 PM</Odate>
   <Cdate>4/22/2021 3:30:43 PM</Cdate>
</Output>

How this 开发者_如何学JAVAcan be done in XSLT 1.0. Thanks in advance.


The following is no general date arithmetic implementation but might suffice to increment the year part:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:param name="year-inc" select="10"/>

<xsl:template match="XML">
  <Output>
    <xsl:apply-templates/>
  </Output>
</xsl:template>

<xsl:template match="Date">
  <xsl:variable name="d0" select="substring-before(., '/')"/>
  <xsl:variable name="d1" select="substring-before(substring-after(., '/'), '/')"/>
  <xsl:variable name="d2" select="substring-after(substring-after(., '/'), '/')"/>
  <xsl:variable name="new-year" select="substring($d2, 1, 4) + $year-inc"/>
  <Cdate>
    <xsl:value-of select="concat($d0, '/', $d1, '/', $new-year, substring($d2, 5))"/>
  </Cdate>
</xsl:template>

</xsl:stylesheet>


Depends a little how pernickety you want to be, e.g. what's the date 10 years after 29 Feb 2004? There are a number of useful XSLT 1.0 date-handling routines you can download at www.exslt.org, I think they include both a parse-date template which will convert your US-format date into a standard ISO date, date arithmetic templates which will allow you to add a duration to an ISO-format date, and a format-date function that will turn it back into US format.


I have figured it with the help of @Martin. I extend on @Martin's code and only called the template when I need to modify the date.

XSLT:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="year-inc" select="10"/>

  <xsl:template match="XML">
    <Output>
      <Odate>
        <xsl:value-of select="Date"/>
      </Odate>
      <Cdate>
        <xsl:call-template name="increment"/>
      </Cdate>
    </Output>
  </xsl:template>

  <xsl:template name="increment">
    <xsl:variable name="d0" select="substring-before(Date, '/')"/>
    <xsl:variable name="d1" select="substring-before(substring-after(Date, '/'), '/')"/>
    <xsl:variable name="d2" select="substring-after(substring-after(Date, '/'), '/')"/>
    <xsl:variable name="new-year" select="substring($d2, 1, 4) + $year-inc"/>
    <xsl:value-of select="concat($d0, '/', $d1, '/', $new-year, substring($d2, 5))"/>
  </xsl:template>

</xsl:stylesheet>

Output:

<?xml version="1.0" encoding="utf-8"?>
<Output>
  <Odate>4/22/2011 3:30:43 PM</Odate>
  <Cdate>4/22/2021 3:30:43 PM</Cdate>
</Output>
0

精彩评论

暂无评论...
验证码 换一张
取 消