How to use Hapi Terser with HL7

Hapi terser is the easiest way to extract and set data in a HL7 v2 messages. In the next example, I will show how to:

  • Create a Terser form a String message
  • Extract information from simple fields, components and repetitions
  • Set data in any part of the message

First of all, I have created an HL7 Message version 2.3, which I will be using in all the tests. The message is very simple, contains all the Patient details in the PID segment, 2 Nexts of Kin in the NKX segment, and patient visit information in the PV1 segment. The MSH segment contains metadata like the version of the message (2.3) and the type of the Message ADT A01, which is an admission message.

public class TerserTest {

    Message message;

    Terser terser;

    public void setup() throws Exception{
        String m = "MSH|^~\\&|hl7Integration|hl7Integration|||||ADT^A01|||2.3|\r" +
                "EVN|A01|20130617154644\r" +
                "PID|1|465 306 5961||407623|Wood^Patrick^^^MR||19700101|1|||High Street^^Oxford^^Ox1 4DP~George St^^Oxford^^Ox1 5AP|||||||\r" +

        //Parse the message
        PipeParser pipeParser = new PipeParser();
        this.message = pipeParser.parse(m);
        this.terser = new Terser(message);

Note that I have used the “\r” special character to set the end of line. The Hapi parser doesn’t recognized the “\n” character.

Once we have parsed the message and built a Terser, accessing each field it is straightforward. If we would like to access a simple field, we need to use the terser object and specify the segment and field, like: terser.get(“/segment-field”).

    public void testAccessSimpleFields() throws Exception{

        //Patient Id
        assertEquals("465 306 5961", terser.get("/PID-2"));
        assertEquals("19700101", terser.get("/PID-7"));
        //Patient Surname
        assertEquals("Wood", terser.get("/PID-5-1"));
        //Patient First Name
        assertEquals("Patrick", terser.get("/PID-5-2"));

We can get a specific components using the ‘-’ character. For instance the PID-5-2, is the second component of the fifth field.
    public void testAccessSegmentRepetitions() throws Exception{

        //First Next of Kin Id
        assertEquals("1", terser.get("NK1(0)-1"));

        //Second Next of Kin Id
        assertEquals("2", terser.get("NK1(1)-1"));

We can get particular repetitions using the brackets. Depending where we put the brackets we will be retrieving a segment repetition, a field repetition or a component repetition.
    public void testAccessFieldRepetitions() throws Exception{
        //Primary Address: Street
        assertEquals("High Street", terser.get("/PID-11(0)-1"));
        //Primary Address: PostCode
        assertEquals("Ox1 4DP", terser.get("/PID-11(0)-5"));
        //Secondary Address: Street
        assertEquals("George St", terser.get("/PID-11(1)-1"));
        //Secondary Address: PostCode
        assertEquals("Ox1 5AP", terser.get("/PID-11(1)-5"));

Also we can use the Terser to add or update a field. In this case we will need to use the set method and add the field or component and the new value, like: terser.set(“/segment-field-component”, “new value”).
    public void testUpdateSimpleFields() throws Exception{
        //Update Patient Id
        terser.set("/PID-2", "123456");
        assertEquals("123456", terser.get("/PID-2"));

        //Update Dob
        terser.set("/PID-7", "19800101");
        assertEquals("19800101", terser.get("/PID-7"));

    public void testSetComponents() throws Exception{
        //Patient Surname
        terser.set("/PID-5-1", "Jones");
        assertEquals("Jones", terser.get("/PID-5-1"));


    public void testSetTypeFields() throws Exception{
        //Add a secondary address
        terser.set("/PID-11(1)-1", "Wellington Avenue");
        assertEquals("Wellington Avenue", terser.get("/PID-11(1)-1"));

Some people prefers to get/set the data using the Hapi methods instead of the terser. For instance, If you want to retrieve the date of birth instead of using terser.get(“PID-7″), you can use pid.getDateOfBirth().getTimeOfAnEvent().getValue().From my point of view this approach presents some disadvantages:
– Hapi methods forces a specific version of HL7 to be used.
– In real life, clients not always follow the standard and you can find that they are populating information in a field that doesn’t correspond to the standard specification. This could be confusing for other developers working within the project.

That’s why I always recommend to use Hapi terser.

If you would like to see how to set repetitions in an HL7 message, please visit:

How to set repetitions in HL7 messages using HAPI Terser

You can find the whole project in github.

You may also like...

5 Responses

  1. alex shaw says:

    Not working


    var NTE1 = terser.Get(“/.OBSERVATION(0)/.NTE1-1”);
    var NTE2 = terser.Get(“/.OBSERVATION(0)/.NTE1-2”);

  2. raise says:

    is there a way to extract the VN out of PID3 directly? (Without iterating)

    PID|1||D-95353^^^^PI~D-55353^^^^VN||PLASTNAME^PFIRSTNAME^^^^^L||19900101|M||U^Unknown|123 MAIN RD^^CITY^NJ^12345^USA^M


  3. Maryjo says:

    Greetings from Idaho! I’m bored to death at work so I decided to browse your website on my iphone during lunch break.
    I enjoy the info you present here and can’t wait to take a
    look when I get home. I’m surprised at how fast your blog loaded on my phone ..
    I’m not even using WIFI, just 3G .. Anyhow, fantastic site!

    barcelona trøje

  4. Carmelo says:

    I am truly delighted to read this weblog posts which includes tons of useful facts, thanks for providing these statistics.

Leave a Reply

Your email address will not be published. Required fields are marked *