This project has moved. For the latest updates, please go here.

X12 Interchange Model

The X12 Parser is designed around a set of objects that get loaded with the help of an X12Parser object. Once loaded, the Interchange object can operate without any further assistance from the X12Parser.

You can use these objects to:

  1. Read an existing X12 file without the use of the XML transformations.
  2. Load an existing X12 file and make modifications without disturbing any segments that you do not explicit change.
  3. Create a new X12 document using a built in or custom transaction specification.


An X12 envelop starts with an Interchange surrounding a set of Function Groups surrounding a set of Transactions.
The transactions can hold individual segments, loops or hierarchical loops. The following domain model represents these objects with the least repetition of their common characteristics.

ParsingModel.png

Let's look at how to use these objects with some code samples to work with the following 270 Eligibility Inquiry x12:

INTERCHANGE
ISA *00 * *00 * *01 *9012345720000 *01 *9088877320000 *020816 *1144 *U *00401 *000000031 *1 *T *:~
FUNCTION GROUP
GS *HS *901234572000 *908887732000 *20070816 *1615 *31 *X *005010X279~
TRANSACTION
ST *270 *1234 *005010X279~
BHT *0022 *13 *10001234 *20060501 *1319~
Information Source Level
HL *1 * *20 *1~
Information Source Name
NM1 *PR *2 *ABC COMPANY * * * * *PI *842610001~
Information Receiver Level
HL *2 *1 *21 *1~
Information Receiver Name
NM1 *1P *2 *BONE AND JOINT CLINIC * * * * *SV *2000035~
Subscriber Level
HL *3 *2 *22 *0~
TRN *1 *93175-012547 *9877281234~
Subscriber Name
NM1 *IL *1 *SMITH *ROBERT * * * *MI *11122333301~
DMG *D8 *19430519~
DTP *291 *D8 *20060501~
Subscriber Eligibility or Benefit Inquiry
EQ *30~
SE *13 *1234~
GE *1 *31~
IEA *1 *000000031~

Reading an existing X12 file

The following code sample shows loading an Interchange object from an existing X12 string.

It then demonstrates traversing the object model to test specific elements against the expected values.

private string inquiry = @"ISA*00*          *00*          *01*9012345720000  *01*9088877320000  *020816*1144*U*00401*000000031*0*T*:~
                                              GS*HS*901234572000*908887732000*20070816*1615*31*X*00501X092A1~
                                                ST*270*1234~
                                                  BHT*0022*13*10001234*20070816*1319*00~
                                                  HL*1**20*1~
                                                    NM1*PR*2*ABC BILLING SERVICE*****PI*842610001~
                                                    HL*2*1*21*1~
                                                      NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~
                                                      HL*3*2*22*0~
                                                        TRN*1*93175-012547*9877281234~
                                                        NM1*IL*1*SMITH*ROBERT*MI****11122333301~
                                                          DMG*D8*19430519~
                                                          DTP*291*D8*20060501~
                                                          EQ*30~
                                                SE*13*1234~
                                              GE*1*31~
                                            IEA*1*000000031~
                                            ";

[TestMethod]
public void Read270Test()
{
    X12Parser parser = new X12Parser();
    Interchange interchange = parser.Parse(new MemoryStream(Encoding.ASCII.GetBytes(inquiry)));
    Assert.AreEqual("9088877320000  ", interchange.InterchangeReceiverId);

Transaction transaction = interchange.FunctionGroups.First().Transactions.First(); Segment bht = transaction.Segments.First();
Assert.AreEqual("10001234", bht.GetElement(3)); HierarchicalLoop subscriberLoop = transaction.FindHLoop("3"); Loop subscriberNameLoop = subscriberLoop.Loops.First(); Assert.AreEqual("SMITH", subscriberNameLoop.GetElement(3), "Subscriber last name not expected."); Assert.AreEqual("11122333301", subscriberNameLoop.GetElement(9), "Subscriber member id not expected."); }

 

Modifying an existing X12 file

See the test  ParseModifyAndTransformBackToX12 for an example of code to modify an existing file.

Creating a new X12 document

Some suggested reading for understanding the X12 format in general: http://docs.oracle.com/cd/E19398-01/820-1275/agdaw/index.html

Some suggested reading for understanding the 270 format: http://www.anthem.com/edi/noapplication/f3/s1/t0/pw_ad086850.pdf

Starting with an outlined version of a 270 file (This code will be included in the test Create270Test in the next release with the test code given above - Read270Test)

private string inquiryOutline = @"ISA*00*          *00*          *01*9012345720000  *01*9088877320000  *020816*1144*U*00401*000000031*0*T*:~
                                              GS*HS*901234572000*908887732000*20070816*1615*31*X*00501X092A1~
                                                ST*270*1234~
                                                  BHT*0022*13*10001234*20070816*1319*00~
                                                  HL*1**20*1~
                                                    NM1*PR*2*ABC BILLING SERVICE*****PI*842610001~
                                                    HL*2*1*21*1~
                                                      NM1*1P*2*BONE AND JOINT CLINIC*****SV*2000035~
                                                      HL*3*2*22*0~
                                                        TRN*1*93175-012547*9877281234~
                                                        NM1*IL*1*SMITH*ROBERT*MI****11122333301~
                                                          DMG*D8*19430519~
                                                          DTP*291*D8*20060501~
                                                          EQ*30~
                                                SE*13*1234~
                                              GE*1*31~
                                            IEA*1*000000031~
                                            ";

 

First you need to create the interchange (The ISA line above).

The following code creates this: ISA*00*          *00*          *01*9012345720000  *01*9088877320000  *020816*1144*U*00401*000000031*0*T*:~ (Along with its ending code in IEA)

image

 

Once the interchange is created, you need to add the Function Group to it. (This is the second line in the above example 270 text starting with GS)

This section of code creates this: GS*HS*901234572000*908887732000*20070816*1615*31*X*00501X092A1~(Along with its ending code in GE)

image

 

The next step is adding an actual transaction to the message. This is done by creating a transaction and a BHT – the header for the group of HL levels below.

This section of code creates this: ST*270*1234~BHT*0022*13*10001234*20070816*1319*00~(Along with its ending code in SE)

image

 

Now you will be adding the information for the HL levels to the BHT created above. There are 4 levels to a 270 request:

HL1 – The information source level

HL2 – The information receiver level

HL3 – The subscriber level

HL4 – The dependent level (Optional)

To create the HL1 level (Information Source):

image

 

To create the HL2 level (Information Receiver)

image

 

For the HL3 Level (Member/Subscriber):

image

 

And the same process would be used for creating an HL4 (Dependent) record addition to the 270.

Basically what you are doing is building up the document with each added hierarchal level or loop until the document is complete.

Last edited Jan 20, 2014 at 8:07 PM by MarkWalls, version 25

Comments

davekolb Feb 15, 2014 at 4:49 AM 
Please fully document the object model. Thx.

MartinJ Nov 27, 2013 at 5:35 PM 
When might some instruction on how to modify or create a new X12 document make it to this page?