/// <summary> /// Given a file, parse the x12 into the hard coded defintion of a specific format T /// </summary> /// <typeparam name="T">specific format type to parse into</typeparam> /// <param name="fullFilePath">location of the x12 file</param> /// <returns>A list of X12 documents, each of which has a unique group of ISA/GS/ST/BHT, if a file has multiple of any of these, they will be rendered as a seperate X12Document</returns> public static IEnumerable <X12Doc> ParseFile <T>(string fullFilePath) where T : X12Doc { X12Doc tempBuildingDoc = (T)Activator.CreateInstance(typeof(T), args: new object[] { true }); var newHeaderSection = false; var newTrailerSection = false; var parserState = new ParserStateMachine(); var retDocs = new List <X12Doc>(); var sStream = new SegmentStream(File.OpenRead(fullFilePath), ref tempBuildingDoc); var lineContent = new BaseFieldValues(sStream.ReadNextLine(tempBuildingDoc.DocDelimiters)); List <string> headerSplit = HeaderSegments.Split(',').ToList(); List <string> trailerSplit = TrailerSegments.Split(',').ToList(); while (lineContent != null) { //is a head segment if (headerSplit.Contains(lineContent[0])) { if (!newHeaderSection) { //copy the errors to date into the tempBuildingDoc so we can see if there are any errors tempBuildingDoc.AddParsingErrors(parserState.Errors); parserState.Errors.Clear(); //if we just had a trailer section, then we need to create a new tempBuildingDoc to start a new X12 document if (newTrailerSection) { tempBuildingDoc = (T)Activator.CreateInstance(typeof(T), args: new object[] { true }); } retDocs.Add(tempBuildingDoc); newHeaderSection = true; newTrailerSection = false; } if (tempBuildingDoc.BeginHierarchicalTransaction.IsQualified(lineContent)) { tempBuildingDoc.BeginHierarchicalTransaction.Populate(lineContent); } else if (tempBuildingDoc.TransactionSetHeader.IsQualified(lineContent)) { tempBuildingDoc.TransactionSetHeader.Populate(lineContent); } else if (tempBuildingDoc.InterchagneControlHeader.IsQualified(lineContent)) { tempBuildingDoc.InterchagneControlHeader.Populate(lineContent); } else if (tempBuildingDoc.FunctionGroupHeader.IsQualified(lineContent)) { tempBuildingDoc.FunctionGroupHeader.Populate(lineContent); } else //should never happen, but defensive { parserState.Errors.Add( new ParserError("Header segment found no IsQualified handlers and failed to parse", X12ErrorTypes.NotDefined, X12ErrorLevel.Segment, parserState.CurrentLoop, lineContent)); } } else if (trailerSplit.Contains(lineContent[0]))//is a trailer segment { newTrailerSection = true; newHeaderSection = false; if (tempBuildingDoc.TransactionSetTrailer.IsQualified(lineContent)) { tempBuildingDoc.TransactionSetTrailer.Populate(lineContent); } else if (tempBuildingDoc.FunctionalGroupTrailer.IsQualified(lineContent)) { tempBuildingDoc.FunctionalGroupTrailer.Populate(lineContent); } else if (tempBuildingDoc.InterchangeControlTrailer.IsQualified(lineContent)) { tempBuildingDoc.InterchangeControlTrailer.Populate(lineContent); } else//should never happen, but defensive { parserState.Errors.Add( new ParserError("Trailer segment found no IsQualified handlers and failed to parse", X12ErrorTypes.NotDefined, X12ErrorLevel.Segment, parserState.CurrentLoop, lineContent)); } } else //has to be in the doc def { newHeaderSection = false; newTrailerSection = false; parserState = tempBuildingDoc.ParseLineSegment(parserState, lineContent); } lineContent = sStream.ReadNextLine(tempBuildingDoc.DocDelimiters); } return(retDocs); }