Java XSLT转换有时失败
我不是XSLT方面的专家,我有一个无法用transformer解释的问题。这个问题只发生在产品使用中:我自己无法复制它 我有一个进程(通过JMS队列)接收XML消息。此消息必须转换为另一个XML 这是执行转换的代码:Java XSLT转换有时失败,java,xml,xslt,xslt-1.0,Java,Xml,Xslt,Xslt 1.0,我不是XSLT方面的专家,我有一个无法用transformer解释的问题。这个问题只发生在产品使用中:我自己无法复制它 我有一个进程(通过JMS队列)接收XML消息。此消息必须转换为另一个XML 这是执行转换的代码: final TransformerFactory factory = TransformerFactory.newInstance(); final Templates templates = factory.newTemplates(new StreamSource(xsl));
final TransformerFactory factory = TransformerFactory.newInstance();
final Templates templates = factory.newTemplates(new StreamSource(xsl));
final Transformer xformer = templates.newTransformer();
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final InputStream inputStream = new ByteArrayInputStream(message.getBytes())) {
final Source source = new StreamSource(inputStream);
final Result result = new StreamResult(outputStream);
xformer.transform(source, result);
....
}
在原始XML中,我接收格式为yyyyMMdd(作为字符串)的日期,但我需要格式为yyyy-MM-dd的日期
<xsl:template match="INVOICE_DATE_FROM">
<xsl:call-template name="fctFormatDate">
<xsl:with-param name="elementName" select="'dateFrom'"/>
<xsl:with-param name="dateParam">
<xsl:value-of select="string(.)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="fctFormatDate">
<xsl:param name="elementName"/>
<xsl:param name="dateParam"/>
<xsl:if test="$dateParam != '' and $dateParam != '00000000'">
<xsl:element name="{$elementName}">
<xsl:value-of select="concat(concat(concat(concat(substring($dateParam, '1', '4'), '-'), substring($dateParam, number('5'), '2')), '-'), substring($dateParam, number('7'), '2'))"/>
</xsl:element>
</xsl:if>
</xsl:template>
大多数情况下,它是有效的,我得到了一个格式良好的日期。但有时,我会收到这样的消息:
<dateFrom>IN18-07-01</dateFrom>
IN18-07-01
有人已经见过这个问题之王了?或者你能告诉我这段代码有什么问题吗
非常感谢
编辑
只有一个精度:我们使用XSLT1.0
编辑2
这是XML的一部分(我不能向您展示更多,因为私有数据将产品标记为标记名)
*************
20180731
39.49
0
39.49
20180701
20180731
20180630
从简化代码开始:
<xsl:value-of select="concat(concat(concat(concat(substring($dateParam, '1', '4'), '-'), substring($dateParam, number('5'), '2')), '-'), substring($dateParam, number('7'), '2'))"/>
这不会解决您的问题,但调试代码的第一步应该始终是消除不必要的复杂性
我怀疑的问题是$dateParam已经保存了不正确的数据,但您当然没有向我们展示足够的信息,让我能够测试这一理论。可能服务器中的语言设置与测试环境中的语言设置不同。这可能会更改默认的日期和时间默认值。所有服务器都是英文的。但我不明白为什么在这种情况下它能改变任何事情。原始值是文本(20180701),XSLT要求将其更改为格式化文本(2018-07-01)。此外,99%的消息转换得很好。我认为“IN”来自源标签名。我还收到过一些类似INVO-07-01的例子,在出现问题的地方向我们展示了一个最小但完整的输入XML,我们可能能够分辨出什么是错误的,只显示代码而不显示输入不允许任何人分辨出什么是错误的,除了假设输入不是您所说的格式之外,XSLT看起来不是问题所在,而是产生XML的任何东西。考虑将注释添加到<代码> XSL:Engult代码块中,以允许查看原始值。例如
。谢谢。当我开始做这个项目时(一周前),我已经做了这个简化。但由于它还没有部署到生产环境中,我将向您展示它在生产环境中的代码。关于输入XML,我只是添加了我能添加的内容。但当我在测试中发送完全相同的输入时,并没有错误。在生产过程中,我只有不到0.1%的失败流程(所有输入都具有相同的结构)。无论这可能多么令人沮丧,您必须清楚,您没有向读者提供足够的信息,使他们能够找到此错误。
<xsl:value-of select="concat(concat(concat(concat(substring($dateParam, '1', '4'), '-'), substring($dateParam, number('5'), '2')), '-'), substring($dateParam, number('7'), '2'))"/>
concat(substring($dateParam, 1, 4), '-',
substring($dateParam, 5, 2), '-',
substring($dateParam, 7, 2))