没有 XML 模式的单程 EDI 解析 - 可能吗?

Single pass EDI parsing without an XML schema - Possible?

在您叹气并把头埋在手里之前,请理解我在相当紧迫的时间线上使用一个相当旧的系统。

我们有一个用商业语言编写的单程 EDI 解析器。目前,包括循环级别、区域和每个段的名称的数据定义存储在数据库中table。 table 还为区域内的每个段分配一个递增的序列号。例如004010 810 Header区:

等等等

因此,如果您按照片段在标准中出现的顺序阅读这些片段,我们可以说每个片段都可以分配一个序号,一个 "depth"(有多少循环 "down"它出现)和一个名字(2-3 个字符)。

解析器目前遵循的算法如下:

Reset currentArea to 1
For each segment in the document
{
   Search for the segment's name in the table restricting the area >= currentArea.
   If not found, we have an error.
   else
   {
      If the area changed
      {
         empty the temporary "search bounds" table.  Create a single record with upper bound equal to MAX(sequence in current area) and lower bound equal to MIN(sequence in current area).
      }
      If the area did not change
      {
          Search for the next segment with a matching, but only within the bounds of the last "bounds" record created.
          If the segment is found and the loop level changed as a result
          {
             Create a new bounds record with lower bound = MIN(sequence in current loop) and upper bound = MAX(sequence in current loop).
          }
          If the segment is not found within the searched bounds
          {
             "Pop" a bounds record out of the table to widen the search, repeat recursively until a segment having the same name is found.
          }
      }
   }
}

不幸的是,我不确定我是否有时间或手段使用实际的文档架构来实施基于 XML 的解决方案。我目前正在研究几个这样的解析器,它们似乎能够根据模式神奇地安排 EDI,无论它看起来如何。

我面临的问题是:

在 945 文档中,详细信息区域如下所示(摘录):

<DETAIL>
   <LX> 
   <MAN>
   <PAL>
   <N9>
      <W12 (loop header)>
      <G69>
      ...
      <miscellaneous other segments>
      ...
      <LS>
         <LX (loop header)>
         ...
         <miscellaneous other segments in LX loop>
         ...
      <LE>
      ...
</DETAIL>

在我的原始数据中,我们有:

LX*1~ MAN*GM*0000803225000421444452~ N9*2I*12150-1~ W12*CC*2*2*0*EA*101199007289*VN*10007~ N9*李*1~ LX*5~ MAN*GM*0000803225000421444453~ N9*2I*12150-2~ ...(其他细分市场)

根据上述算法,当命中第二个LX段时,当前从W12(W12)中的第一个段到W12(FA。 FA2).因此,当对文档的标准 table 执行搜索时,定义中要找到的下一个 LX 是在 W12 中打开其自身循环的 LX。这是错误的——细节区域实际上是在这里重置,LX 实际上是该区域的第一个段,而不是 W12.LX 循环的开始。由于解析器的天真性质,它无法区分这一点,因为它是基于循环的标准 table 自下而上的搜索。

更改解析器以查看区域的开始(自上而下)而不是当前模型会产生相反的问题。如果贸易伙伴实际上打算打开内部 W12.LX 循环,解析器会将其解释为新详细信息区域的开始。

是否可以使用使用我所描述的 table 中定义的标准的单通道解析器来解决这种情况?找到某种方法将 XML 解决方案破解到我们相当陈旧的系统中是这里唯一的方法吗?由于 EDI 没有 "end tags",我可以确定循环实际上结束的唯一方法是通过文档中的 "looking ahead" 来应对不可能的情况,例如内部 [ 之后出现的 MAN 段=66=](因为详细信息区域必须重置才能再次使用 MAN 段)。

我已无路可走,欢迎提出任何想法。

是的,这可以在单程解析器中完成(我做到了)。
正如您所指出的,正确的循环级别应在 table.
中指示 诀窍是让您跟踪自己在 table.
中的位置 阅读新片段,在 table.
中查找 从读取的 table 中的最后一段开始查找。
table 中的查找有点复杂:
1.新记录可以在同一个循环级别
2. 可以重复相同的循环
3.循环可能已经结束,你需要进一步查看消息
如果没有找到,报错。
如果找到,转到传入文件中的新段等。

据我所知,如果 segments/loops 是强制性的或有条件的,则 绝对 必须包含在 table 中 - 如果您想要一个可以解析所有 message/transaction 类型的通用工具.

实际上,您 运行 遇到的问题是 LS/LE 循环。第二个 LX 循环嵌入在 LS/LE 段中。 LS/LE 是为了解决 'collision' 问题而发明的。如果在 LS 循环中,它应该以 LE 段终止。