HL7 Introduction

I wrote this short introduction for a fellow programmer that had to work with HL7 for the first time and wanted to get a feel for what it is about. Keep in mind that this is from the perspective of someone that doesn’t like HL7 and has no certification or formal training in it (other than reading famous chapter 2).

HL7 Introduction (For People That Don’t Really Want To Know HL7)
The basics are pretty easy to get. I am absolutely no expert on the topic, but from a pure programming perspective if you get the delimiters, that’s about all there is to it. Whether OBX-25:1 repetition 3 subcomponent 2 is the patient’s favorite pet’s gender or the temperature of the bath water of the lab technician this morning is kind of irrelevant and subject to interpretation anyway.

I don’t know what you already know but here’s a real high level overview of HL7 not counting the network (MLLP) stuff, which I’m not sure if you need.

Most HL7 records come in multiple segments delimited by carriage returns (\r). Usually they start with an MSH segment (unless it’s a batch, which is rare, and I won’t get into that). It might look like this:

OBR||30725991^EPIC_EC||CBCDIF^CBC and

Note that I added newlines between segments which aren’t supposed to be there to highlight where they are. Basically this has five segments, MSH, PID, PV1, ORC and OBR.

The characters immediately after the MSH tell you what you other delimiters are – if you’re writing parsing software it’s vitally important that you read them and not assume the field separator is going to be a pipe (|) – it’s not always. So the first character after MSH is the field separator, the second is the component separator, the third is the repetition separator, the forth is the escape character and the fifth is the subcomponent separator. 90% of the time you won’t have to parse below the component level. You may also want to note that despite the order of the delimiters in the record, the component is subordinant to the repetition. Again, unless you are writing a parser its probably not even important.

So in our example the field separator is a pipe, the component is a caret, the repetition is a tilde, the escape is a backslash and the subcomponent is the ampersand.

Now for actually naming the fields, be aware the the numbering of the MSH segment is different than all the rest. In the MSH segment, the character right after the MSH is considered the first field (so in this case MSH:1 is a pipe), MSH:2 would be the rest of the delimiters or “^~\&”. MSH:3 is the sending system (LAB), MSH:4 the sending facility (CCF), 5 and 6 are blank, 7 is a timestamp and, importantly, 9 is the message type (ORM^O01).

Other segments count fields more sanely, the first field is whatever is after the first pipe and so on. ORC:1 is CA and ORC:2 is 30725991^EPIC_EC. In ORC:2 you’ll see a caret, which means components. Technically from a programming perspective they are the first and second components of the first (and only) repetition. HL7 may not have a repetition legally defined for ORC:2, but if you’re programming this, I suggest you treat it that way. In the HL7 browser I define this ORC:2 second component as ORC:2-0-1, where the zero means ignore repetitions (although a 1 would be legal too, as it’s the first rep).

Beyond this cursory overview, it really comes down to understanding what segments are appropriate for what kind of message (OBX contains result information and isn’t appropriate in an ADT message). And understanding what fields mean for each type of message. For that you really need the HL7 organization manuals (which are HUGE and hard to read, but invaluable references). You need to be an HL7 member to get them. Alternatively companies like neotool offer HL7 training, which would be a fast way to get jumpstarted.