FORG0001:日期无效。非数字组件

Posted

技术标签:

【中文标题】FORG0001:日期无效。非数字组件【英文标题】:FORG0001: Invalid date. Non-numeric component 【发布时间】:2021-11-09 08:50:04 【问题描述】:

我正在尝试使用 XSLT 将 XML 转换为另一种格式。在将日期从一种格式转换为另一种格式时,我收到以下验证错误。 FORG0001:日期“22/12/2020 18:16:34”无效。非数字组件

输入 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 模板

<?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>

驱动 Java 程序

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);
    

我正在使用 XSLT 2.0 版和 Saxon-8.7

【问题讨论】:

Saxon 的当前版本是 Saxon 10.5,最新的 9.x 版本是 9.9。我认为 8.7 是在 XSLT 2 规范最终确定之前发布的。不过,我希望支持 XSD 日期/日期时间格式,所以基本上您需要将自定义日期/日期时间格式转换为 YYYY-MM-DDThh:mm:ss @MartinHonnen - 我将 jar 从 Saxon 8.7 更改为 Saxon-HE 10.5。并得到 - FORG0001 无效的日期时间值“22/12/2020T18:16:34”(非数字年份组件)。然后我将日期更改为 2020-12-22T22:10:15 并且它正在工作。那么,YYYY-MM-dd hh:mm:ss 是有效的 XSLT 日期时间格式吗? 【参考方案1】:

所以尝试将replace(release_dttm, '([0-9]2)/([0-9]2)/([0-9]4) (.+)', '$3-$2-$1T$4') 转换为xs:dateTime 格式,正如Michael Kay 指出的那样,完整的代码需要转换并使用正确的format 函数,例如

  <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]')"/>

需要在 XSLT 中声明 xmlns:xs="http://www.w3.org/2001/XMLSchema",才能使用 xs:dateTimexs:date 函数。

【讨论】:

这里需要注意的是,replace() 的结果是一个字符串,并且没有从字符串自动转换为xs:dateTime;所以你需要将此调用包装在显式转换format-dateTime(xs:dateTime(replace(....))) 中。还需要明确我们使用的是xs:date还是xs:dateTime @MichaelKay,你是对的,我修改了答案。【参考方案2】:

format-date() 期望第一个参数是xs:date 类型;但是,如果您提供一个无类型节点,就像您在此处所做的那样,它将尝试将该节点的字符串值转换为 xs:date 值。如果输入不是标准 ISO 日期格式 yyyy-mm-dd,此转换将失败(错误 FORG0001)。强烈建议您在 XML 中存储日期时使用国际日期格式,因为像 03/04/2019 这样的格式是不明确的。但如果您无法更改 XML,则需要按照 @MartinHonnen 的建议手动将其转换为 yyyy-mm-dd 格式。

【讨论】:

以上是关于FORG0001:日期无效。非数字组件的主要内容,如果未能解决你的问题,请参考以下文章

什么是“oracle ORA-01722”无效数字?

ORA-01722: 无效的数字,但数据类型是日期,它不会以任何方式接受它

程序集致命错误 LNK1190:找到无效修复,类型 0x0001

检查 Amazon Redshift 中的无效日期

使用 NSDateFormatter 格式化月份和年份返回无效日期

Redshift 中的无效数据错误