EDIFACT Schemas

XML schemas for EDIFACT are included with EDI SDK by default, and can be found in the "schemas\EDIFACT" folder of the installation directory. However, in cases where you need a schema for a proprietary version that isn't included, or if you need to make custom changes within a schema, you can edit the contents of a schema manually. EDI SDK's schemas use an intuitive XML format, where each version of a standard is contained in a single file. That schema format is documented below.

Root Element

To create a new EDIFACT schema, first create the root element and name it based on the EDIFACT version that you want to use, such as "D97A" or "D21B". It will have sections for defining messages, segments that appear in those messages, elements that might appear in a segment, and valid code values for certain elements:

<D23A> <Messages> ... </Messages> <Segments> ... </Segments> <Elements> ... </Elements> <Codes> ... </Codes> </D23A>

Messages

The Messages section contains all defined messages. See the following as an example:

<Messages> <APERAK desc="Application error and acknowledgement" category="Transport"> ... </APERAK> <AUTHOR desc="Authorization" category="Finance"> ... </AUTHOR> ...... </Messages>

A message tag uses the message type as the tag name. It has a "desc" attribute with a human-readable description of the message and a "category" attribute that specifies what category of EDI message it belongs to. The message tag also contains a representation of any segments and groups of segments that appear in the message, like this:

<APERAK desc="Application error and acknowledgement" category="Transport"> <UNH/> <BGM/> <DTM req="0" maxcount="9"/> <FTX req="0" maxcount="9"/> <CNT req="0" maxcount="9"/> <DOCGroup req="0" maxcount="99"> ... </DOCGroup> <RFFGroup req="0" maxcount="9"> ... </RFFGroup> <NADGroup req="0" maxcount="9"> ... </NADGroup> <ERCGroup req="0" maxcount="99999"> ... </ERCGroup> <UNT/> </APERAK>

Every segment or group in a message definition has 2 attributes: "req" and "maxcount".

  • "req" : If 'req="0"' appears, the segment/group is optional. If "req" doesn't appear, the segment/group is considered mandatory.
  • "maxcount": Specifies the maximum number of times the segment or group can appear. Must be an integer value. If "maxcount" is not specified, the segment or group may only appear once.

To add a new message type, add an XML element inside the Messages section, then lay out the structure of the segments that should appear within the message.

Groups contain a list of segments, which can also be further organized into subgroups. For example:

<ERCGroup req="0" maxcount="99999"> <ERC/> <FTX req="0"/> <RFFGroup2 req="0" maxcount="9"> <RFF/> <FTX req="0" maxcount="9"/> </RFFGroup2> </ERCGroup>

Segments

The Segments section contains all defined segments:

<Segments> <AAI desc="Accommodation allocation information"> ... </AAI> <ADI desc="Health care claim adjudication information"> ... </ADI> ...... </Segments>

Every segment has a "desc" attribute, which contains a human-readable description of the segment. It also contains an ordered list of elements that appear within the segment.

To add a new segment, create an XML tag with a matching name and add a list of elements. Elements in the list should be named with the segment name followed by a position, such as "ADI-060" for the sixth element in the ADI segment. <ADI desc="Health care claim adjudication information"> <ADI-010 ref="EE206" maxcount="3"/> <ADI-020 ref="EE021" req="0" maxcount="3"/> <ADI-030 ref="E1229" req="0"/> <ADI-040 ref="EE017" req="0" maxcount="15"/> <ADI-050 ref="E6060" req="0" maxcount="3"/> <ADI-060 ref="EE030" req="0" maxcount="15"/> <ADI-070 ref="E9620" req="0" maxcount="4"/> <ADI-080 ref="E5389" req="0"/> <ADI-090 ref="EE507" req="0"/> <ADI-100 ref="E9639" req="0"/> <ADI-110 ref="E5482" req="0"/> </ADI>

Every element in a segment has 3 attributes: "ref", "req" and "maxcount".

  • "ref" : This value is used to referenced the element in the Elements list (see Section 4).
  • "req" : If 'req="0"' appears, the element is optional. If "req" doesn't appear, the element is considered mandatory.
  • "maxcount" : Specifies the maximum number of times the element can appear. Must be an integer value. If the "maxcount" attribute is not present, the element may only appear once.

Note: Header and footer segments such as UNB, UNG, UNH, UNT, UNE, and UNZ are recognized by the EDIFACT components by default, and do not need to be added to the Segments section.

Elements

The Elements section contains all defined elements. See the following:

<Elements> <E0035 type="N" minlen="1" maxlen="1" desc="Test indicator"/> <E0051 type="AN" minlen="1" maxlen="3" desc="Controlling agency, coded"/> ...... <EC001 type="composite" desc="Transport means"> <C001-010 ref="E8179" req="0"/> <C001-020 ref="E1131" req="0"/> <C001-030 ref="E3055" req="0"/> <C001-040 ref="E8178" req="0"/> </EC001> ...... </Elements>

For each of the elements referenced in a segment, you will need to add the element to the Elements section of the schema. The structure of the XML will depend on whether the element is a simple element (contains only one value) or a composite element (contains multiple related values). All elements' names have the prefix 'E' followed by the element's identifier.

Simple Element

A simple element has 5 attributes ("type", "min", "max", "codes" and "desc") and no child elements: <E1001 type="AN" minlen="1" maxlen="3" codes="C1001" desc="Document name code"/>

  • "type": The valid characters for the value. This can be "A", "AN" or "N". ("A" means alphabetic only; "N" means numeric (0~9) only; "AN" means any alphanumeric character)
  • "minlen" : The minimum length of the value.
  • "maxlen" : The maximum length of the value.
  • "codes" : If this appears, it indicates that the valid values for this element are defined in the Codes element (see Section 5).
  • "desc": A human-readable description of the element.

Composite Element

A composite element's name will have a second letter after the initial 'E'. It also has a "type" attribute (which is always "composite") and a "desc" attribute with a description of the element. It contains tags for each of its component elements, with references to a simple element definition for each component:

<EC001 type="composite" desc="Transport means"> <C001-010 ref="E8179" req="0"/> <C001-020 ref="E1131" req="0"/> <C001-030 ref="E3055" req="0"/> <C001-040 ref="E8178" req="0"/> </EC001>

  • Every component has a name in the format of "[Element Name]-[Component Position]". For example, for component "C001-030", the "Element Name" is "C001", and the "Component Position" is "030"
  • Every component element has 2 attributes: "ref" and "req":
    • "ref" : Contains a reference to the type of simple element that should appear in that location.
    • "req" : If 'req="0"' appears, the component is optional. If the "req" attribute doesn't appear, the component is mandatory.

After adding a composite element, each of its components should be added to the Elements section as simple elements as well.

Codes

The Codes element contains all defined codes, which specify the valid values for elements. See the following:

<Codes> <C1001 desc="Document name code"> ... </C1001> <C1049 desc="Message section code"> ... </C1049> ...... <Codes>

For any elements that have a "codes" attribute, create an entry in the Codes section of the schema. The name of the XML element should start with C and match the value in the "codes" attribute of the element that uses the list. The only attribute is the "desc" attribute, which contains a human-readable description of the code.

For each valid value, add an "Item" element with a "value" attribute containing the value. The item should also have a "desc" attribute describing its meaning.

<C1049 desc="Message section code"> <Item value="1" desc="Heading section"/> <Item value="2" desc="Detail section"/> <Item value="5" desc="Multiple sections"/> <Item value="6" desc="Summary section"/> <Item value="7" desc="Sub-line item"/> <Item value="8" desc="Commercial heading section of CUSDEC"/> <Item value="9" desc="Commercial line detail section of CUSDEC"/> <Item value="10" desc="Customs item detail section of CUSDEC"/> <Item value="11" desc="Customs sub-item detail section of CUSDEC"/> </C1049>

Once all of the codes have been added, the schema should be ready for use. To test it, you can try loading the schema in the EDIFACTReader component and parsing a message of the appropriate type:

EDIFACTReader reader = new EDIFACTReader(); reader.LoadSchema("C:/Path/to/D23A.xml", "APERAK"); reader.InputFile = "C:/Path/to/Example_APERAK.edi"; reader.Parse();

X12 Schemas

X12 schemas cannot be included with EDI SDK due to licensing restrictions put in place by x12.org, which prohibit redistribution of X12 schema definitions. Instead, the XML schemas must either be imported from the official schemas provided by x12.org or created manually.

Importing from the official X12 Schemas

To import files from an official X12 schema, you will first need to download a ZIP file containing the XSD files from x12.org. Next, you can use the X12Import tool (located in the installation directory at "schemas\X12\x12import.exe") to convert the ZIP file to the EDI SDK XML schema format. x12import.exe requires the path to the ZIP file as an argument:

./x12import.exe "C:/Path/To/X12/Official/Schema.zip"

Any imported schemas will automatically be placed in the "schemas\X12" folder, ready to be used for EDI Object generation.

Creating Your Own X12 Schema

EDI SDK's schemas use an intuitive XML format, where each version of a standard is contained in a single file. That schema format is documented below, allowing you to create your own schema file in cases where an official schema file is not available.

Root Element

To start creating an X12 schema, add the root element and name it based on the version of the standard that you want to use, such as "R5010" or "R8030". It will contain sections for defining transaction sets, segments that appear in those transaction sets, elements that might appear in a segment, and valid code values for certain elements:

<R5010> <TransactionSets> ... </TransactionSets> <Segments> ... </Segments> <Elements> ... </Elements> <Codes> ... </Codes> </R5010>

Transaction Sets

The TransactionSets section contains all defined transaction sets. See the following as an example:

<TransactionSets> <T100 desc="Insurance Plan Description" category="Insurance"> ... </T100> <T101 desc="Name and Address Lists" category="Supply Chain"> ... </T101> ...... </TransactionSets>

A transaction set tag uses the transaction type as the tag name. It has a "desc" attribute with a human-readable description of the transaction set and a "category" attribute that specifies what category of EDI transaction it belongs to. The tag also contains a representation of any segments and loops of segments that appear in the transaction set, like this:

<T101 desc="Name and Address Lists" category="Supply Chain"> <ST/> <BGN/> <DTMLoop maxcount="unlimited"> <DTM/> <N1 maxcount="unlimited"/> <N9Loop req="0" maxcount="unlimited"> <N9/> <LXLoop maxcount="unlimited"> <LX/> <IN2 req="0" maxcount="unlimited"/> <NX2 req="0" maxcount="unlimited"/> <REF req="0" maxcount="unlimited"/> <SPA req="0"/> <COM req="0" maxcount="unlimited"/> </LXLoop> </N9Loop> </DTMLoop> <SE/> </T101>

Every segment or loop in a transaction set definition has 2 attributes: "req" and "maxcount".

  • "req" : If 'req="0"' appears, the segment/loop is optional. If "req" doesn't appear, the segment/loop is considered mandatory.
  • "maxcount": Specifies the maximum number of times the segment or loop can appear. This can either be "unlimited" or a specific integer value. If "maxcount" is not specified, the segment or loop may only appear once.

To add a new transaction set, add an XML element inside the TransactionSets section, then lay out the structure of the segments that should appear within the transaction set.

Loops contain a list of segments, which can contain nested loops. For example:

<N9Loop req="0" maxcount="unlimited"> <N9/> <LXLoop maxcount="unlimited"> <LX/> <IN2 req="0" maxcount="unlimited"/> <NX2 req="0" maxcount="unlimited"/> <REF req="0" maxcount="unlimited"/> <SPA req="0"/> <COM req="0" maxcount="unlimited"/> </LXLoop> </N9Loop>

Segments

The Segments section contains all defined segments:

<Segments> <AAA desc="Request Validation"> ... </AAA> <ACD desc="Account Description"> ... </ACD> ...... </Segments>

Every segment has a "desc" attribute, which contains a human-readable description of the segment. It also contains an ordered list of elements that appear within the segment.

To add a new segment, create an XML tag with a matching name and add a list of elements. Elements in the list should be named with the segment name followed by a position, such as "ACT-06" for the sixth element in the ADI segment. <ACT desc="Account Identification"> <ACT-01 ref="E508"/> <ACT-02 ref="E93" req="0"/> <ACT-03 ref="E66" req="0" rule="P0304"/> <ACT-04 ref="E67" req="0"/> <ACT-05 ref="E569" req="0" rule="C0506"/> <ACT-06 ref="E508" req="0"/> <ACT-07 ref="E352" req="0" rule="C0705"/> <ACT-08 ref="E107" req="0"/> <ACT-09 ref="E1216" req="0"/> </ACT>

Every element in a segment has 3 attributes: "ref", "req" and "maxcount".

  • "ref" : This value is used to referenced the element in the Elements list (see Section 4).
  • "req" : If 'req="0"' appears, the element is optional. If "req" doesn't appear, the element is considered mandatory.
  • "rule" : Specifies when the segment appears relative to other segments. A rule consists of a letter that specifies the type of rule and two or more two-digit element numbers indicating which elements within the segment the rule applies to:
    • 'C' : Conditional - If the first element appears, all the other listed elements are mandatory. If the first element is absent, the other elements are optional.
    • 'L' : List Conditional - If the first element appears, at least one of the other listed elements must appear.
    • 'P' : Paired - If any of the listed elements appear, all of the listed elements must be present.
    • 'R' : Required - At least one of the listed elements must appear in the segment.
    • 'E' : Exclusive - At most one of the listed elements may appear in the segment.

Note: Header and footer segments such as ISA, IAE, GS, GE, ST, and SE are recognized by the X12 components by default, and do not need to be added to the Segments section.

Elements

The Elements section contains all defined elements. See the following:

<Elements> ...... <E7 type="AN" minlen="6" maxlen="17" desc="Bank Account Number"/> <E8 type="ID" minlen="1" maxlen="1" codes="C8" desc="Bank Client Code"/> ...... <EC002 type="composite" desc="Actions Indicated"> <C002-01 ref="E704"/> <C002-02 ref="E704" req="0"/> <C002-03 ref="E704" req="0"/> <C002-04 ref="E704" req="0"/> <C002-05 ref="E704" req="0"/> </EC002> ...... </Elements>

For each of the elements referenced in a segment, you will need to add the element to the Elements section of the schema. The structure of the XML will depend on whether the element is a simple element (contains only one value) or a composite element (contains multiple related values). All elements' names have the prefix 'E' followed by the element's identifier.

Simple Element

A simple element has 5 attributes ("type", "min", "max", "codes" and "desc") and no child elements: <E1001 type="AN" minlen="1" maxlen="3" codes="C1001" desc="Document name code"/>

  • "type": The valid characters for the value. This can be "A", "AN" or "N". ("A" means alphabetic only; "N" means numeric (0~9) only; "AN" means any alphanumeric character)
  • "minlen" : The minimum length of the value.
  • "maxlen" : The maximum length of the value.
  • "codes" : If this appears, it indicates that the valid values for this element are defined in the Codes element (see Section 5).
  • "desc": A human-readable description of the element.

Composite Element

A composite element's name will have a second letter after the initial 'E'. It also has a "type" attribute (which is always "composite") and a "desc" attribute with a description of the element. It contains tags for each of its component elements, with references to a simple element definition for each component:

<EC002 type="composite" desc="Actions Indicated"> <C002-01 ref="E704"/> <C002-02 ref="E704" req="0"/> <C002-03 ref="E704" req="0"/> <C002-04 ref="E704" req="0"/> <C002-05 ref="E704" req="0"/> </EC002>

  • Every component has a name in the format of "[Element Name]-[Component Position]". For example, for component "C001-030", the "Element Name" is "C001", and the "Component Position" is "030"
  • Every component element has 2 attributes: "ref" and "req":
    • "ref" : Contains a reference to the type of simple element that should appear in that location.
    • "req" : If 'req="0"' appears, the component is optional. If the "req" attribute doesn't appear, the component is mandatory.

After adding a composite element, each of its components should be added to the Elements section as simple elements as well.

Codes

The Codes element contains all defined codes, which specify the valid values for elements. See the following:

<Codes> <C8 desc="Bank Client Code"> ... </C8> <C9 desc="Late Reason Code"> ... </C9> ...... <Codes>

For any elements that have a "codes" attribute, create an entry in the Codes section of the schema. The name of the XML element should start with C and match the value in the "codes" attribute of the element that uses the list. The only attribute is the "desc" attribute, which contains a human-readable description of the code.

For each valid value, add an "Item" element with a "value" attribute containing the value. The item should also have a "desc" attribute describing its meaning.

<C8 desc="Bank Client Code"> <Item value="E" desc="Payee"/> <Item value="R" desc="Payer"/> </C8>

Once all of the codes have been added, the schema should be ready for use. To test it, you can try loading the schema in the X12Reader component and parsing a transaction of the appropriate type:

X12Reader reader = new X12Reader(); reader.LoadSchema("C:/Path/to/R5010.xml", "T101"); reader.InputFile = "C:/Path/to/Example_T101.edi"; reader.Parse();

EDI Objects

EDI Objects in EDI SDK provide a strongly typed, schema-driven API for EDI documents. Rather than navigating segments by tag names or tracking element positions with numeric indexes, EDI Objects model EDI documents as an object hierarchy that mirrors the underlying schema. They allow applications to read, write, and validate EDI documents using the underlying EDI SDK reader and writer components.

Generating EDI Objects

Object generation is schema-driven, which guarantees that the resulting API matches the structure and constraints defined by the EDI specification. All generated message types follow a consistent naming and object model.

For EDIFACT, all standard UNECE releases are included in the install directory of EDI SDK under /schemas/edifact. X12 schemas are not included due to licensing restrictions. For details, see X12 Schemas.

EDIObjects.exe is a command line tool used to generate the EDI Object classes from our XML Schemas. For example: ./ediobjects.exe "/path/to/D87A.xml" -m INVOIC,DESADV -o "/path/to/EDIFACT/" -l java ./ediobjects.exe "/path/to/4010.xml" -m 810,850 -o "/path/to/X12Out/" -l java

Command Arguments Usage: ediobjects <input-file> [options] <input-file> An XML schema file (e.g. D96B.xml, 4010.xml) Options: -m, --messages <msg1,msg2,...> For EDIFACT: Comma-separated list of message(transactionset) types to process (for example: INVOIC,ORDERS). If not specified, all messages are processed. -t, --transactionsets <tSet1,tSet2,...> For X12: Comma-separated list of transaction set types to process (for example: T810,T820). If not specified, all transaction sets are processed. -o, --output <directory> Output directory for generated source code. -l, --lang <net | java ...> Target language for code generation. Default: net All generated classes for a standard are required at runtime. Together, they provide full support for parsing, validating, creating, and writing EDI messages for the specified standard and version.

EDI Object API Model

EDI Objects provide a strongly typed, schema-driven API for EDI documents, built on top of the core reader components (EDIFACTReader or X12Reader). Calling Read constructs the object hierarchy, and exposes events for applications that need to respond to data as it is parsed.

EDI Objects support two primary processing patterns. Event-driven processing allows applications to respond to data as it is parsed through events such as OnStartMessage and OnSegment. Object-model traversal allows applications to access the fully populated object hierarchy after parsing is complete, providing strongly typed access to messages and segments.

Event-Driven Processing

Event-driven processing gives access to schema-validated objects during parsing. Common events include

  • OnStartInterchange
  • OnStartMessage
  • OnSegment
  • OnEndMessage
  • OnEndInterchange

Applications can inspect objects, initialize state, or trigger downstream logic as data arrives: edifact.OnStartMessage += (s, e) => { IMessage msg = e.Message; if(msg.GetType() == typeof(INVOIC)){ // Inspect or record data for later processing GenerateInvoice(msg.Reference); } }; Object-Model Traversal

With object-model traversal, applications call Read and then access the fully populated hierarchy. This provides strongly typed access to interchanges, messages, and segments, suitable for logic that depends on fully parsed data. edifact.Read("invoice.edi"); foreach (Interchange inter in edifact.Interchanges) { foreach (IMessage message in inter.Messages) { INVOIC invoice = (INVOIC)message; string invoiceNumber = invoice.BGM.DocumentMessageNumber; foreach (INVOIC_LineItem item in invoice.LineItems) { // Process line items } } }

Possible Errors

Errors generated by non-conformant EDI documents can be found under ErrorDetails in the top-level standard object after a Read or Write operation. Each ErrorDetail provides the location of the error using object indexes, along with an ErrorCode and ErrorMessage.

A specific type of error may occur during a Read operation if the preceding operation attempts to generate a message type that is not defined in the currently loaded schema. When this happens, parsing will fail with an error message like: "Type nsoftware.EDIFACT.release.message not found. No matching schema loaded."

Resolving this error requires ensuring that the schema contains a definition for the missing message.