# EDIFACT field access

Read and write EDIFACT business data through semantic Python names instead of positions.

Typed EDIFACT messages expose their segments, elements and components as Python attributes with semantic names - the same model as [HL7 v2 field access](https://zato.io/docs/dev/healthcare/hl7/v2/field-access/index.html). The names come from the dialect's message classes, so every dialect you define per [Dialects and profiles](https://zato.io/docs/dev/healthcare/edifact/dialects/index.html) exposes its fields through attributes as well, with the names you choose.

## Segments and elements {#segments-and-elements}

Each segment a message declares is an attribute of the message, and each element is an attribute of its segment:

```python
from zato.edifact import parse_edifact

# The Dutch healthcare dialect, shipped as an example
import zato.edifact.nl

msg = parse_edifact(raw).message

# A segment, then an element on it
sex = msg.pid.sex

# Elements that hold a composite have typed components
family_name = msg.pid.patient_name.married_name
prefix      = msg.pid.patient_name.married_name_prefix
born_year   = msg.pid.date_of_birth.year
```

A message class maps `pid` to the wire tag PID and `patient_name` to the element position of the name composite, so services read like the business logic they implement.

## Composites {#composites}

Composite data elements group their components under one attribute:

```python
# An address composite and its components
street   = msg.pad.address.street
number   = msg.pad.address.building_number
city     = msg.pad.address.city
postcode = msg.pad.address.postcode
```

## Repeating segments {#repeating-segments}

A segment declared as repeatable is a list - iterate it, index it, take its length:

```python
# TXT repeats - one segment per line of text
for line in msg.text:
    print(line.text)

first_line = msg.text[0].text
line_count = len(msg.text)
```

## Repeating groups {#repeating-groups}

Groups model the nested, repeating structures of larger messages. In a lab result, for example, each specimen has its own determinations, and each determination its own remarks:

```python
for material in msg.materials:

    print(material.det.date.day, material.ide.identification_number)

    for determination in material.determinations:
        print(determination.determination, determination.result, determination.unit)

    for remark in material.determination_remarks:
        print(remark.text)
```

## The service segments {#the-service-segments}

UNH and UNT are typed like any other segment, and the interchange envelope segments UNB and UNZ are reachable on the interchange itself:

```python
interchange = parse_edifact(raw)
msg = interchange.message

message_type = msg.unh.identifier.message_type
version      = msg.unh.identifier.version
reference    = msg.unh.reference_number
count        = msg.unt.segment_count

sender    = interchange.header.sender.identification
recipient = interchange.header.recipient.identification
```

## Positional fallback {#positional-fallback}

You can read any segment - typed or not - by position, which covers fields outside the declared structure and wholly unknown segments:

```python
# All segments with a given tag, in wire order
for seg in msg.segments('NAD'):

    # e_1, e_2 .. resolve to elements by position
    print(seg.e_1)
```

## Building and modifying {#building-and-modifying}

Segments are plain classes - instantiate one, assign its elements and serialize it:

```python
from zato.edifact.nl.segments import TXT

line = TXT()
line.text = 'Please review the attached results'

wire = line.serialize()   # TXT+Please review the attached results'
```

Assignments on a parsed message merge into the original wire data during serialization - what you change is re-serialized, everything else stays as received.

## See also {#see-also}

- [Message parsing](https://zato.io/docs/dev/healthcare/edifact/parsing/index.html) - How the typed objects these names live on come into being
- [Dialects and profiles](https://zato.io/docs/dev/healthcare/edifact/dialects/index.html) - Where the semantic names are defined and how to choose your own
- [EDIFACT in healthcare tutorial](https://zato.io/tutorials/healthcare/edifact.html) - Typed access in a complete service, from lab result to reply

## Learn more {#learn-more}

- [Healthcare interface engine](https://zato.io/docs/dev/healthcare/) - Clinical messages, FHIR, conversion and operations
- [HL7 v2 parsing](https://zato.io/docs/dev/healthcare/hl7/v2/parsing/) - Messages as typed objects, with field access and validation
- [MLLP channels](https://zato.io/docs/dev/healthcare/hl7v2/mllp/) - Receiving and sending HL7 v2 over MLLP sockets
- [FHIR integrations](https://zato.io/docs/dev/healthcare/hl7/fhir/) - Read and write FHIR resources, with paths, bundles and extensions
- [HL7 v2 to FHIR](https://zato.io/docs/dev/healthcare/hl7/to-fhir/) - Converting v2 messages into FHIR bundles, codes and references included
- [EDIFACT](https://zato.io/docs/dev/healthcare/edifact/) - Parsing interchanges, dialects and the transports they arrive on
- [Transformation](https://zato.io/docs/dev/healthcare/transformation/) - One message in, another standard out, in ordinary Python
- [Audit log](https://zato.io/docs/dev/healthcare/audit-log.html) - Every message with its acknowledgment, searchable by patient identifier
- [AI in clinical interfaces](https://zato.io/docs/dev/healthcare/ai/) - Services calling LLMs and AI agents calling clinical services as tools
