XSLT 1.0 Get Current DateTime

54,077

Solution 1

Playing with DateTime is not possible with XSLT 1.0 alone .. In a similar situations I took help of scripting .. (C#)

Sample XML:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <Apple>2011-12-01T16:33:33Z</Apple>
</root>

Sample XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:cs="urn:cs">
  <xsl:output method="xml" indent="yes"/>
  <msxsl:script language="C#" implements-prefix="cs">
    <![CDATA[
      public string datenow()
     {
        return(DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"));
     }
     ]]>
    </msxsl:script>
      <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Apple">
      <xsl:copy>
      <xsl:value-of select="cs:datenow()"/>
      </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Resulting Output:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <Apple>2012-02-22T18:03:12Z</Apple>
</root>

The script may reside in a same file (like I have it in my sample XSLT code) or if the code triggering XSLTransformation is C# then move the same code in the calling place :)

Solution 2

It's better to pass current datetime from your XML engine. Declare <xsl:param name="current-datetime"/> in your xsl:stylesheet, and pass the value from processor.

Solution 3

You'll better pass the current data as an input / xsl:param to the template.

The XSLT aims to be purely functional language; that is, all templates / functions should conform to e.g. the following condition: If a pure function is called with parameters that cause no side-effects, the result is constant with respect to that parameter list (sometimes called referential transparency), i.e. if the pure function is again called with the same parameters, the same result will be returned (this can enable caching optimizations such as memoization).

Although there are workarounds on this (as InfantPro'Aravind' pointed out), it is not recommended to do such things; by doing it, you're ruining one of the most significant XSLT benefits.

Share:
54,077
Mike
Author by

Mike

Updated on October 22, 2020

Comments

  • Mike
    Mike over 3 years

    I have a node in my XML file containing the following:

    <Apple>2011-12-01T16:33:33Z</Apple>

    I wish to take this line and replace it with the current date and time using the same format as shown above.

    YYYY-MM-DDTHH:MM:SSZ

    The node is within a namespace declared as 'x'

  • Mike
    Mike over 12 years
    I would uprate the solution but don't have enough rep to do so :(
  • Dimitre Novatchev
    Dimitre Novatchev over 12 years
    @infantprogrammer'Aravind': +1 for a correct answer. Do note, however, that use of inline <msxsl:script> isn't recommended in cases of a server system under heavy use and in such case it is better to use an extension object and its public methods. The issue with inline <msxsl:script> is that XslCompiledTransform generates code for the script dynamically, in dynamic assemblies. If a transformation is repeatedly performed then the same scripts generate new dynamic dlls -- over and over again -- this eventually consumes almost all of the available memory and requires recycling.
  • InfantPro'Aravind'
    InfantPro'Aravind' over 12 years
    @DimitreNovatchev, really valuable comment :) I indeed faced an issue due to this behavior of code. :) a clean up tool used to delete junk dlls, which caused my transformation process to halt in the middle .. later as per your suggestion when I moved that code to new class under calling code helped resolving the issue :)
  • Jay
    Jay almost 9 years
    Note: Not all xsl interpreters support C# scripting.
  • dtroy
    dtroy over 8 years
    You might want to use DateTime.UtcNow. DateTime.Now will return local time and you're formatting it as UTC.