没有 XML 模式的单程 EDI 解析 - 可能吗?
Single pass EDI parsing without an XML schema - Possible?
在您叹气并把头埋在手里之前,请理解我在相当紧迫的时间线上使用一个相当旧的系统。
我们有一个用商业语言编写的单程 EDI 解析器。目前,包括循环级别、区域和每个段的名称的数据定义存储在数据库中table。 table 还为区域内的每个段分配一个递增的序列号。例如004010 810 Header区:
- 片段序列
- 大 5
- NTE 10
- 15 元
- REF 20
- YNQ 25
- 每 30
- N1(循环开始)35
- N2 40
等等等
因此,如果您按照片段在标准中出现的顺序阅读这些片段,我们可以说每个片段都可以分配一个序号,一个 "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 段终止。
在您叹气并把头埋在手里之前,请理解我在相当紧迫的时间线上使用一个相当旧的系统。
我们有一个用商业语言编写的单程 EDI 解析器。目前,包括循环级别、区域和每个段的名称的数据定义存储在数据库中table。 table 还为区域内的每个段分配一个递增的序列号。例如004010 810 Header区:
- 片段序列
- 大 5
- NTE 10
- 15 元
- REF 20
- YNQ 25
- 每 30
- N1(循环开始)35
- N2 40
等等等
因此,如果您按照片段在标准中出现的顺序阅读这些片段,我们可以说每个片段都可以分配一个序号,一个 "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 段终止。