HL7v2 (HL7v2 v3.10.1)

Copy Markdown View Source

Pure Elixir HL7 v2.x toolkit.

Schema-driven parsing, typed segment structs, programmatic message building, validation, and integrated MLLP transport.

Parsing

# Raw mode — canonical round-trip, delimiter-based
{:ok, raw} = HL7v2.parse(text)

# Typed mode — segments become structs
{:ok, msg} = HL7v2.parse(text, mode: :typed)

Building

msg =
  HL7v2.new("ADT", "A01", sending_application: "PHAOS")
  |> HL7v2.Message.add_segment(%HL7v2.Segment.PID{...})

text = HL7v2.encode(msg)

Acknowledgments

{:ok, typed} = HL7v2.parse(wire, mode: :typed)
msh = hd(typed.segments)
{ack_msh, msa} = HL7v2.ack(msh)

MLLP Transport

{:ok, _} = HL7v2.MLLP.Listener.start_link(port: 2575, handler: MyHandler)

Summary

Functions

Builds an ACK (Application Accept) for the given MSH segment.

Encodes an HL7v2 message to wire format.

Fetches a value, returning {:ok, value} or {:error, reason}.

Gets a value from a typed message using a path string like "PID-5" or a %HL7v2.Path{} struct.

Gets a value from a typed message with a default.

Builds a new HL7v2 message. Shortcut for HL7v2.Message.new/3.

Parses an HL7v2 message from a binary string.

Converts a %HL7v2.RawMessage{} to a %HL7v2.TypedMessage{}.

Validates an HL7v2 typed message.

Functions

ack(msh, opts \\ [])

Builds an ACK (Application Accept) for the given MSH segment.

Shortcut for HL7v2.Ack.accept/2.

Options

  • :text — optional text message for MSA-3
  • :message_control_id — override the generated ACK message control ID

Examples

{ack_msh, msa} = HL7v2.ack(original_msh)

encode(message)

Encodes an HL7v2 message to wire format.

Accepts:

  • %HL7v2.RawMessage{} — encodes directly
  • %HL7v2.Message{} — converts to raw via Message.encode/1
  • %HL7v2.TypedMessage{} — converts to raw via TypedParser.to_raw/1, then encodes

Examples

wire = HL7v2.encode(raw_message)
wire = HL7v2.encode(builder_message)
wire = HL7v2.encode(typed_message)

fetch(msg, path)

@spec fetch(HL7v2.TypedMessage.t(), binary() | HL7v2.Path.t()) ::
  {:ok, term()} | {:error, atom()}

Fetches a value, returning {:ok, value} or {:error, reason}.

get(msg, path)

@spec get(HL7v2.TypedMessage.t(), binary() | HL7v2.Path.t()) :: term()

Gets a value from a typed message using a path string like "PID-5" or a %HL7v2.Path{} struct.

get(msg, path, default)

@spec get(HL7v2.TypedMessage.t(), binary() | HL7v2.Path.t(), term()) :: term()

Gets a value from a typed message with a default.

new(code, event, opts \\ [])

@spec new(binary(), binary(), keyword()) :: HL7v2.Message.t()

Builds a new HL7v2 message. Shortcut for HL7v2.Message.new/3.

Options

  • :sending_application — string or %HD{}
  • :sending_facility — string or %HD{}
  • :receiving_application — string or %HD{}
  • :receiving_facility — string or %HD{}
  • :message_control_id — string (default: auto-generated)
  • :processing_id — string (default: "P")
  • :version_id — string (default: "2.5.1")

Examples

msg = HL7v2.new("ADT", "A01", sending_application: "PHAOS")

parse(text, opts \\ [])

@spec parse(
  binary(),
  keyword()
) :: {:ok, term()} | {:ok, term(), [map()]} | {:error, term()}

Parses an HL7v2 message from a binary string.

Options

  • :mode:raw (default) or :typed
  • :validatetrue to validate after parsing (default false). Requires mode: :typed; silently ignored in :raw mode.
  • :copytrue to copy all parsed binaries (prevents GC reference to original message binary). Use when storing parsed messages long-term. Default false.

Examples

{:ok, msg} = HL7v2.parse("MSH|^~\\&|...")
{:ok, msg} = HL7v2.parse(text, mode: :typed, validate: true)
{:ok, msg} = HL7v2.parse(text, copy: true)

type(raw)

@spec type(HL7v2.RawMessage.t()) :: {:ok, HL7v2.TypedMessage.t()} | {:error, term()}

Converts a %HL7v2.RawMessage{} to a %HL7v2.TypedMessage{}.

Shortcut for HL7v2.TypedParser.convert/1.

Examples

{:ok, raw} = HL7v2.parse(wire)
{:ok, typed} = HL7v2.type(raw)

validate(message, opts \\ [])

@spec validate(
  term(),
  keyword()
) :: :ok | {:ok, [map()]} | {:error, [map()] | :not_a_typed_message}

Validates an HL7v2 typed message.

Returns :ok when all validation rules pass, or {:error, errors} with a list of error/warning maps. Requires a HL7v2.TypedMessage -- raw messages return {:error, :not_a_typed_message}.

Version-aware rules (v2.7+ B-field exemptions, etc.) are driven by MSH-12 (version_id) by default. Pass :version to override this — useful for validating messages that mis-declare their version or when cross-checking a v2.5.1 payload against v2.7 conformance rules.

Options

  • :mode -- :lenient (default) or :strict
  • :validate_tables -- true to check coded fields against HL7 tables (default false)
  • :version -- explicit HL7 version override (e.g. "2.7"). When provided, version-specific rules use this value instead of the one extracted from MSH-12. Invalid or unrecognized versions fall back to the MSH-12 value.
  • :profile -- a HL7v2.Profile struct (or list of profiles) to validate against in addition to the base schema. Profiles express organization- specific constraints: required segments, required fields beyond the base spec, table bindings, cardinality, value predicates, and custom rules. Profile errors include a :rule (which rule type fired) and :profile (profile name) for traceability.

Examples

{:ok, msg} = HL7v2.parse(text, mode: :typed)
:ok = HL7v2.validate(msg)

# With table validation
{:error, errors} = HL7v2.validate(msg, validate_tables: true)

# Override the version read from MSH-12 and apply v2.7 rules instead
:ok = HL7v2.validate(msg, version: "2.7")

# Validate against a conformance profile
profile =
  HL7v2.Profile.new("Hospital_ADT_A01", message_type: {"ADT", "A01"})
  |> HL7v2.Profile.require_field("PID", 18)
  |> HL7v2.Profile.require_cardinality("OBX", min: 1, max: 10)

HL7v2.validate(msg, profile: profile)