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])
      return
   end

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

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

   AlterMSH(Out.MSH)
   local PID = hl7util.findSegment(Out, FindPID)
   if PID then
      AlterPID(PID)   
   end

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

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

function AlterPID(PID)

   return PID
end

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

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

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
   end
   return S:sub(1,i)
end