Documentation
Command line
Six crates ship a binary. They are useful without writing any Rust at all — looking at an unfamiliar message, checking a batch in a shell script, converting a directory of files.
The six binaries
| Binary | From crate | Does |
|---|---|---|
hl7-v2 | hl7-2 | Tree, query, check, edit, and re-emit an HL7 v2 message |
hl7-2-from-er7-into-xml | same name | ER7 → v2.xml |
hl7-2-from-xml-into-er7 | same name | v2.xml → ER7 |
hl7-2-from-er7-into-json | same name | ER7 → typed JSON |
hl7-2-from-json-into-er7 | same name | typed JSON → ER7 |
hl7-2-from-xsd-into-json-dictionary | same name | A directory of v2.xml XSDs → the JSON dictionary hl7-2 reads |
Install any of them with cargo install <crate> — see Install. Note that cargo install hl7-2 gives you a
binary named hl7-v2.
hl7-v2 — the HL7 v2 tool
hl7-v2 [OPTIONS] [FILE]Reads FILE, or standard input when FILE is absent or -.
Input may hold one message, several, or a batch; each is handled separately.
Output modes — the first one given wins
| Option | Prints |
|---|---|
-t, --tree | The message as an indented tree. The default. |
-q, --query PATH | Every value at PATH, one per line. |
-c, --check | Validation diagnostics, or ok. |
-e, --er7 | The message back as ER7. |
Options
| Option | Effect |
|---|---|
-s, --set PATH=VALUE | Set a value before printing. Repeatable. |
-n, --null PATH | Write the explicit HL7 null at a path before printing. |
-v, --hl7-version VER | Force a release rather than reading it from MSH-12. |
-d, --dictionary FILE | Read the message through a JSON schema dictionary. |
-f, --flat | Suppress message-structure grouping. |
-p, --paths | Show each node's path beside it. |
-S, --strict | Fail on a validation error. |
-o, --output FILE | Write to a file instead of stdout. |
Successive trees are separated by a blank line. The value and ER7 outputs are not, so they can be piped straight into another tool.
# Look at a message you have never seen
hl7-v2 samples/oru_r01.hl7
# Pull out every result value
hl7-v2 --query OBX-5 samples/oru_r01.hl7
# Check it, with an exit status a shell can act on
hl7-v2 --check samples/adt_a01.hl7
# Read a vendor dialect
hl7-v2 --dictionary samples/acme.json samples/vendor.hl7
# Change something and write it back out
hl7-v2 --set 'PID-8=F' --er7 samples/orm_o01.hl7$ hl7-v2 --paths samples/vendor.hl7
ADT_A01
MSH [MSH[1]]
...
ZAC [ZAC[1]]
ZAC.1 = 7 [ZAC[1]-1[1]]
ZAC.2 [ZAC[1]-2[1]]
ZAC.2.1 = SMITH [ZAC[1]-2[1].1]
ZAC.2.2 = JOHN [ZAC[1]-2[1].2]
ZAC.3 = 20260814 [ZAC[1]-3[1]]The four converters
All four read a file or standard input and write standard output or -o FILE. The
ER7-side tools accept one message, several, or an HL7 batch file (FHS/BHS envelopes are
dropped); each message becomes one output document.
ER7 → XML, and the same flags apply to ER7 → JSON
# From a file to stdout
hl7-2-from-er7-into-xml samples/orm_o01.hl7
# From stdin, to a file
cat samples/oru_r01.hl7 | hl7-2-from-er7-into-xml -o out.xml
# Disable message-structure grouping
hl7-2-from-er7-into-xml --flat samples/orm_o01.hl7
# Convert against a dictionary built from XSDs instead of bundled v2.5
hl7-2-from-er7-into-xml --dictionary my-dialect.json samples/orm_o01.hl7
# Let that dictionary decide the document's exact shape
hl7-2-from-er7-into-xml --dictionary my-dialect.json --schema-shape samples/orm_o01.hl7--dictionary FILE reads a JSON dictionary — such as one built by the XSD tool — in
place of the bundled HL7 v2.5 tables. --schema-shape changes how that dictionary is
read: instead of only naming what a field is, it decides what the document contains — required fields are written even when empty, fields that cannot repeat keep
their repetition separator as text, and no field the dictionary does not declare is written.
The JSON converter has one flag of its own:
# Compact (single-line) JSON instead of pretty-printed
hl7-2-from-er7-into-json --compact samples/orm_o01.hl7The two reverse tools take the segment terminator instead:
# v2.xml back to ER7
hl7-2-from-xml-into-er7 samples/orm_o01.xml
# Typed JSON back to ER7
hl7-2-from-json-into-er7 samples/orm_o01.json
# Choose the segment terminator
hl7-2-from-xml-into-er7 --terminator crlf samples/orm_o01.xmlMessage-structure group elements and keys are flattened automatically, so grouped and --flat input from the forward tool both reconstruct the same message.
The dictionary builder
hl7-2-from-xsd-into-json-dictionary schemas/paris -o paris.json
# Two things the schemas cannot tell you, so you pass them in
hl7-2-from-xsd-into-json-dictionary schemas/paris \
--name paris \
--alias ADT_A28=ADT_A05 \
--alias ADT_A31=ADT_A05 \
-o paris.json
# Layer the document over a bundled release instead of standing alone
hl7-2-from-xsd-into-json-dictionary schemas/paris --inherits 2.5 -o paris.json--alias says which trigger events arrive carried by another message's structure. A
directory holds ADT_A05.xsd but never says that an ADT^A28 is one, so
that mapping has to come from you. See Vendor dictionaries.
Exit status, and using it in a shell
hl7-v2 exits:
- 0 — success.
- 1 — a usage error, or the input was not a message at all.
- 2 —
--checkor--strictfound something wrong with the message.
Those three are distinct on purpose: “this file is not HL7” and “this file is HL7 and it is wrong” need different handling, and a script that conflates them will quarantine the wrong things.
A triage script that uses the distinction
#!/bin/sh
# Reject anything that does not conform before it reaches the interface engine.
for message in inbox/*.hl7; do
if hl7-v2 --check "$message" >/dev/null; then
mv "$message" accepted/
else
hl7-v2 --check "$message" >> rejected.log
mv "$message" rejected/
fi
doneRecipes
# Every patient identifier in a directory of messages
cat inbox/*.hl7 | hl7-v2 --query PID-3
# Fix a sex code and re-emit, in one pass
hl7-v2 --set 'PID-8=F' --er7 in.hl7 > out.hl7
# Clear a field with the explicit HL7 null rather than emptying it
hl7-v2 --null 'PID-11' --er7 in.hl7
# Force a release when the sender's MSH-12 lies
hl7-v2 --hl7-version 2.3 vendor.hl7
# Round trip, as a smoke test
hl7-2-from-er7-into-xml in.hl7 | hl7-2-from-xml-into-er7 | diff - in.hl7hl7-v2 --help lists everything, and each converter's own spec/index.md §8 is the normative statement of its command-line contract. See Specifications.