Eliot’s Tips and Tricks

Handling optional segments

This can be one of the more subtle areas of mapping HL7 – how to map optional segments. A few pictures will go a long way to explaining the concept and how to deal with them in the Translator.

Imagine we have a message that has a repeating group of segments. The first segment of each group is always the a patient identification segment (PID) which is followed by an optional NTE segment:

MSH|^~\&|MESA_RPT_MGR|EAST_RADIOLOGY|REPOSITORY|XYZ|||ORU^R01|MESA3b781ae8|P|2.3.1||||||||
PID|||4525285^^^ADT1||Smith^Tracy||19980210|F||Martian|86 Yonge St.^^ST. LOUIS^MO^51460|||||||10-346-6|284-517-569|
NTE|1|Patient is silly!|
PID|||5488754^^^ADT1||Smith^Fred||20041012|M||Martian|20 Delphi Cres.^^Chicago^IL^55037|||||||59-693-654|558-171-617|

The life.vmd is used to define the grammar of the message as:

<> means that the PATIENT group is optional and repeating.

[ ] means that the NTE segment is optional.

Now when use this vmd file to parse the message and look at it in the Translator we see something like this:

In this case the optional segments are not showing. I can show them by using the toolbar option to show empty nodes:

(it is the 4th icon from the right)

Now the message should show the empty nodes:

If you look above you should see how the non-present segments are shown greyed out.

There is a helpful utility method supported by nodes which helps us to detect non present HL7 segments through the API. It is called isNull(). These screen shots show it action:

Here you can see isNull() returning false for the first call to the MapNote function. Looking at the second annotation you can see isNull returns true and so you can see than we do not invoke the mapping code in this case.

A mistake people often make it is write code like this:

if NTE ~= nil then
   T.Note = NTE[2]
end
-- or
if NTE then
   T.Note = NTE[2]
end

This will not work as expected because an optional segment which is not present does not result in the member being equal to ‘nil’. It is present in the node tree but just empty.

Hopefully that explains how to use the isNull() method. If it is not clear then let us know and we will try and do a better job of explaining it.

Here is a copy of the code used for this example:

require("node")

function main(Data)
   local Msg,Name = hl7.parse{vmd='life.vmd', data=Data}
   local Out      = db.tables{vmd='life.vmd', name=Name}

   if     Name == 'Lab' then ProcessLab(Out, Msg) end
end

function MapPatient(T, PID) 
   T.Id = PID[3][1][1]
   T.LastName = PID[5][1][1][1]:nodeValue()
   T.GivenName = PID[5][1][2]
   T.Race = PID[10][1][1]
   return T
end  

function MapNote(T, NTE)
   if not NTE:isNull() then
     T.Note = NTE[2]
   end   
end

function ProcessLab(Out, Msg)
   for i=1, #Msg.PATIENT do
      MapPatient(Out.patient[i], Msg.PATIENT[1].PID)
      MapNote(Out.patient[i], Msg.PATIENT[i].NTE)
   end
   return Out
end
Tagged: