XSLT转换有时会失败

时间:2018-10-15 09:13:11

标签: java xml xslt xslt-1.0

我不是XSLT方面的专家,我有一个无法用转换器解释的问题。此问题仅在生产用途中出现:我自己无法复制。

我有一个进程(通过JMS队列)接收XML消息。该消息必须转换为另一个XML。

这是执行转换的代码:

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>

有人已经遇到了这个问题之王吗?还是可以告诉我这段代码有什么问题?

非常感谢。

编辑

只有一种精度:我们使用XSLT 1.0

编辑2

这是XML的一部分(我不能向您显示更多的信息,原因是私有数据和标签名称都是品牌产品)。

<DUNNING_LINE SEGMENT="1">
    <INVOICE_NUMBER>*************</INVOICE_NUMBER>
    <INVOICE_DUE_DATE>20180731</INVOICE_DUE_DATE>
    <INVOICE_TOTAL_AMOUNT>39.49</INVOICE_TOTAL_AMOUNT>
    <INVOICE_PAID_AMOUNT>0.00</INVOICE_PAID_AMOUNT>
    <INVOICE_DUE_AMOUNT>39.49</INVOICE_DUE_AMOUNT>
    <INVOICE_DATE_FROM>20180701</INVOICE_DATE_FROM>
    <INVOICE_DATE_TO>20180731</INVOICE_DATE_TO>
    <INVOICE_POSTING_DATE>20180630</INVOICE_POSTING_DATE>
</DUNNING_LINE>

1 个答案:

答案 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()接受任意数量的参数,并且子字符串的第二个和第三个参数是数字,因此这减少为

concat(substring($dateParam, 1, 4), '-', 
       substring($dateParam, 5, 2), '-', 
       substring($dateParam, 7, 2))

这不会解决您的问题,但是调试代码的第一步应该始终是摆脱不必要的复杂性。

我怀疑的问题是$ dateParam已经保存了不正确的数据,但是您当然没有向我们显示足够的信息来检验这个理论。