Class: HL7::Message

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ruby-hl7.rb

Overview

Ruby Object representation of an hl7 2.x message the message object is actually a “smart” collection of hl7 segments

Examples

Creating a new HL7 message

# create a message
msg = HL7::Message.new

# create a MSH segment for our new message
msh = HL7::Message::Segment::MSH.new
msh.recv_app = "ruby hl7"
msh.recv_facility = "my office"
msh.processing_id = rand(10000).to_s

msg << msh # add the MSH segment to the message

puts msg.to_s # readable version of the message

puts msg.to_hl7 # hl7 version of the message (as a string)

puts msg.to_mllp # mllp version of the message (as a string)

Parse an existing HL7 message

raw_input = open( "my_hl7_msg.txt" ).readlines
msg = HL7::Message.new( raw_input )

puts "message type: %s" % msg[:MSH].message_type

Defined Under Namespace

Classes: Segment

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw_msg = nil, &blk) ⇒ Message

setup a new hl7 message

raw_msg

is an optional object containing an hl7 message it can either be a string or an Enumerable object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ruby-hl7.rb', line 86

def initialize( raw_msg=nil, &blk )
  @segments = []
  @segments_by_name = {}
  @item_delim = "^"
  @element_delim = '|'
  @segment_delim = "\r"

  parse( raw_msg ) if raw_msg

  if block_given?
    blk.call self
  end
end

Instance Attribute Details

#element_delimObject (readonly)

Returns the value of attribute element_delim.



79
80
81
# File 'lib/ruby-hl7.rb', line 79

def element_delim
  @element_delim
end

#item_delimObject (readonly)

Returns the value of attribute item_delim.



80
81
82
# File 'lib/ruby-hl7.rb', line 80

def item_delim
  @item_delim
end

#segment_delimObject (readonly)

Returns the value of attribute segment_delim.



81
82
83
# File 'lib/ruby-hl7.rb', line 81

def segment_delim
  @segment_delim
end

Class Method Details

.parse(inobj) ⇒ Object

parse a String or Enumerable object into an HL7::Message if possible

  • returns a new HL7::Message if successful



192
193
194
195
196
# File 'lib/ruby-hl7.rb', line 192

def parse( inobj )
  HL7::Message.new do |msg|
    msg.parse( inobj )
  end
end

.parse_batch(batch) ⇒ Object

:yields: message

Raises:



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/ruby-hl7.rb', line 162

def parse_batch(batch) # :yields: message
  raise HL7::ParseError, 'badly_formed_batch_message' unless
    batch.hl7_batch?

  # JRuby seems to change our literal \r characters in sample
  # messages (from here documents) into newlines.  We make a copy
  # here, reverting to carriage returns.  The input is unchanged.
  #
  # This does not occur when posts are received with CR
  # characters, only in sample messages from here documents.  The
  # expensive copy is only incurred when the batch message has a
  # newline character in it.
  batch = batch.gsub("\n", "\r") if batch.include?("\n")

  raise HL7::ParseError, 'empty_batch_message' unless
    match = /\rMSH/.match(batch)

  match.post_match.split(/\rMSH/).each_with_index do |_msg, index|
    if md = /\rBTS/.match(_msg)
      # TODO: Validate the message count in the BTS segment
      # should == index + 1
      _msg = md.pre_match
    end

    yield 'MSH' + _msg
  end
end

Instance Method Details

#<<(value) ⇒ Object

add a segment to the message

  • will force auto set_id sequencing for segments containing set_id’s



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ruby-hl7.rb', line 149

def <<( value )
  unless ( value && value.kind_of?(HL7::Message::Segment) )
    raise HL7::Exception.new( "attempting to append something other than an HL7 Segment" )
  end

  value.segment_parent = self unless value.segment_parent
  (@segments ||= []) << value
  name = value.class.to_s.gsub("HL7::Message::Segment::", "").to_sym
  (@segments_by_name[ name ] ||= []) << value
  sequence_segments unless @parsing # let's auto-set the set-id as we go
end

#[](index) ⇒ Object

access a segment of the message

index

can be a Range, Fixnum or anything that responds to to_sym



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/ruby-hl7.rb', line 103

def []( index )
  ret = nil

  if index.kind_of?(Range) || index.kind_of?(Fixnum)
    ret = @segments[ index ]
  elsif (index.respond_to? :to_sym)
    ret = @segments_by_name[ index.to_sym ]
    ret = ret.first if ret && ret.length == 1
  end

  ret
end

#[]=(index, value) ⇒ Object

modify a segment of the message

index

can be a Range, Fixnum or anything that responds to to_sym

value

an HL7::Message::Segment object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ruby-hl7.rb', line 120

def []=( index, value )
  unless ( value && value.kind_of?(HL7::Message::Segment) )
    raise HL7::Exception.new( "attempting to assign something other than an HL7 Segment" )
  end

  if index.kind_of?(Range) || index.kind_of?(Fixnum)
    @segments[ index ] = value
  elsif index.respond_to?(:to_sym)
    (@segments_by_name[ index.to_sym ] ||= []) << value
  else
    raise HL7::Exception.new( "attempting to use an indice that is not a Range, Fixnum or to_sym providing object" )
  end

  value.segment_parent = self
end

#eachObject

yield each segment in the message



213
214
215
216
# File 'lib/ruby-hl7.rb', line 213

def each # :yeilds: segment
  return unless @segments
  @segments.each { |s| yield s }
end

#index(value) ⇒ Object

return the index of the value if it exists, nil otherwise

value

is expected to be a string



138
139
140
141
142
143
144
145
# File 'lib/ruby-hl7.rb', line 138

def index( value )
  return nil unless (value && value.respond_to?(:to_sym))

  segs = @segments_by_name[ value.to_sym ]
  return nil unless segs

  @segments.index( segs.to_a.first )
end

#lengthObject

return the segment count



219
220
221
222
# File 'lib/ruby-hl7.rb', line 219

def length
  0 unless @segments
  @segments.length
end

#parse(inobj) ⇒ Object

parse the provided String or Enumerable object into this message



200
201
202
203
204
205
206
207
208
209
210
# File 'lib/ruby-hl7.rb', line 200

def parse( inobj )
  unless inobj.kind_of?(String) || inobj.respond_to?(:each)
    raise HL7::ParseError.new
  end

  if inobj.kind_of?(String)
      parse_string( inobj )
  elsif inobj.respond_to?(:each)
      parse_enumerable( inobj )
  end
end

#sequence_segments(base = nil) ⇒ Object

auto-set the set_id fields of any message segments that provide it and have more than one instance in the message



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/ruby-hl7.rb', line 242

def sequence_segments(base=nil)
  last = nil
  segs = @segments
  segs = base.children if base

  segs.each do |s|
    if s.kind_of?( last.class ) && s.respond_to?( :set_id )
      last.set_id = 1 unless last.set_id && last.set_id.to_i > 0
      s.set_id = last.set_id.to_i + 1
    end

    if s.respond_to?(:children)
      sequence_segments( s )
    end

    last = s
  end
end

#to_hl7Object

provide a HL7 spec version of the message



230
231
232
# File 'lib/ruby-hl7.rb', line 230

def to_hl7
  @segments.collect { |s| s if s.to_s.length > 0 }.join( @segment_delim )
end

#to_mllpObject

provide the HL7 spec version of the message wrapped in MLLP



235
236
237
238
# File 'lib/ruby-hl7.rb', line 235

def to_mllp
  pre_mllp = to_hl7
  "\x0b" + pre_mllp + "\x1c\r"
end

#to_sObject

provide a screen-readable version of the message



225
226
227
# File 'lib/ruby-hl7.rb', line 225

def to_s
  @segments.collect { |s| s if s.to_s.length > 0 }.join( "\n" )
end