jL7: How to use the jl7 domain specific language

Introduction

The jl7 DSL (Domain Specific Language) is a scripting language which can be used to process and convert HL7 messages. It allows accessing HL7 entities (like message, segments, fields…) with a more natural language than using the Java API.

The DSL is implemented in the package org.jl7.dsl. The entry point to the DSL capabilities is the HL7DSL class. It provides two static methods to work with HL7 messages:

  • processMessage
  • convertMessage

The only difference between these two methods is that convertMessage additionally creates an output message which is returned after the processing.

In the processMessage method, the provided message is to be referred to as “message”. In the convertMessage method, the input message is called “message_in” and the output message is called “message_out”.

General syntax

The DSL is based on Groovy (see http://groovy.codehaus.org for more information). All Groovy and Java libraries can be used.

Here are a few examples of how to use the DSL.

Accessing message content

The following example obtains the PID segment:

println "message.PID:\n"+message.PID

If the message contains multiple PID segments, it will return the first one. In order to get the second PID segment the following syntax shall be used:

println "message.PID[2]:\n"+message.PID[2]

Note: The first segment has the index number 1 (not 0).

To obtain the PID-5 field from a message we can write:

println "message.PID(5):\n"+message.PID(5)

If we have a repetition of this field, the second instance of the field can be accessed by using:

println "message.PID(5)[2]:\n"+message.PID(5)[2]

This is actually the same syntax as for segments.

If the field contains multiple components we access the second component with:

println "message.PID(5)(2):\n"+message.PID(5)(2)

The same kind of syntax can be used to access subcomponents:

println "message.PID(5)[2](3)(2):\n"+message.PID(5)[2](3)(2)

So in the DSL a message has the following structure:

  1. Message
  2. Segment
  3. Field
  4. Component
  5. Subcomponent

To go from one level to the next one, round brackets are used: xxx(n).
To access a repetition of a segment or a field, square brackets are used: xxx[n].
In both cases, the first index is 1.

Modifying message content

A message can be assigned the value of another message using the operator: <<.

The following example copies the content of message_in to message_out.

message_out << message_in

A segment of one message can be added to another message. The following example copies the MSH segment from message_in to message_out.

message_out << message_in.MSH

The operator = can be used instead of >> in order to replace a segment rather than add it.

message_out.PV1 = "PV1|1|O"

The example above replaces the first PV1 segment in message_out by the new segment.

message_out.PV1 = message_in.PV1

Note: If there is no PV1 segment already available in message_out, the two operators = and << have the same effect.

Message groups

The jl7 DSL also supports segments groups. These are groups of segment semantically related e.g. the PD1, ARV, ROL, NK1, NTE segments following a PID segment belong together with the PID segment to a PATIENT group.

The following groups exist:

  • PATIENT: PID or MRG, PD1, ARV, ROL, NK1, NTE
  • VISIT: PV1, PV2, ARV, ROL, DB1
  • ORDER: ORC, OBR, NTE
  • PROCEDURE: PR1, ROL
  • INSURANCE: IN1, IN2, IN3, ROL

Segment groups can be extracted from a message:

message_in.PATIENTS

This returns a list of all PATIENT segment groups. In order to get one of these group, the following can be used:

message_in.PATIENTS(1)

The first group in the list is indexed with 1.

Segments group can be added to a message just like segments.

message_out.MSH = message_in.MSH
message_out.EVN = message_in.EVN
message_out << message_in.PATIENTS(1)
message_out << message_in.VISITS(1)

Mapping message content

In order to map values in a HL7 message, a mapping table can be define.

//Define mapping table
def map = ["s":"I", "a":"O"]
//Change the visit type
message_out.PV1(2) << map[message_in.PV1(2)]

A default value can also be defined for the map.

def map = ['s':'I', 'a':'O'].withDefault{ 'U' }

This means that if the value of attribute being mapped is not ‘s’ or ‘a’, ‘U’ will be used as mapped value.

Note: jL7 can be downloaded here.

Leave a Reply

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