---
title: Parse EDI text into segments and elements
summary: Lexically split raw EDI text into segments, data elements, and composite sub-elements.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-15
library: SAIF.Framework.Common.Files
reference_type: package
operation_id: OP-06
trigger: Called by the EDI file read operation, or directly by a consumer
---

# Parse EDI text into segments and elements

`EdiSegmentParser.Parse` and its cascaded `EdiDataElementParser`/`EdiCompositeDataElementParser` collaborators split raw EDI text on the `~`, `*`, and `:` delimiters respectively, building the flat segment/element list consumed by [Build the X12 envelope hierarchy](build-x12-envelope-hierarchy.md).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-06 |
| **Trigger** | Called by [Read an EDI interchange file](read-edi-interchange-file.md), or directly by a consumer. |
| **Inputs** | Raw EDI string. |
| **Outputs** | `List<IEdiSegment>`. |
| **Primary components** | `EdiSegmentParser.Parse`, `EdiDataElementParser.Parse`, `EdiCompositeDataElementParser.Parse` |
| **Entry point** | `Common\SAIF.Common.Files\Edi\Core\Parsers\EdiSegmentParser.cs`, `EdiDataElementParser.cs`, `EdiCompositeDataElementParser.cs` |

## Steps

1. Split the input on `~` (`EdiRecordBase.SegmentDelimiter`) with `RemoveEmptyEntries` ([BR-018](../business-rules.md#br-018-segments-delimited-by-tilde-empty-segments-discarded)).
2. For each segment token, create an `EdiSegment` with `Index = IndexingSequence.NextValue` (delegated: `SAIF.Framework.Common` → `Sequence`), `Value = token`, and `DataElements = new EdiDataElementParser().Parse(token)`.
3. `EdiDataElementParser.Parse` splits on `*`.
   - A token containing `:` becomes an `EdiCompositeDataElement` whose children come from `EdiCompositeDataElementParser.Parse` (split on `:`) ([BR-019](../business-rules.md#br-019-colon-containing-elements-become-composite-elements)).
   - The **first** token receives index 0 and all others receive sequence values ([BR-020](../business-rules.md#br-020-first-element-is-the-segment-identifier)).
4. `ediSegment.SegmentId = ediSegment.GetChildValue(0)` — the segment id is element 0 ([BR-020](../business-rules.md#br-020-first-element-is-the-segment-identifier)).
5. Each parser instance carries its own `results` list and index sequence, so instances are single-use.*

## Process flow

```mermaid
flowchart TD
	Start([Raw EDI string]) --> Segs["Split on ~ (RemoveEmptyEntries)"]
	Segs --> Loop[For each segment token]
	Loop --> Elems["EdiDataElementParser.Parse: split on *"]
	Elems --> Composite{Token contains colon?}
	Composite -->|Yes| Comp["EdiCompositeDataElementParser.Parse<br>split on colon"]
	Composite -->|No| Simple[Simple EdiDataElement]
	Comp --> SetId["SegmentId = element 0"]
	Simple --> SetId
	SetId --> More{More segment tokens?}
	More -->|Yes| Loop
	More -->|No| EndOk([List of IEdiSegment returned])
```

## Failure and edge-case behavior
- Empty segments produced by adjacent `~~` are silently discarded by `RemoveEmptyEntries` rather than becoming zero-element `EdiSegment` instances ([BR-018](../business-rules.md#br-018-segments-delimited-by-tilde-empty-segments-discarded)).
- Reusing a single `EdiSegmentParser`/`EdiDataElementParser`/`EdiCompositeDataElementParser` instance across two `Parse` calls accumulates results from both calls in the same internal list and index sequence, because each instance is single-use.*

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **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\Core\Parsers\EdiSegmentParser.cs
- Common\SAIF.Common.Files\Edi\Core\Parsers\EdiDataElementParser.cs
- Common\SAIF.Common.Files\Edi\Core\Parsers\EdiCompositeDataElementParser.cs
- Common\SAIF.Common.Files\Edi\EdiRecordBase.cs
