XSLT2.0 Transformation error while converting input date to xs:dateTime and formatting the date, Also increment the date
apache-camel, xslt-2.0
Solution
The reason is both the processors I was using to transform were XSLT1.0 processors.
The online tool which i mentioned: http://www.freeformatter.com/xsl-transformer.html is not XSLT2.0 processor. Also my application which is using Apache Camel has default XSLT processor 1.0. Using a `XSLT 2.0 processor` resolves the issue. So the error is related to using with a XSLT 1.0 processor
Also, just declaring `<xsl:stylesheet version="2.0"` has no meaning that you are using XSLT 2.0 processor. This was another wrong [illogical] assumption i had!
To run `xs:date` or `xs:dateTime` , I should use `XSLT 2.0` processor
What i did in my Apache Camel configuration :
Added `Saxon 9.4.0.1` as dependency [as jar or pom.xml dependency], and in my camel route, i made the changes:
<route..
<from uri=
<to uri="xslt:stylesheets/test.xslt?transformerFactoryClass=net.sf.saxon.TransformerFactoryImpl" />
Problem
I am trying to convert a date to a valid `dateTime` format, and then format the date. However i am running into transformation error after including `xs:dateTime` . XML: ``` <?xml version="1.0" encoding="UTF-8"?> <book> <title>doublebell</title> <timestamp>02/06/2014 13:51:09</timestamp> </book> ``` XSLT: ``` <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="xml" version="1.0" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <myentity> <label> <xsl:value-of select="book/title" /> </label> <date> <xsl:apply-templates select="book/timestamp" /> </date> </myentity> </xsl:template> <xsl:template match="book/timestamp"> <xsl:variable name="datestr"> <xsl:value-of select="concat(substring(., 7, 4), '-', substring(., 4, 2), '-', substring(., 1, 2), 'T', substring(., 12))" /> </xsl:variable> <!--<xsl:value-of select="$datestr" /> --> <!-- prints 2014-06-02T13:51:09 --> <xsl:variable name="date1" as="xs:dateTime" select="xs:dateTime($datestr)" /> <xsl:variable name="formatteddate1"> <xsl:value-of select="format-dateTime($date1, '[Y0001]-[M01]-[D01]')" /> </xsl:variable> <xsl:value-of select="$formatteddate1" /> </xsl:template> </xsl:stylesheet> ``` I am getting XSLT transformation error while using "xs:dateTime". I could not figure out where i am doing wrong I am trying in the tool: http://www.freeformatter.com/xsl-transformer.html PS: I can format the date just by using `substring()` and `concat()` functions. But i like to get the `date` in `dateTime` format so that i can increment the date by one day. Hence using the `xs:dateTime()` function to get the data in valid `dateTime` format. Edit: What i mean by valid `dateTime` format, is something of the datatype 'date' [like datatype String, number etc] Please throw some pointers on what i am doing wrong Update: Even when i try this simple XSLT [based on SO - https://stackoverflow.com/questions/3885292/xslt-subtracting-days] XSLT: ``` <?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" xmlns:fn="http://www.w3.org/xpath-functions"> <xsl:template match="/"> <xsl:value-of select="xs:date('2010-01-01')" /> </xsl:template> </xsl:stylesheet> ``` I am getting error. This time i also tried from my Apache Camel XSLT processor Error details: `The first argument to the non-static Java function 'date' is not a valid object reference. javax.xml.transform.TransformerException: The first argument to the non-static Java function 'date' is not a valid object reference.` Update 1: Looks like this has something to do with the XSLT transformation `processor` http://www.freeformatter.com/xsl-transformer.html is not XSLT2.0 processor, and my Apache Camel default processor is 1.0, and to process `XSLT2.0`, i need to explicitly mention transformer as some `XSLT2.0` processor like `Saxon 9.4.0.1` primary issue resolved update 2 and update 3 are formatting date and increment date Update 2: [i am not posting in a different thread as this is inter-related] Finally i need to add a day to the input date, that was the reason why i went for `xs:dateTime`. I am placing the code i tried, in case it will be useful for someone else in future. This time i am going for `<xsl:call-template />` XML: ``` <?xml version="1.0" encoding="UTF-8"?> <book> <title>doublebell</title> <timestamp>20131217-13:04:59-UTC</timestamp> </book> ``` XSLT: ``` <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="/"> <date> <xsl:call-template name="formatdate"> <xsl:with-param name="timestampstring" select="book/timestamp" /> </xsl:call-template> </date> </xsl:template> <xsl:template name="formatdate"> <xsl:param name="timestampstring" /> <!-- date is 20131217-13:04:59-UTC --> <xsl:variable name="datestr"> <xsl:value-of select="concat(substring($timestampstring, 1, 4), '-', substring($timestampstring, 5, 2), '-', substring($timestampstring, 7, 2), 'T', substring($timestampstring,10, 8))" /> </xsl:variable> date: <xsl:value-of select="$datestr" /><!-- date is 2013-12-17T13:04:59 --> date in custom format: <xsl:value-of select="format-dateTime($datestr, '[Y0001]-[M01]-[D01]')" /> date+1: <xsl:value-of select="xs:dateTime($datestr) + xs:dayTimeDuration('P1D')" /> <!-- add one day --> date+3: <xsl:value-of select="xs:dateTime($datestr) + xs:dayTimeDuration('P3D')" /> <!-- add three days --> </xsl:template> </xsl:stylesheet> ``` Output ``` date: 2013-12-17T13:04:59 date in custom format: 2013-12-17 date+1: 2013-12-18T13:04:59 date+3: 2013-12-20T13:04:59 ``` Update 3 How to make adding the number of days, more `generic`? I did this way, ``` <!-- Made generic, increment interval can be passed as parameter --> <xsl:template name="formatdateafterincrement"> <xsl:param name="timestampstring" /> <xsl:param name="incr" /> <!-- input format: 'YYYYMMDD-HH:MM:SS-UTC' --> <!-- output format after date increment: YYYY-MM-DD --> <xsl:variable name="datestr"> <xsl:value-of select="concat(substring($timestampstring, 1, 4), '-', substring($timestampstring, 5, 2), '-', substring($timestampstring, 7, 2), 'T', substring($timestampstring,10, 8))" /> </xsl:variable> <xsl:variable name="datestrincr"> <xsl:value-of select="xs:dateTime($datestr) + xs:dayTimeDuration($incr)" /> </xsl:variable> <xsl:value-of select="format-dateTime($datestrincr, '[Y0001]-[M01]-[D01]')" /> </xsl:template> <!-- how to call the template --> <newdate> <xsl:call-template name="formatdateafterincrement"> <xsl:with-param name="timestampstring" select="book/timestamp" /> <xsl:with-param name="incr" select="'P1D'" /> <!-- one day --> </xsl:call-template> </newdate> ``` http://xsltransform.net/ is a good XSLT 2.0 processor. This works well. If someone has any suggestions, please share the same. I do not have a specific question. The questions are answered.