【问题标题】:Discard arbitrary header lines in BizTalk Flat File processing?在 BizTalk 平面文件处理中丢弃任意标题行?
【发布时间】:2017-02-24 18:45:36
【问题描述】:

我找到了这些相关的帖子,但它们没有直接回答我的问题:

BizTalk - Flat file with Header multiple records and Footer - Disassemble problem

Removing header from a flat file in 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*** 而不是列标题字符串时,此标题架构会失败。

【问题讨论】:

  • 您能否给我们一些示例消息和示例架构,您尝试在其中解决问题?没有这些就很难提供帮助
  • 你能把第一列的名字当作一个标签吗?如果是这样,您的问题听起来确实没有那么复杂。
  • @Dijkgraaf 我添加了一些例子!
  • 正如约翰斯所说。创建一条具有 CustomerName 标记的记录,并让该记录的 MinOccurs 为 0。为您的数据创建一条 Min Occurs 0 的重复记录,以及另一条带有 EOF 标记和 MinOccurs 0f 0 的记录。
  • @Dijkgraaf 我真的很喜欢这个主意!但是,我不确定它是否会起作用——当我尝试它时,BizTalk 错误声称“无法匹配输入流中的数据”并且它挂起的消息是“EOF ” 本身。我的标题架构有 Date 行、MinOccurs 1、ColumnHeaders 行、Tag "CustomerName" MinOccurs 0 和 eof 行 Tag "***EOF" MinOccurs 0。文档架构包含重复记录。我尝试了在标题架构上设置中缀/后缀子顺序的各种设置,以及“为空数据保留分隔符”和“禁止尾随分隔符”。

标签: biztalk biztalk-schemas


【解决方案1】:

可能有一些巧妙的方法可以使用平面文件模式来处理这个问题,但我想不出。

我可能希望为管道编写一个自定义 Decode 组件,该组件将检查该 ***EOF*** 的消息的前几个字节 - 如果是这样,只需将流清空(或者可能用预期的方式重写它headers) - 如果没有,则将流的位置重置为 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多