Siddhant K.
Siddhant K.

Reputation: 33

SAXON 10 datetime is always processed as string despite having a date time variable

Recently I have migrated to Saxon 10 (XSLT 3.1) from Saxon 9 (XSLT 2.0). I have a variable $datetime Variable, that is of the type DateTime and whenever I have used the variable in XPATH expression calculator in my java application I have just used directly the variable and it used to get processed as the said variable type.

However, with Saxon 10 (XSLT 3.1), this variable during evaluation is always process as string type. I read the documentation where AtomicValue is made non-serializable in Saxon 10.5 hence, it is processed as string type.

I found a workaround that if I typecast the variable as xs:datetime($datetime) then the expression gets evaluated.

The current expression for reference is as follows:

current-dateTime() - $datetime

and the error I get is

Unsuitable types for- operation (xs:dateTimestamp, xs:string)

so here the second param is considered as string by saxon processor.

Reference code

XSDateTimeDummyProperty.java

public class XSDateTimeDummyProperty extends SaxonParentProperty<DateTimeValue> {


public static <T> T completeCopy(T orig) {
    if (orig == null) {
        return null;
    }
    try {
        // Convert orig to stream obj and copy 
    } catch (Throwable e) {
        throw new RuntimeException(e);
    }
}

public static <T> T normalCopy(T orig) {
    if (orig == null) {
        return null;
    }
    T copiedRef = orig;
    return (T) copiedRef;
}



public static void main(String[] args) {
    XSDateTimeDummyProperty originalArgument = new XSDateTimeDummyProperty();

    originalArgument.setValue("2020-07-01T11:44:10.011705+02:30"); //dummyDATETIME-String
    XSDateTimeDummyProperty deepCopiedReference = XSDateTimeDummyProperty.completeCopy(originalArgument); // java.io.NotSerializableException occurs
    XSDateTimeDummyProperty normalCopiedReference = XSDateTimeDummyProperty.normalCopy(originalArgument);

    System.out.println(deepCopiedReference);
    System.out.println(normalCopiedReference);
}}

SaxonParentProperty.java

public abstract class SaxonParentProperty<T extends AtomicValue> {
T obj;
protected void setValue(Object value) {
    ConversionResult conversionResult = DateTimeValue.makeDateTimeValue((CharSequence) value, ConversionRules.DEFAULT);

    this.obj = (T) conversionResult;
}}

Error At Runtime:

Exception in thread "main" java.lang.RuntimeException: java.io.NotSerializableException: com.xxx.utils.property.type.XSDateTimeDummyProperty
at com.xxx.utils.property.type.XSDateTimeDummyProperty.completeCopy(XSDateTimeDummyProperty.java:28)

It would be really helpful if I get an appropriate answer quickly.

Tried looking at the saxon documentation with little or less info.

Upvotes: -1

Views: 133

Answers (1)

Michael Kay
Michael Kay

Reputation: 163625

It's true that up to Saxon 9.3 or so (that is, about 10 years ago) the AtomicValue class implemented Serializable, and I can conceive of applications that might be affected by the fact that we changed it. I find it a little surprising that it should have the symptoms you describe, but if you showed us some code I guess we could work it out, and advise you what changes to make to restore the previous behaviour.

Later (16 Aug 2023)

If I recall correctly, the reason we made the change was that (a) we changed the internal implementation of some atomic values to use JDK classes that were not serialisable -- possibly something related to locales and timezones -- and (b) the original Saxon feature that required values to be serializable, namely the ability to serialize a compiled stylesheet in its entirety, had been dropped many years earlier.

You seem to be relying on serializability to make a deep copy of an atomic value. It shouldn't be necessary to make a deep copy, because atomic values are (for practical purposes) immutable. (The only exception is the setTypeLabel() method, but that is only called during initialization). If you really do need to make a copy, you can achieve this using:

AtomicValue x = ...
AtomicValue y = x.copyAsSubType(x.getItemType());

Upvotes: 0

Related Questions