读取 EDI 格式的文件
Posted
技术标签:
【中文标题】读取 EDI 格式的文件【英文标题】:Reading EDI Formatted Files 【发布时间】:2011-01-08 05:48:03 【问题描述】:我是 EDI 新手,我有一个问题。
我了解到,您可以通过查看 ISA 行的最后 3 个字符来获得有关 EDI 格式的大部分信息。如果每个 EDI 都使用换行符来分隔实体,这很好,但我发现许多是单行文件,其中有任意数量的字符用作换行符。我注意到我解析的每个 EDI 中的最后一个字符是中断字符。我看了几百个,没有发现任何例外。如果我首先抓取该字符,并使用它来获取 ISA 行的最后 3 行,我是否应该合理地期望我能够解析来自 EDI 的数据?
我不知道这是否有帮助,但有问题的 EDI“类型”往往是 850、875。我不确定这是否是标准,但可能值得一提。
【问题讨论】:
2010 年的 EDI?我认为 XML 更容易使用 90% 的收入来自 EDI。沃尔玛、塔吉特、玩具反斗城和其他大型零售商占其中的 50%。我们使用 EDI 不是因为我们喜欢它,我们使用它是因为我们的客户喜欢它。这些大型零售商不值得花时间/金钱换成另一种形式,因为它确实有效。 当我说 90% 的收入时,我希望人们理解我的意思是我公司收入的 90%。 【参考方案1】:edi 的交易类型并不重要(850 = 订单,875 = 杂货店)。编写了一些 edi 解析器,以下是我发现的一些内容:
您应该能够指望 ISA(和仅 ISA)是固定宽度的(如果没有记错的话,105 个字符)。 去掉前 105 个字符。之后和第一次出现“GS”之前的所有内容都是您的行终止符(这可以是任何东西,包括一个 0x07 - 哔声 - 所以请注意您是否输出到标准输出进行调试,或者您可能会有一堆哔声出扬声器)。通常这是 1 或 2 个字符,有时可能更多(如果向您发送数据的人出于某种原因添加了额外的终止符)。一旦有了行终止符,就可以获得段(字段)分隔符。我通常会拉出 GS 行的第 3 个字符并使用它,尽管 ISA 行的第 4 个字符也应该可以工作。
还要注意,您可以获得包含多个 ISA 的文件。在这种情况下,您不能指望每个 ISA 中的行或字段分隔符都相同。
另一件事.. edi 文件也有可能(同样,不确定其规范)具有可变长度的 ISA。这是非常罕见的,但我不得不适应它。如果发生这种情况,您必须将该行解析为其字段。 ISA 中的最后一个字段只有一个字符长,因此您可以从中确定 ISA 的实际长度。如果是我,除非你看到类似的文件,否则我不会担心这个。这是一种罕见的情况。
我上面所说的可能不是“规范”的字母......也就是说,我不确定在同一个文件中使用不同的行分隔符是否合法,但在不同的 ISA 中,但它在技术上是可行的,我可以容纳它,因为我必须处理以这种方式通过的文件。我使用的 edi 处理器每天处理超过 5000 个文件,其中包含超过 3000 个可能的数据源(所以我看到了很多奇怪的东西)。
最好的问候, 不要
【讨论】:
唐,这是一个很好的回应。我想我可以指望文件的最后一个字符作为我的行终止符,但这只有在使用单个 ISA 时才是正确的,即使那样,它也不能适应使用超过 1 个字符的情况作为行终止符。在我工作的每个 EDI 中,我没有看到超过一个 ISA,也没有看到任何超过单个字符作为行终止符的东西,但我不妨为此做好准备。 你要小心。我看到很多文件中人们在行终止符之后放置了一个或两个额外的字符......通常是一个空或两个(0x00)。我要做的是首先规范化文件中的行终止符 - 即使用 0x0D/0x0A 作为行终止符重写文件。我这样做是因为它使文件在文本编辑器中易于阅读。然后我浏览文件并确保每个 ISA 都有一个匹配的 IEA。如果在 IEA 之后有额外的数据,我通常会丢弃它。如果 IEA 之后的数据以 ISAt 开头,则表示它是部分传输(错误情况)。 哎呀,我的意思是说“最后一行终止符之后的一两个额外字符”......在文件末尾。 唐,我很好奇您是否遇到过超过 1 个字符的 SEGMENT 终止符。正如你提醒我的那样,我知道线路终结符可能是这样(虽然我还没有看到)。 我见过它,但它非常罕见 - 我与很多相关方打交道,有时他们中的一个会将以前单独的数据放入一个文件中并导致这种情况。我的软件处理它(我认为)。我不会担心的。让发件人修复问题可能比适应它更容易。【参考方案2】:EDI 内容由段和元素组成。
要解析它,你需要先把它分解成段,然后像这样的元素(在 php 中):
<?php
$edi = "YOUR EDIT STRING!";
$segment_delimeter = "~";
$element_delimeter = "*";
//First break it into segments
$segments = explode($segment_delimiter, $edi);
//Now break each segment into elements
$segs_and_elems = array();
foreach($segments as $segment)
$segs_and_elems[] = explode(element_delimeter, $segment);
//To echo out what type of EDI this is for example:
foreach($segs_and_elems as $seg)
if($seg[0] == "GS") echo($seg[1]);
?>
希望这有助于您入门。
【讨论】:
【参考方案3】:对于标头信息,以下 java 将让您轻松获得基本信息。 C# 也有拆分,代码看起来非常相似
try
String sCurrentLine;
fileContent = new BufferedReader(new FileReader(filePathName));
sCurrentLine = fileContent.readLine();
// get the delimiter after ISA, if you know your field delimiter just force it.
// we look at lots of different senders messages so never sure what it will be.
delimiterElement = sCurrentLine.substring(3,1); // Grab the delimiter they are using
String[] splitMessage = sCurrentLine.split(delimiterElement,16); // to get the messages if everything is on one line of course
senderQualifier = splitMessage[5]; //who sent something we need fixed qualifier
senderID = splitMessage[6]; //who sent something we need fixed alias
ISA = splitMessage[13]; // Control number
testIndicator = splitMessage[15];
dateStamp = splitMessage[9];
timeStamp = splitMessage[10];
... do stuff with the pieces of info ...
【讨论】:
以上是关于读取 EDI 格式的文件的主要内容,如果未能解决你的问题,请参考以下文章