This question already has answers here:
XML-XSLT : How to compare two dates which are in String
(2 answers)
Closed 3 years ago.
I know this question might get repeated and i am still learning (XML-XSLT : How to compare two dates which are in String)
EX:<oldDate>2019-09-25T10:49:52.755Z</oldDate>
<currentDate>2019-07-25T10:49:52.755Z</currentDate>
can some one help me
sample code:
XML-XSLT : How to compare two dates which are in String
EXPECTED output:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<output>OK</output>
</xml>
or
<?xml version="1.0" encoding="utf-8"?>
<xml>
<output>Not Ok</output>
</xml>
Please someone help me to compare this kind of date format
You can simply use below code after typecast the string as date xs:dateTime():
<xsl:value-of select="if (xs:dateTime(/root/oldDate) > xs:dateTime(/root/currentDate)) then ('OK') else ('Not OK')"/>
see this link: https://xsltfiddle.liberty-development.net/bnnZX6
Related
I want to take off 20 hours from the expectedDispatchDate
Input XML:
<Extrinsic name="expectedDispatchDate">2020-01-15T16:00:00+01:00</Extrinsic>
XSLT:
<xsl:value-of select="Extrinsic[#name='expectedDispatchDate'] - 20"/>
Output XML:
2020-01-14T20:00:00+01:00
Take a look at the EXSLT dates-and-times library at www.exslt.org, and in particular at the XSLT template named date:add-duration which can be found at http://exslt.org/date/functions/add-duration/date.add-duration.template.xsl
I'm attempting to create an XSLT mapping that properly converts a fairly large integer value coming through in a text field into the appropriate integer value. The problem is that since 1.0 only supports converting to type number, I get a value like 1.234567890E9 back for input of "1234567890"
I'm using Altova MapForce with XSLT1.0 as the coding platform. XSLT2.0 doesn't appear to be an option, as the XSLT has to be processed using a pre-existing routine that only supports XSLT1.0
By default Mapforce generates
<xsl:value-of select="string(floor(number(string(.))))"/>
and I've tried every combination of functions I can think of, but always get a float for large values.
Further testing shows the problem lies in Mapforce, which insists on using the number() function when mapping from text to int.
Let me try and move this forward by answering a question that you did not ask, but perhaps should have. Suppose you have the following input:
XML
<input>
<value>1234567890000000.9</value>
<value>9876543210000000</value>
</input>
and you want to make sure that the input values (which are all numbers, but some of them are not integers) are converted to integers at the output, you could apply the following transformation:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:for-each select="input/value">
<value><xsl:value-of select="format-number(., '#')"/></value>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
to obtain the following output:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<value>1234567890000001</value>
<value>9876543210000000</value>
</output>
Note that the results here are rounded, not floored.
Are you sure that mapforce isn't using xslt-2.0?
If I do in XSLT-1.0 (with either saxon or Altova's processor):
<xsl:value-of select="number('1234567890')"/>
I get -> 1234567890
If I use XSLT-2.0 I get -> 1.23456789E9
So I think it is very strange that an XSLT 1 transformation supposedly returns you the floating point representation of the number.
Formatting the number with format-number(1.23456789E9,'#') will always give you 1234567890 in both XSLT-1.0 and 2.0. Edit: saxon will not convert 1.23456789E9 to number in xslt-1.0, altova's processor however will.
The problem lies within Mapforce, so I've decided to let mapforce generate it's code, then overwrite it for this one field that's causing all the trouble.
#Tobias #Michael Thanks to you both for your help. I've +1'ed both your answers and a few comments since your help led to the answer.
this is a self-answered post, since it took me some time to find the reason for the following XTSE0120.
I'm quite new to XSLT and made a mistake and put some text outside <xsl:template>:
bellack#bellack-TP-T430u:~$ cat -n /tmp/x.xsl
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <xsl:stylesheet
3 version="2.0"
4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 >
6 <xsl:output method="text"/>
7 <xsl:template name="build" match="/">
8 <!--
9 a lot of xslt code lines
10 -->
11 </xsl:template>
12 ****** misplaced text ****************
13 </xsl:stylesheet>
As this is not allowed, I got error XTSE120, see http://www.w3.org/TR/xslt-30/#err-XTSE0120:
bellack#bellack-TP-T430u:~/workspace/tembanking/generator/crud$ java -jar ../lib/saxon9.jar -xsl:/tmp/x.xsl -s:/dev/null
Error at xsl:template on line 7 of file:/tmp/x.xsl:
XTSE0120: No character data is allowed between top-level elements
Failed to compile stylesheet. 1 error detected.
But the Error is reported for line 7, and since x.xsl had some hundred lines, I was searching for something wrong around line 7 in vain, where the error was in fact at the end of the file.
I don't know if other XSLT processors than saxon also give this misleading error message.
Hope that helps somebody ...
Udo
Saxon only keeps line number information for element nodes, not for text nodes, so we have difficulty reporting an accurate position for the rare case where the error is in a text node.
I have the following code that reads a rss feed into my page, but I would like to have the pubDate convert into a more human readable date if alt all possible.
<?xml version="1.0" encoding="iso-8859-1"?><!-- DWXMLSource="mm_news.xml" -->
<!DOCTYPE xsl:stylesheet]>
<xsl:output method="html" encoding="iso-8859-1"/>
<xsl:template match="/">
<p class="newsList-date"><xsl:value-of select="pubDate"/></p>........
This gives me:
Fri, 9 Sept 2011 15:21:36 GMT
but Would Like to read something like
Friday 9 Sept 2011
Even be happy if I could simply trim off the end to just have 'Fri, 9 Sept 2011'
Also if easier can I add an extra section within the xml so i can simply enter the date like I want it so I can read it, something like below? (The xml is hand written not dynamically created)
<?xml version="1.0" encoding="US-ASCII" ?>
<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="direct.xsl"?>
<rss version="2.0">
<channel>....
<item>....
<title>.....
<description>....
<thedate>.....
Many Thanks
Well, the quick & dirty way would be to substitute select="pubDate" for an expression like this:
select="substring(pubDate,1,16)"
That one's dependent on the month being four letters however, and only gives you your 'fallback' result of 'Fri, 9 Sept 2011'.
If necessary, you can be a bit cleverer and remove the requirement of the month being four letters (which seems unlikely for May), by using this expression:
select="substring(pubDate,1,string-length(substring-before(pubDate,':'))-3)"
Rather than taking a fixed length of 16, it bases it on where the first : is (in the time), and subtracts 3 from that.
If you REALLY want, there's a one-line expression that can give you what you want, but it's a bit convoluted:
select="concat(normalize-space(substring('Monday Tuesday WednesdayThursday Friday Saturday Sunday ',string-length(substring-before('MonTueWedThuFriSatSun',substring(pubDate,1,3))) * 3 + 1,9)),substring(pubDate,5,string-length(substring-before(pubDate,':'))-7))"
This uses a 'lookup', to find where the day of the week exists in one string, and uses that to pick the full name from another, finally using 'normalize-space' to trim any extra spaces. Then it just concatenates it with the date part.
We have to transform some XML that contain numbers in exponent (aka scientific) notation
eg.
<Value>12.34e12</Value>
<Value>-12.34e-12</Value>
rather irritatingly, we cannot use the sum() function and the like because the XSLT parser expects numbers to be in decimal format.
[We are using the .Net XslCompiledTransform class to do the transform but I think this problem is common to all XSLT implementations]
The only solution to this problem that we have so far is to transform the string value to a number using a javascript function (see below) and then write our own sum template which calls this function.
It seems to me that there must be a better way - is there?
/*
This function attempts to coerce the input into a number.
*/
function toNumber( x ) {
if(!x) {
return Number.NaN;
}
if(typeof x === 'number') {
return x;
}
return parseFloat(x);
};
Saxon-B 9.0.0.6 works fine here. Outputs 0.
EDIT: Now I see that Saxon 6 (processor only for xslt 1.0) returns NaN. But if you try xslt 2.0, you won't ever want anything else. :-)
XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Value>12.34e12</Value>
<Value>-12.34e12</Value>
</root>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="root">
<xsl:value-of select="sum(Value)"/>
</xsl:template>
</xsl:stylesheet>