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.