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:dateTime
或 xs: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:日期无效。非数字组件的主要内容,如果未能解决你的问题,请参考以下文章
ORA-01722: 无效的数字,但数据类型是日期,它不会以任何方式接受它
程序集致命错误 LNK1190:找到无效修复,类型 0x0001