Skip to content

Build the X12 envelope hierarchy

EdiFile.RefreshGroupings and EdiGroupParser convert the flat segment list produced by Parse EDI text into segments and elements into the X12 envelope hierarchy: interchange header/trailer, then functional groups, transaction sets, hierarchical transactions, and hierarchical levels.

Field Value
Operation ID OP-08
Trigger SetSegments, Add of a control segment, or first access to EdiFile.FunctionalGroups.
Inputs Flat segment list.
Outputs IFunctionalGroupContainer tree.
Primary components EdiFile.RefreshGroupings, EdiGroupParser
Entry point Common\SAIF.Common.Files\Edi\EdiFile.cs, Common\SAIF.Common.Files\Edi\Core\Parsers\EdiGroupParser.cs

Steps

  1. RefreshGroupings locates the first ISA segment and parses it into IsaSegment (Header), and the first IEA into IeaSegment (Trailer) (BR-029).
  2. Functional groups are (re)built only when ISA, IEA, GS and GE are all present (BR-030).
  3. If not all present: skip group construction; EdiFile.FunctionalGroups remains unbuilt.
  4. EdiFile.Add(segment) assigns segment.Index = IndexingSequence.NextValue (delegated Sequence), appends it, and re-runs RefreshGroupings when the segment id IsIn("ISA","IEA","GS","GE") (delegated: SAIF.Framework.Common → IEnumerableExtensions.IsIn) (BR-031, BR-032).
  5. CreateFunctionalGroups calls ParseSegmentGroup(file.Segments, "GS", 6) — each GS starts a group keyed on element 6 (group control number); header = first GS, trailer = last GE; member Segments exclude ISA/IEA/GS/GE (BR-033, BR-034).
  6. CreateTransactionSets calls ParseSegmentGroup(fg.Segments, "ST", 2) — key is element 2 (transaction set control number); header ST, trailer SE; members exclude ST/SE (BR-033).
  7. CreateHierarchialTransactions calls ParseSegmentGroup(ts.Segments, "BHT", 1), parses the BHT into BhtSegment, then partitions the remainder with ParseSegmentGroup(htc, "BHT", "HL", 1) and builds HierarchialLevel objects from each HL (key element 1), excluding HL/ST/SE from level members (BR-033, BR-035).
  8. ParseSegmentGroup(parentGroup, segmentId, keyElement) creates one SegmentGroup per matching segment, then moves every segment between that segment's index + 1 and the index before the next occurrence (or the last segment index) into the group via MoveSegmentsToSegmentGroup.
  9. Helper lookups GetNext, GetFirstInRange, GetLastInRange, FindInRange all operate on Index ordering and return 0 when nothing matches (BR-036).
  10. EdiFile.FunctionalGroups lazily caches the result of CreateFunctionalGroups on first access.

Process flow

flowchart TD
    Start([RefreshGroupings triggered]) --> HeaderTrailer["Locate first ISA (Header)<br>and IEA (Trailer)"]
    HeaderTrailer --> Check{"ISA, IEA, GS, GE all present?"}
    Check -->|No| Stop([FunctionalGroups left unbuilt])
    Check -->|Yes| FG["CreateFunctionalGroups<br>ParseSegmentGroup(GS, element 6)"]
    FG --> TS["CreateTransactionSets<br>ParseSegmentGroup(ST, element 2)"]
    TS --> HT["CreateHierarchialTransactions<br>ParseSegmentGroup(BHT, element 1)"]
    HT --> HL["Partition HL segments into<br>HierarchialLevel objects"]
    HL --> EndOk([IFunctionalGroupContainer tree])

Failure and edge-case behavior

  • Missing any of ISA/IEA/GS/GE: the interchange still exposes its flat Segments collection, but FunctionalGroups is not built and no exception is raised (BR-030).
  • ParseSegmentGroup's GetNext/GetFirstInRange/GetLastInRange/FindInRange helpers return 0 rather than a sentinel/null when no matching segment exists, so a malformed interchange with unmatched control segments can silently produce an empty or misaligned group rather than an error (BR-036).*
  • EdiGroupParser.ParseSegmentGroup(parentGroup, segmentId, segmentEndId, maxCount, segmentGroupKeyElement) (the 5-parameter overload) is unreachable as implemented: its loop guard compares the group count against a negated maxCount, so it always breaks after the first group; the overload has no caller in this library.*

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • Common\SAIF.Common.Files\Edi\EdiFile.cs
  • Common\SAIF.Common.Files\Edi\Core\Parsers\EdiGroupParser.cs
  • Common\SAIF.Common.Files\Edi\Segments\IsaSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\IeaSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\GsSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\GeSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\StSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\SeSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\BhtSegment.cs
  • Common\SAIF.Common.Files\Edi\Segments\HlSegment.cs
  • Common\SAIF.Common\Extensions\IEnumerableExtensions.cs