I am trying to convert an XML to another format using XSLT. While converting a date from one format to another, I am getting the below validation error. FORG0001: Invalid date "22/12/2020 18:16:34". Non-numeric component
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<ft_tnx_record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.misys.com/portal/interfaces/xsd/ft.xsd"/>
<release_dttm>22/12/2020 18:16:34</release_dttm>
</ft_tnx_record>
XSLT Template
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/ft_tnx_record">
<release_dttm>
<xsl:value-of select="format-date(release_dttm,'[Y0001]-[M01]-[D01]')"/>
</release_dttm>
</xsl:template>
</xsl:stylesheet>
Driver Java Program
public class Main {
public static void main(String[] args) throws TransformerException {
String filePathPrefix = System.getProperty("user.dir") System.getProperty("file.separator");
String directImportInputXmlPath = filePathPrefix "directImportInputXml.xml";
StreamSource directImportXml = new StreamSource(new File(directImportInputXmlPath));
String directImportXsltPath = filePathPrefix "directImportXslt.xslt";
StreamSource directImportXslt = new StreamSource(new File(directImportXsltPath));
String directImportOutputXmlPath = filePathPrefix "directImportOutputXml.xml";
StreamResult directImportOutputXml = new StreamResult(new File(directImportOutputXmlPath));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(directImportXslt);
transformer.transform(directImportXml, directImportOutputXml);
}
}
I am using XSLT version 2.0 and Saxon-8.7
CodePudding user response:
format-date()
expects the first argument to be of type xs:date
; but if you supply an untyped node, as you are doing here, it will attempt to cast the string value of that node to an xs:date
value. This cast will fail (with error FORG0001) if the input is not in the standard ISO date format yyyy-mm-dd
. It's strongly recommended to use international date formats whenever you store dates in XML, because formats like 03/04/2019 are ambiguous. But if you can't change the XML, then you need to convert it manually to yyyy-mm-dd
format as @MartinHonnen has suggested.
CodePudding user response:
So try replace(release_dttm, '([0-9]{2})/([0-9]{2})/([0-9]{4}) (. )', '$3-$2-$1T$4')
to convert to the xs:dateTime
format, and as Michael Kay pointed out, the complete code then needs to cast and use the right format
function e.g.
<xsl:value-of select="format-dateTime(xs:dateTime(replace(release_dttm, '([0-9]{2})/([0-9]{2})/([0-9]{4}) (. )', '$3-$2-$1T$4')),'[Y0001]-[M01]-[D01]')"/>
Needs to declare xmlns:xs="http://www.w3.org/2001/XMLSchema"
in the XSLT, to be able to use xs:dateTime
or xs:date
functions.