XSLT-преобразование иногда не удавалось - PullRequest
0 голосов
/ 15 октября 2018

Я не эксперт по XSLT, и у меня есть проблема, которую я не могу объяснить с помощью трансформатора.Эта проблема возникает только при производственном использовании: я не могу воспроизвести ее сам.

У меня есть процесс, получающий сообщение XML (через очередь JMS).Это сообщение должно быть преобразовано в другой 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-дд.

<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 голосов
/ 15 октября 2018

Начните с упрощения кода:

<xsl:value-of select="concat(concat(concat(concat(substring($dateParam, '1', '4'), '-'), substring($dateParam, number('5'), '2')), '-'), substring($dateParam, number('7'), '2'))"/>

concat () принимает любое количество аргументов, а 2-й и 3-й аргументы подстроки являются числами, поэтому это сокращается до

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

Это не решит вашу проблему, но первым шагом в отладке кода всегда должно быть избавление от ненужной сложности.

Проблема, которую я подозреваю, состоит в том, что $ dateParam уже содержит неверные данные, ноКонечно, вы не показали нам достаточно информации, чтобы я смог проверить эту теорию.

...