HL7 to HL7

Find the PID segment

The Translator gives us a variety of ways to find the PID segment for both ADT and Lab messages; let’s look at two possible solutions.

Solution 1: Use different code for Lab and ADT messages

This would be doing something like

This is valid approach. Notice we still only have one AlterPID routine so it’s maintainable code. We could create functions like ProcessADT and ProcessLab to clean the logic up further.

Solution 2: Use hl7utils.find to find the PID segment

This is a powerful technique. The hl7utils module enables us to write some code which will find the PID segment for us. All we need to do is add a require line for the hl7util module and call hl7util.findSegment().

require 'hl7util'

It’s easiest to see it in action:

The hl7util.findSegment() function works by searching through the node tree passed in and putting each segment in the tree through the filter function FindPID(Segment) which is supplied as the second argument. This one of the nice things about Lua: functions are stored as tables which can be passed as parameters to other functions.

Once the filter function returns true, hl7util.findSegment() will return the segment to us.

This utility can be very useful for many things in HL7 interfaces. Frequently one needs to find a message segment which matches a specific criteria, i.e., searching the next of kin segments for someone with specific status like the mother and/or guardian. Then the versatility of a filter function really comes into its own; it is very simple to create one to match your criteria.

And here is the latest code:

require 'split'
require 'zsegment'
require 'diff'
require 'hl7util'

local function trace(a,b,c,d) return end

function main(Data)
   local Orig = hl7.parse  {vmd = 'transform.vmd', data = Data}

   if Orig:nodeName() == 'Catchall' then
      iguana.logInfo('Filtered '..Orig.MSH[9][1]..'^'..Orig.MSH[9][2])

   local Out  = hl7.message{vmd = 'transform.vmd', name = Orig:nodeName()}

   local Copy = zsegment.copyZSegments(Data, Out:S())
   CheckTransform(Data:StripLastReturns(), Copy:StripLastReturns())

   local PID = hl7util.findSegment(Out, FindPID)
   if PID then

   local Diff = diff.Compare(Orig:S(), Out:S(), 'transform.vmd')
   local DataOut = Out:S()
   DataOut = zsegment.copyZSegments(Data, DataOut)
   DataOut = DataOut:StripLastReturns()
   queue.push{data = DataOut}

function FindPID(Segment)
   if Segment:nodeName() == 'PID' then
      return true

function AlterPID(PID)

   return PID

function AlterMSH(MSH)
   MSH[3][1] = 'Acme'
   MSH[4][1] = 'Lab'
   return MSH

function CheckTransform(Orig, Copy)
   if Orig ~= Copy then
      error('Copy of HL7 message does not match the original')

function string.StripLastReturns(S)
   -- strip return(s) "\r" & "\n" from the end of a string
   local i = #S
   while S:byte(i) == 10 or S:byte(i) == 13 do
      i = i - 1
   return S:sub(1,i)

Leave A Comment?