我使用 EDIFACT 消息并开发了许多工具来帮助我从原始文件格式中解析和提取相关信息。
我一直在努力解决的问题是展示原始的 EDIFACT。我通常只是将消息复制到 Microsoft Word 中,对段分隔符进行查找和替换,然后逐行查看内容。
我一直想以层次结构格式显示 EDIFACT 文件,但我一生都无法找到一种方法来做到这一点。
下面是原始 EDIFACT 消息的一小部分摘录。左侧显示了我如何获取数据(不包括行号),右侧显示了我希望如何根据客户规范显示它。
01. UNA -UNA
02. UNB -UNB
03. UNH -UNH
04. BGM -BGM
05. DTM - | DTM
06. DTM - | DTM
07. DTM - | DTM
08. NAD - | NAD
09. NAD - | NAD
10. NAD - | NAD
11. GIS - | GIS
12. LIN - | | LIN
13. LOC - | | | LOC
14. LOC - | | | LOC
15. LOC - | | | LOC
16. RFF - | | | RFF
17. QTY - | | | QTY
18. QTY - | | | QTY
19. RFF - | | | | RFF
20. DTM - | | | | | DTM
21. SCC - | | | SCC
22. QTY - | | | | QTY
23. DTM - | | | | | DTM
24. DTM - | | | | | DTM
25. SCC - | | | SCC
26. QTY - | | | | QTY
27. DTM - | | | | | DTM
28. DTM - | | | | | DTM
29. SCC - | | | SCC
30. QTY - | | | | QTY
31. DTM - | | | | | DTM
32. QTY - | | | | QTY
33. DTM - | | | | | DTM
34. SCC - | | | SCC
35. QTY - | | | | QTY
36. DTM - | | | | | DTM
37. NAD - | | | NAD
38. CTA - | | | | CTA
39. COM - | | | | | COM
40. SCC - | | | | SCC
41. QTY - | | | | | QTY
42. UNT -UNT
43. UNZ -UNZ
您可以看到数据是基于树的,并且由发送给我的规范描述。上述 EDIFACT 消息的一种规范如下:
Tag St Max Lvl
0000 1 UNA C 1 0 SERVICE STRING ADVICE
0000 2 UNB M 1 0 INTERCHANGE HEADER
0010 3 UNH M 1 0 MESSAGE HEADER
0020 4 BGM M 1 0 BEGINNING OF MESSAGE
0030 5 DTM M 10 1 DATE/TIME/PERIOD
0040 6 FTX C 5 1 FREE TEXT
0080 SG2 C 99 1 NAD
0090 7 NAD M 1 1 NAME AND ADDRESS
0190 SG6 C 9999 1 GIS-SG7-SG12
0200 8 GIS M 1 1 GENERAL INDICATOR
0210 SG7 C 1 2 NAD
0220 9 NAD M 1 2 NAME AND ADDRESS
0370 SG12 C 9999 2 LIN-LOC-FTX-SG13-SG15-SG17-SG22
0380 10 LIN M 1 2 LINE ITEM
0450 11 LOC C 999 3 PLACE/LOCATION IDENTIFICATION
0470 12 FTX C 5 3 FREE TEXT
0480 SG13 C 10 3 RFF
0490 13 RFF M 1 3 REFERENCE
0540 SG15 C 10 3 QTY-SG16
0550 14 QTY M 1 3 QUANTITY
0570 SG16 C 10 4 RFF-DTM
0580 15 RFF M 1 4 REFERENCE
0590 16 DTM C 1 5 DATE/TIME/PERIOD
0600 SG17 C 999 3 SCC-SG18
0610 17 SCC M 1 3 SCHEDULING CONDITIONS
0620 SG18 C 999 4 QTY-DTM
0630 18 QTY M 1 4 QUANTITY
0640 19 DTM C 2 5 DATE/TIME/PERIOD
0760 SG22 C 999 3 NAD-SG24-SG27
0770 20 NAD M 1 3 NAME AND ADDRESS
0830 SG24 C 5 4 CTA-COM
0840 21 CTA M 1 4 CONTACT INFORMATION
0850 22 COM C 5 5 COMMUNICATION CONTACT
0920 SG27 M 999 4 SCC-SG28
0940 SG28 M 999 5 QTY
0950 24 QTY M 1 5 QUANTITY
1030 25 UNT M 1 0 MESSAGE TRAILER
0000 26 UNZ M 1 0 INTERCHANGE TRAILER
重要的列是 Tag、St(M=Mandatory,C=Conditional)、Max(可以重复的最大次数)、lvl(树的深度)。以 SG 开头的标签表示存在循环
我面临的问题是格式非常灵活,可以有条件段、条件循环、重复段。试图想出一种可以处理这一切的方法一直是我的问题。
从上面规范的顶部开始,您可以立即看到,当您来到 DTM 标签时,它最多可以重复 10 次。在示例 EDIFACT 消息中,它仅在第 5、6、7 行出现了 3 次。按照规范,FTX 可能会出现但不会出现在我的示例消息中,然后有一个 SG2 标记,这意味着下面的 NAD 标记可能重复 99次。
在 LIN 标签(SG12 组下,可以重复多达 9999 次,并且在许多情况下确实重复多次)内稍微向前移动,它来到了第一个 QTY 标签。根据规范,这个段可以有条件组(SG15)RFF和它下面的一个DTM。使用我的示例,您可以在第 17 行和第 18 行看到它有 QTY 段,但第 18 行也有这个条件组。
当您查看 SCC 细分市场时,类似的事情也开始发生。
我的想法是能够将该规范输入某种文件格式,然后根据该规范的规则运行原始 EDIFACT 消息,以便输出基于层次结构,以便一目了然地查看哪些数据涉及到什么段以及检查 EDIFACT 消息是否有效的方法。
我遇到的麻烦是进行该转换的实际算法或过程。
我尝试过幼稚的方法,例如逐行进行,但是当我尝试确定当前行是在一个组中,还是重复或其他内容时,它会变得混乱。我尝试了一种递归方法,通过将整个 EDIFACT 按最大组(SG12-LIN 组)拆分,然后递归处理每个拆分并构建输出。这是我迄今为止最好的方法,但由于我的逻辑不正确,它距离处理许多错误读数还很远。
我基本上需要能够选择消息的一部分,并确定它应该在层次结构中的哪个位置并显示它。
我不知道如何解决这个问题。我确信有一个很好的简单方法可以做到这一点,但我就是无法解决。
任何帮助将不胜感激。
轻微更新。
我已按照所述规范的层次结构将规范转换为 XML 文件。该 XML 文件现在包含与每个标签相关的所有组和各种属性。现在我也开始了解 EDIFACT 需要遵守的内容。
如果我在纸上(和头脑中)通过它,我可以通过一些前瞻性思维来构建我想要做的输出,所以我的新想法是在 EDIFACT 文件中“向前扫描”,并构建一个可能基于结果。有点像国际象棋人工智能如何向前看几步。