XSLT 2.0 How to change default formatting for numbers? - xslt

In XSLT 1.0 (using Xalan), outputting the result of:
<xsl:variable name="source0" select="number(num3)"/>
<xsl:value-of select="$source0"/>
was the number spelled out as 2011234. But in XSLT 2.0 (using Saxon), it shows up as 2.011234E6. I want it to always display as 2011234 in the Saxon/2.0 case.
Is there a way to set the default picture string for whenever it outputs a number?
I saw decimal-format, but that just affects picture strings, it doesn't set number formatting. I can't just throw format-number everywhere since then I'd have to check datatypes everywhere and... it would be a mess.

There is no way to express in XSLT 2.0 (or XSLT 1.0) that every time a number value is output it must be in a "default" format, without ussing fn:format-number() or xsl:decimal-format or op:cast or built-in type constructors. The only way that every number will be consider of some specific type is that a schema has been declared for the input (so it's a PSVI) and you run the transformation with schema-awere processor.

Related

Using same XSLT key with different contexts subsequently. Semantics depends on XSLT version or XSLT engine?

With this example:
XSLT Keys Example
I got different results by only changing the XSLT version from 1.0 to 2.0.
With v1.0 result is: <result>111</result> (obviously the key is initialized with the context when is used the first time and stays unchanged). But with v2.0. result is: <result>1 61 61 6</result> there it seems the key is reinitialized whenever the context changes.
My question is if this is because of different XSLT version 1.0 vs 2.0 semantics or can it also be caused by different XSLT engines and same XSLT version? Thx.
The semantics of xsl:value-of has changed in XSLT 2; while in XSLT 1.0 <xsl:value-of select="some-expression"/> outputs a text node with the string value of the first node selected by some-expression in XSLT 2 a text node containing a space separated (more generally, the value of the separator attribute if present) sequence of the string values of all selected items is created.
XSLT 2 or 3 processors supporting XPath 1 backwards compatibility mode will use the XSLT 1 behaviour where xsl:version="1.0" or version="1.0" is used.

XSLT 1.0 - Compare date values and offset by -15 days

I am trying to compare to date values that are being passed into XSLT with the format of MMDDYY, for example: 01022020 (Jan 2, 2020). I am using the below snippet of code in the test:
<xsl:if test="(E_Payclass ='FT') and (E_Status ='TERMINATED') and (E_TermDate < E_PayEnd_Date)">
In an example, the dates are:
E_TermDate: 072017
E_PayEnd_Date: 020120
When running this file, I get the 072017 appearing even though it is actually less than the current date. It seems to me that the file is actually taking the number literally (which is most likely what is supposed to happen) and returning it since its technically greater than 020120.
Overall I am trying to accomplish an outcome in the test that basically would take the E_PayEnd_Date as an actual date, and only return E_TermDate if it is within 15 days prior to it.
Does anyone know how to do that in XSLT 1.0 within an if test statement?

XSLT 2.0: declare string array

is it possible declare a string array in XSLT 2.0?
I would like declare something as below:
<xsl:variable name="countries" select="('IT','EN','SP')" />
but doesn't work.
Thanks.
There are no arrays in the data model that XSLT/XPath 2.0 work with. Your code <xsl:variable name="countries" select="('IT','EN','SP')" /> binds a sequence of string values to the variable named countries and you should be able to access single items with a positional predicate like e.g. $countries[2].
If you think you need arrays then you need to use XPath 3.1 where you can use <xsl:variable name="countries" select="['IT', 'EN', 'SP']"/>, see http://www.w3.org/TR/xpath-31/#id-arrays. I am not aware of any released XSLT processor that supports this, however, I think XQuery implementations like BaseX have already been upgraded to support this.
As long as you simply want to store three or more atomic values in a flat data type I don't see why you would need the new array feature, the sequence ('IT','EN','SP') should suffice. Arrays can be nested, sequences not, as (1, (2, 3), 4) results in a flat sequence (1, 2, 3, 4), so in case you needed a nested data structure (with primitive values like numbers or strings) you might need an array and have to wait until there is support for XPath 3.1, you can however always created an XML tree structure for nested data in current versions of XSLT.

Deduct milliseconds from DateTime in xslt

I have a dateTime in this format: 2015-04-29T01:30:27.058Z and time difference of 5000milliseconds. Is there any XSLT function which can deduct this time difference and produce an output of a dateTime?
In XSLT 2.0 or later (requires an XSLT 2.0 processor like Saxon 9 or XmlPrime) you can use arithmetic with xs:dateTime and xs:dayTimeDuration, for instance
xs:dateTime('2015-04-29T01:30:27.058Z') + xs:dayTimeDuration('-PT0.058S')
computes a new xs:dateTime 2015-04-29T01:30:27Z.
The XML schema namespace assumed for the prefix xs is http://www.w3.org/2001/XMLSchema.
See http://www.datypic.com/sc/xsd/t-xsd_dayTimeDuration.html on how dayTimeDurations can be written.
So with that version of the language my suggestion is to make use of those two data types and the arithmetic operations provided instead of going to milliseconds for computations.
In XSLT 2.0,
(xs:dateTime($timeStamp) - xs:dateTime('2000-01-01T00:00:00Z'))
div xs:dayTimeDuration('PT0.001S')
gives the number of milliseconds since the start of the current century.

get the date:time by xsl

currently I'm using xsl to get the min and max value of #last_updated_time in a sharepoint list, the type is string (like 9/14/2012 1:26:23 PM)
so how can I display the earliest and latest time?
P.S. I try to remove all things but number,then convert to the int, then do the compare, but how to convert that, can anybody show me an approach?
You'll find it much easier to manipulate dates and times in XSLT (especially in XSLT 2.0) if you use international format (2012-14-09T13:26:23) rather than US localized format. So first, if your data is in US format, write code to translate it to ISO format. (That's a simple exercise in string manipulation).
Once you're there, you can use the XSLT 2.0 min() and max() functions to find the earliest and latest in a set of dates or date/time values. Or in XSLT 1.0, you can sort them and select the first and last in sorted order.