如何识别EDIFACT文件数据含义并映射Java模型类变量?
EDIFACT转XML后的数据映射难题
我用edireader把UN/EDIFACT文件转成了XML格式,示例如下:
原始UN/EDIFACT文件
UNB+UNOA:1+US::US+50138::THEM+140531:0305+001934++ORDERS' UNH+1+ORDERS:91:2:UN' BGM+220+A761902+4:20140530:102+9' RFF+CT:EUA01349' RFF+AAV::C' TXT+THIS IS WHAT AN EDI MESSAGE WOULD LOOK LIKE... ' NAD+BY++OUR NAME PLC::::+++++EW4 34J' CTA+PD' COM+01752 253939:TE+01752 253939:FX+0:TL' CTA+OC+:A.SURNAME' COM+2407:EX' CTA+TI+:B.BROWN' COM+0:EX' CTA+SU' COM+0161 4297476:TE+01752 670633:FX' UNT+15+1' UNZ+1+001934'
转换后的XML文件
<?xml version="1.0" encoding="UTF-8"?> <ediroot> <interchange Standard="EDIFACT" SyntaxId="UNOA" SyntaxVersion="1" Date="140531" Time="0305" Control="001934" ApplRef="ORDERS" Decimal="."> <sender> <address Id="US" Qual="" Extra="US"/> </sender> <receiver> <address Id="50138" Qual="" Extra="THEM"/> </receiver> <group> <transaction Control="1" DocType="ORDERS" Version="91" Release="2" Agency="UN"> <segment Id="BGM"> <element Id="BGM01">220</element> <element Id="BGM02">A761902</element> <element Id="BGM03" Composite="yes"> <subelement Sequence="1">4</subelement> <subelement Sequence="2">20140530</subelement> <subelement Sequence="3">102</subelement> </element> <element Id="BGM04">9</element> </segment> <segment Id="RFF"> <element Id="RFF01" Composite="yes"> <subelement Sequence="1">CT</subelement> <subelement Sequence="2">EUA01349</subelement> </element> </segment> <segment Id="RFF"> <element Id="RFF01" Composite="yes"> <subelement Sequence="1">AAV</subelement> <subelement Sequence="3">C</subelement> </element> </segment> <segment Id="TXT"> <element Id="TXT01">THIS IS WHAT AN EDI MESSAGE WOULD LOOK LIKE... </element> </segment> <segment Id="NAD"> <element Id="NAD01">BY</element> <element Id="NAD03" Composite="yes"> <subelement Sequence="1">OUR NAME PLC</subelement> </element> <element Id="NAD08">EW4 34J</element> </segment> <segment Id="CTA"> <element Id="CTA01">PD</element> </segment> <segment Id="COM"> <element Id="COM01" Composite="yes"> <subelement Sequence="1">01752 253939</subelement> <subelement Sequence="2">TE</subelement> </element> <element Id="COM02" Composite="yes"> <subelement Sequence="1">01752 253939</subelement> <subelement Sequence="2">FX</subelement> </element> <element Id="COM03" Composite="yes"> <subelement Sequence="1">0</subelement> <subelement Sequence="2">TL</subelement> </element> </segment> <segment Id="CTA"> <element Id="CTA01">OC</element> <element Id="CTA02" Composite="yes"> <subelement Sequence="2">A.SURNAME</subelement> </element> </segment> <segment Id="COM"> <element Id="COM01" Composite="yes"> <subelement Sequence="1">2407</subelement> <subelement Sequence="2">EX</subelement> </element> </segment> <segment Id="CTA"> <element Id="CTA01">TI</element> <element Id="CTA02" Composite="yes"> <subelement Sequence="2">B.BROWN</subelement> </element> </segment> <segment Id="COM"> <element Id="COM01" Composite="yes"> <subelement Sequence="1">0</subelement> <subelement Sequence="2">EX</subelement> </element> </segment> <segment Id="CTA"> <element Id="CTA01">SU</element> </segment> <segment Id="COM"> <element Id="COM01" Composite="yes"> <subelement Sequence="1">0161 4297476</subelement> <subelement Sequence="2">TE</subelement> </element> <element Id="COM02" Composite="yes"> <subelement Sequence="1">01752 670633</subelement> <subelement Sequence="2">FX</subelement> </element> </segment> </transaction> </group> </interchange> </ediroot>
我打算用XML转Java模型的工具做数据映射,但现在卡壳了:搞不懂EDIFACT里各个字段的具体含义,也不知道Java类里该定义哪些变量来对应这些数据。
解决思路
1. 先搞懂EDIFACT字段含义
- 查对应报文的EDIFACT规范:你这个是ORDERS订单报文,找UN/EDIFACT ORDERS的官方规范,里面会明确每个段(比如UNB、BGM、NAD)、每个元素(比如BGM01、BGM02)的含义。举个例子:
UNB是交换头段,用来标识整个EDI交换的基本信息;BGM是业务报文头段,其中BGM01是报文类型代码(220代表订单),BGM02是订单编号;NAD是名称地址段,NAD01的BY表示这个是买方信息,NAD03是买方名称,NAD08是买方邮编。
- 结合edireader的XML输出:XML里的
segment Id就是EDIFACT的段代码,element Id是「段代码+序号」,比如RFF01就是RFF段的第一个复合元素,里面的子元素对应EDIFACT里的组分隔符(冒号)拆分的内容。
2. 构建Java模型类
分两种思路,按需选择:
- 通用模型(适配所有EDIFACT报文):直接对应XML的层级结构创建类,适合需要处理多种EDIFACT报文的场景:
// 根节点 public class EdiRoot { private Interchange interchange; // getters & setters } // 交换层 public class Interchange { private String standard; private String syntaxId; private Sender sender; private Receiver receiver; private List<Group> groups; // 其他属性+getters & setters } // 发送方/接收方 public class Sender { private Address address; // getters & setters } public class Address { private String id; private String qual; private String extra; // getters & setters } // 事务段(对应单个订单报文) public class Transaction { private String control; private String docType; private List<Segment> segments; // getters & setters } // 段元素 public class Segment { private String id; private List<Element> elements; // getters & setters } // 数据元素 public class Element { private String id; private boolean composite; private List<Subelement> subelements; private String value; // 非复合元素用这个 // getters & setters } // 复合元素的子元素 public class Subelement { private int sequence; private String value; // getters & setters } - 业务模型(只适配ORDERS报文):把通用的Segment换成具体的业务类,变量名用有业务含义的名称,更易维护:
public class OrderTransaction { private String transactionControlNumber; private BgmSegment bgm; // 订单头 private List<RffSegment> rffList; // 参考信息 private NadSegment buyerNad; // 买方信息 private List<CtaSegment> ctaList; // 联系人信息 // 其他业务字段+getters & setters } public class BgmSegment { private String documentTypeCode; // BGM01,对应220 private String documentNumber; // BGM02,对应A761902 private DocumentDate compositeDate; // BGM03的复合元素 private String functionCode; // BGM04,对应9 // getters & setters } public class DocumentDate { private String dateTypeCode; // 子元素1,对应4 private String date; // 子元素2,对应20140530 private String dateQualifier; // 子元素3,对应102 // getters & setters }
3. 工具使用技巧
用JAXB或Jackson XML工具先根据XML生成初始的Java类,然后手动修改:
- 把自动生成的
elementId这类无意义的变量名,换成对应EDIFACT字段含义的名称; - 给每个变量加注释,说明对应EDIFACT的哪个段/元素、含义是什么;
- 对于复合元素,可以拆分成单独的子类,比如把BGM03的复合元素做成
DocumentDate类。
内容的提问来源于stack exchange,提问作者iwritecomeinmymind
相关产品推荐
相关产品推荐

