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...

7 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. Adam says:


    If we have multiple NTE messages with the same numbers is there a way to locate them?

    My second question: When I try to locate OBX|5| it also fails. Is it because there is NTE in between and is there a way to avoid this?

    OBX|1|ST|CHROM21^Chromosome 21||Negative||||||F|||20180531115104|
    OBX|2|ST|CHROM18^Chromosome 18||Negative||||||F|||20180531115104|
    OBX|3|ST|CHROM13^Chromosome 13||Negative||||||F|||20180531115104|
    OBX|4|ST|INTERP1^Interpretation||See Notes||||||F|||20180531115104|
    NTE|1||This specimen showed an expected representation of
    NTE|2||chromosome 21, 18 and 13 material. Clinical correlation is
    OBX|5|ST|CHROMY^Y Chromosome||Detected||||||F|||20180531115104|
    OBX|6|ST|YINTERP^Y Chr. Interpretation||Consistent with a male fetus.||||||F|||20180531115104|
    OBX|7|ST|AF^Additional Findings||N/A||||||F|||20180531115104|
    OBX|8|ST|AFINTERP^Add’l Findings Interp||N/A||||||F|||20180531115104|
    OBX|9|ST|AFNOTE^Add’l Findings Note||N/A||||||F|||20180531115104|
    OBX|10|ST|Lab Director Comments||See Notes||||||F|||20180531115104|
    NTE|1||Fetal Fraction: 15%

  4. RS says:

    Hi How can i get number of segments in a message

  5. Bobby says:

    hello, does anybody have a solution of how to handle repeat for OBX segments? Been trying all combinations and its not working.. pulling first OBX segment only…

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.