I need to display date like Wednesday, 5th May, 2011
I am trying
<xsl:value-of select="format-date(
current-date(),
'[FNn,*-3], [D01] [MNn,*-3] [Y0001]',
'en',
'',
'US'
)" />
And another one i tried
<xsl:value-of select="format-date(
current-date(),
'[FNn], [MNn] [D1o], [Y]',
'en',
(),
()
)" />
Both gives me following. I need text and it gives number only. I use XSLT 2.0
3, 5 4, 2011
This stylesheet:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="format-date(
current-date(),
'[FNn], [D1o] [MNn,*-3], [Y]',
'en',
(),
()
)" />
</xsl:template>
</xsl:stylesheet>
Output:
Wednesday, 4th May, 2011
Tested on Saxon and Altova.
Related
Please suggest how to do math functions like power in XSLT2 with Saxon 9HE.
Getting following error:
Cannot find a matching 2-argument function named {http://exslt.org/math}power()
XML:
<root><num>12.3</num></root>
XSLT 2.0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="exsl math">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<!--1/(1+e^(-t))--><!-- this is required formula -->
<xsl:template match="num">
<xsl:variable name="varE"><xsl:value-of select="."/></xsl:variable>
<xsl:variable name="varT"><xsl:text>0.718</xsl:text></xsl:variable>
<xsl:variable name="varPower">
<xsl:value-of select="1 div (1 + math:power(number($varE), number(-$varT)))"/>
</xsl:variable>
<xsl:value-of select="$varPower"/>
</xsl:template>
</xsl:stylesheet>
There are XPath standardized math functions like math:pow e.g. math:pow(2, 4) in the namespace https://www.w3.org/2005/xpath-functions/math e.g with the namespace declaration xmlns:math="http://www.w3.org/2005/xpath-functions/math" available in all editions of Saxon (at least with 9.8 but I think it also works with earlier version like 9.7 and 9.6 (documentation http://saxonica.com/html/documentation9.6/functions/math/pow.html says since 9.6 in all editions).
I need to convert 11/14/2016 - This is String Data Type. I need to convert it to 2016-11-14 using XSLT 2.0. Please let me know how to proceed? I don't want to use subString method. I tried format-date() function from xslt 2.0 but not successful.
You could do something like this. You can use the tokenize function instead, if you do not want to use substring.
Assuming an input XML like:
<string>11/14/2016</string>
When run against a style sheet below:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:variable name="target_string">
<xsl:value-of select="tokenize(string, '/')[last()]"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="tokenize(string, '/')[1]"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="tokenize(string, '/')[2]"/>
</xsl:variable>
<date1>
<xsl:value-of select="xs:date($target_string)"/>
</date1>
<date2>
<xsl:value-of select="format-date(xs:date($target_string), '[MNn] [D], [Y]')"/>
</date2>
</xsl:template>
</xsl:stylesheet>
produces:
<date1>2016-11-14</date1><date2>November 14, 2016</date2>
Sorry to say that XSLT is following ISO 8601 which should be yyyy-mm-dd, so subString will be your only choice.
Reference:
https://www.w3.org/TR/xmlschema-2/#isoformats
I need to display latest date in N number of months using xslt.
My input:
2016/10/18
2016//10/15
2016/09/29
2016/09/15
and so on.
My output should be like below:
2016/10/18
2016/09/29
Can anyone help me on this?
Given a string of dates in that format you first need to tokenize to extract the date values, then you need to convert to the xs:date format, then you can group by the month and select the maximum value in each group. Using XSLT 3.0 that can be done as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:param name="input" as="xs:string">2016/10/18 2016/10/15 2016/09/29 2016/09/15</xsl:param>
<xsl:variable name="dates" as="xs:date*"
select="tokenize($input, '\s+')!xs:date(replace(., '/', '-'))"/>
<xsl:variable name="max-dates" as="xs:date*">
<xsl:for-each-group select="$dates" group-by="month-from-date(.)">
<xsl:sort select="current-grouping-key()"/>
<xsl:sequence select="max(current-group())"/>
</xsl:for-each-group>
</xsl:variable>
<xsl:template name="main" match="/">
<xsl:value-of select="$max-dates" separator="
"/>
</xsl:template>
</xsl:stylesheet>
In XSLT 2.0 you need to rewrite the date sequence construction a bit:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="2.0">
<xsl:param name="input" as="xs:string">2016/10/18 2016/10/15 2016/09/29 2016/09/15</xsl:param>
<xsl:variable name="dates" as="xs:date*"
select="for $dateString in tokenize($input, '\s+') return xs:date(replace($dateString, '/', '-'))"/>
<xsl:variable name="max-dates" as="xs:date*">
<xsl:for-each-group select="$dates" group-by="month-from-date(.)">
<xsl:sort select="current-grouping-key()"/>
<xsl:sequence select="max(current-group())"/>
</xsl:for-each-group>
</xsl:variable>
<xsl:template name="main" match="/">
<xsl:value-of select="$max-dates" separator="
"/>
</xsl:template>
</xsl:stylesheet>
I. Here is a short XSLT 2.0 solution:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="d" group-by="substring(.,6,2)">
<xsl:sequence select="current-group()[. eq max(current-group()/string())][1]"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document (unordered and multi-year dates -- to make it more interesting):
<t>
<d>2016/10/15</d>
<d>2016/09/15</d>
<d>2016/10/18</d>
<d>2016/09/29</d>
<d>2017/09/17</d>
</t>
the wanted, correct result is produced:
<d>2016/10/18</d>
<d>2017/09/17</d>
II. If the date that has the same month's highest day is wanted -- regardless of the year, this transformation:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="d" group-by="substring(.,6,2)">
<xsl:sequence select=
"current-group()[substring(.,9,2) eq max(current-group()/substring(.,9,2))][1]"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the same XML document (above), the correct result is produced:
<d>2016/10/18</d>
<d>2016/09/29</d>
III. If the dates are given together as a string:
Just use the tokenize() standard XPath 2.0 fy=unction.
For example, the equivalent of the first transformation above becomes:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vDates"
select="'2016/10/15 2016/09/15 2016/10/18 2016/09/29 2017/09/17'"/>
<xsl:template match="/">
<xsl:for-each-group select="tokenize($vDates, '\s+')[.]" group-by="substring(.,6,2)">
<xsl:sequence select="max(current-group())"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
This is the logic i am trying to use .Should i sub string 2002-05-30T09:30:10-06:00 and get 2002-05-30T09:30:10 and 06:00 separate and subtract and use it in the below logic.If there is any easier way kindly let me know.
{code}
<tns:timestamp>
<xsl:variable name="date" select="/Order/#OrderDate"/>
<xsl:value-of select='xs:dateTime("1970-01-01T00:00:00") + #date *xs:dayTimeDuration("PT0.001S")'/>
</tns:timestamp>
I don't think you should subtract the offset in your calculation. If you do:
(xs:dateTime(#OrderDate) - xs:dateTime('1970-01-01T00:00:00Z')) div xs:dayTimeDuration('PT1S')
the result will be:
1022772610
If you convert that unix time into human readable time you get the correct GMT and local time:
Here's an example (see it working here)...
XML Input
<Order OrderDate="2002-05-30T09:30:10-06:00"/>
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"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:template match="/Order">
<Order unix-time="{(xs:dateTime(#OrderDate) - xs:dateTime('1970-01-01T00:00:00Z'))
div xs:dayTimeDuration('PT1S')}">
<xsl:copy-of select="#*|node()"/>
</Order>
</xsl:template>
</xsl:stylesheet>
XML Output
<Order unix-time="1022772610" OrderDate="2002-05-30T09:30:10-06:00"/>
My output looks like
<TransactionLog TID="1400" SeqNo="3337446" SQLTransaction="Insert into TankerLoads Values(141221,53,299,18,1,426148,6,'Nov 19 2007 12:00AM','Dec 30 1899 12:59PM',3.00,20682,0,'Zevo','Nov 19 2007 12:00AM',0)" />
where I need to add <root> node so that it will look like below
<root>
<TransactionLog TID="1400" SeqNo="3337446" SQLTransaction="Insert into TankerLoads Values(141221,53,299,18,1,426148,6,'Nov 19 2007 12:00AM','Dec 30 1899 12:59PM',3.00,20682,0,'Zevo','Nov 19 2007 12:00AM',0)" />
</root>
I combined all the records by using below code and now I need to add root node and I need to diplay this with OUTPUT METHOD AS TEXT. Please help me.
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)" />
</xsl:template>
You can capture the output of your transformation in a variable and apply to the contents of the variable a transformation similar to this:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vResult1">
<TransactionLog TID="1400"
SeqNo="3337446"
SQLTransaction="Insert into TankerLoads Values(141221,53,299,18,1,426148,6,'Nov 19 2007 12:00AM','Dec 30 1899 12:59PM',3.00,20682,0,'Zevo','Nov 19 2007 12:00AM',0)" />
</xsl:variable>
<xsl:template match="node()|#*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|#*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<root>
<xsl:apply-templates select="$vResult1/*" mode="pass2"/>
</root>
</xsl:template>
</xsl:stylesheet>
When this transformation is performed on any XML document (not used), the wanted, correct result is produced:
<root>
<TransactionLog TID="1400" SeqNo="3337446"
SQLTransaction="Insert into TankerLoads Values(141221,53,299,18,1,426148,6,'Nov 19 2007 12:00AM','Dec 30 1899 12:59PM',3.00,20682,0,'Zevo','Nov 19 2007 12:00AM',0)"/>
</root>
Alternatively, and much better, modify your existing transformation to something like this:
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
Or if your transformation already has a template matching /:
<xsl:template match="/">
<root>
<!-- Put the body of your current template here -->
</root>
</xsl:template>
</xsl:stylesheet>