Отменить произвольные строки заголовка при обработке плоских файлов BizTalk?

Я нашел эти связанные темы, но они не дают прямого ответа на мой вопрос:

BizTalk - плоский файл с несколькими записями заголовка и нижним колонтитулом - Разобрать проблему

Удаление заголовка из плоского файла в BizTalk

Я имею дело со старой системой, которая предоставляет плоские файлы с очень свободной схемой. В частности, заголовок состоит из двух строк: первая строка - это заголовок, а вторая строка - заголовки столбцов. Все последующие строки являются действительными записями.

Проблема в том, что при отсутствии записей за этот день заголовки столбцов опускаются; в этом случае у нас есть заголовок документа, а затем итоговая строка (для потребления человеком), которая уведомляет читателя об отсутствии записей за этот день.

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

Я пробовал два подхода к этому:

  • Схема заголовка, содержащая два элемента поля, разделенных символом возврата каретки, каждый из которых является непрозрачной строкой.
  • Схема заголовка, содержащая две записи с разделителями и возвратом каретки, каждая из которых определяет фиктивный инфиксный разделитель, который никогда не будет существовать ни в одной строке (что приводит к одной непрозрачной строке на запись)

Однако, когда я их развертываю, BizTalk будет собирать файлы и обрабатывать их, однако на самом деле это не приводит к появлению каких-либо сообщений. Это наводит меня на мысль, что BizTalk обрабатывает мои плоские файлы так, как будто весь файл является заголовком, поэтому он не находит никаких записей.

Решение, которое я пытаюсь найти, заключается в том, как создать схему заголовка, которая заставляет BizTalk обрабатывать первые две строки файла как заголовок, независимо от их содержимого, и отбрасывать их. Это возможно?

РЕДАКТИРОВАТЬ: Примеры различных файлов:

Записи существуют:

2017-02-27 19:27:03
CustomerName, OrderNumber, Expedite, ItemNumber, Count
CustomerA, O196801, 0, I232, 2
CustomerA, O196801, 0, I255, 1
CustomerB, O196802, 0, I237, 1
CustomerC, O196803, 0, I214, 1
CustomerC, O196803, 0, I232, 2

В этом файле нет записей:

2017-02-27 19:30:22
***EOF***
  • Первая строка всегда одна и та же, и ее можно описать записью с позиционными разделителями.
  • Вторая строка - это либо список имен столбцов, разделенных запятыми, либо строка EOF.
  • EOF отображается только при отсутствии записей.

В настоящее время я могу обрабатывать файлы с записями, только определяя разделитель между схемами заголовка и документа как всю строку заголовка столбца, т.е. CustomerName, OrderNumber, Expedite, ItemNumber, Count{CR}{LF} Однако эта схема заголовка не работает для пустого файла, когда он находит ***EOF*** вместо строки заголовка столбца .


person bwerks    schedule 24.02.2017    source источник
comment
Не могли бы вы дать нам несколько примеров сообщений и образец схемы, в которой вы пытались решить проблему? Без них довольно сложно помочь   -  person Dijkgraaf    schedule 25.02.2017
comment
Можете ли вы рассматривать имя первого столбца как тег? Если это так, ваша проблема действительно не кажется такой сложной.   -  person Johns-305    schedule 27.02.2017
comment
@Dijkgraaf Я добавил несколько примеров!   -  person bwerks    schedule 28.02.2017
comment
Как сказал Джонс. Создайте запись с тегом CustomerName и с MinOccurs равным 0. Повторяющаяся запись с Min Occurs 0 для ваших данных, а также другая запись с тегом EOF и MinOccurs 0f 0.   -  person Dijkgraaf    schedule 28.02.2017
comment
@Dijkgraaf Мне очень понравилась эта идея! Однако я не уверен, что это сработает - когда я пытаюсь это сделать, BizTalk выдает ошибку, заявляя, что не удается сопоставить данные во входном потоке, а сообщение, которое он приостанавливает, - EOF само собой. В моей схеме заголовка есть строка Date, MinOccurs 1, строка ColumnHeaders, Tag CustomerName MinOccurs 0 и строка eof Tag *** EOF MinOccurs 0. Схема документа содержит повторяющуюся запись. Я пробовал это с различными настройками для Infix / Postfix Child Order в схеме заголовка, а также с Preserve Delimiter for Empty Data и Suppress Trailing Delimiters.   -  person bwerks    schedule 03.03.2017
comment
Также я должен добавить, что у меня разбиты схемы заголовка и документа, так что дизассемблер плоских файлов будет обрабатывать мои повторяющиеся записи, установив MaxOccurs 1 в элементе повторяющейся записи в схеме документа.   -  person bwerks    schedule 03.03.2017


Ответы (1)


Может быть какой-нибудь умный способ справиться с этим с помощью схемы плоского файла, но я не могу об этом подумать.

Я бы, вероятно, попытался написать собственный компонент Decode для конвейера, который бы проверял первые несколько байтов сообщения для этого ***EOF*** - если да, просто обнулить поток (или, возможно, переписать его с ожидаемыми заголовками) - если нет, сбросить положение потока возвращается к 0 и передает его дальше.

например (примечание: непроверенный, возможно, работает код):

public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
    if (pInMsg == null || pInMsg.BodyPart == null) return pInMsg;

    var stream = pInMsg.BodyPart.GetOriginalDataStream();
    if (stream == null || stream.Length == 0) return pInMsg;

    if (!stream.CanSeek)
    {
        stream = new ReadOnlySeekableStream(stream);
        pContext.ResourceTracker.AddResource(stream);
    }

    StreamReader reader = new StreamReader(stream);
    pContext.ResourceTracker.AddResource(reader);
    reader.ReadLine(); // date line
    if (reader.ReadLine() == "***EOF***")
    {
        pInMsg.BodyPart.Data = null;
    }
    else 
    {
        stream.Position = 0;
        pInMsg.BodyPart.Data = stream;
    }
    return pInMsg;
}
person Dan Field    schedule 28.02.2017