Class: HL7::Message

Inherits:
Object
  • Object
show all
Extended by:
MessageBatchParser
Includes:
Enumerable
Defined in:
lib/message.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

Modules: SegmentFields, SegmentListStorage Classes: Delimiter, Segment, SegmentGenerator

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MessageBatchParser

parse_batch

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



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/message.rb', line 45

def initialize( raw_msg=nil, &blk )
  @segments = []
  @segments_by_name = {}
  @item_delim = "^"
  @element_delim = '|'
  @segment_delim = "\r"
  @delimiter = HL7::Message::Delimiter.new( @element_delim,
                                            @item_delim,
                                            @segment_delim)

  @message_parser = HL7::MessageParser.new(@delimiter)

  parse( raw_msg ) if raw_msg

  if block_given?
    blk.call self
  end
end

Instance Attribute Details

#delimiterObject (readonly)

Returns the value of attribute delimiter.



40
41
42
# File 'lib/message.rb', line 40

def delimiter
  @delimiter
end

#element_delimObject (readonly)

Returns the value of attribute element_delim.



37
38
39
# File 'lib/message.rb', line 37

def element_delim
  @element_delim
end

#item_delimObject (readonly)

Returns the value of attribute item_delim.



38
39
40
# File 'lib/message.rb', line 38

def item_delim
  @item_delim
end

#message_parserObject (readonly)

Returns the value of attribute message_parser.



36
37
38
# File 'lib/message.rb', line 36

def message_parser
  @message_parser
end

#segment_delimObject (readonly)

Returns the value of attribute segment_delim.



39
40
41
# File 'lib/message.rb', line 39

def segment_delim
  @segment_delim
end

Instance Method Details

#<<(value) ⇒ Object

add a segment or array of segments to the message

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



129
130
131
132
133
134
135
136
137
138
# File 'lib/message.rb', line 129

def <<( value )
  # do nothing if value is nil
  return unless value

  if value.kind_of? Array
    value.map{|item| append(item)}
  else
    append(value)
  end
end

#[](index) ⇒ Object

access a segment of the message

index

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



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/message.rb', line 83

def []( index )
  ret = nil

  if index.kind_of?(Range) || index.kind_of?(Integer)
    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, Integer or anything that responds to to_sym

value

an HL7::Message::Segment object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/message.rb', line 100

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?(Integer)
    @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, Integer or to_sym providing object" )
  end

  value.segment_parent = self
end

#append(value) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/message.rb', line 140

def append( 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 defined?(@parsing) && @parsing # let's auto-set the set-id as we go
end

#correction?Boolean

Checks if any of the results is a correction

Returns:

  • (Boolean)


200
201
202
# File 'lib/message.rb', line 200

def correction?
  Array(self[:OBX]).any?(&:correction?)
end

#eachObject

yield each segment in the message



153
154
155
156
# File 'lib/message.rb', line 153

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

#generate_segments_enumerable(enumerable) ⇒ Object



74
75
76
77
78
# File 'lib/message.rb', line 74

def generate_segments_enumerable(enumerable)
  enumerable.each do |segment|
    generate_segments( message_parser.parse_string( segment.to_s ))
  end
end

#index(value) ⇒ Object

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

value

is expected to be a string



118
119
120
121
122
123
124
125
# File 'lib/message.rb', line 118

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



159
160
161
162
# File 'lib/message.rb', line 159

def length
  0 unless @segments
  @segments.length
end

#parse(inobj) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/message.rb', line 64

def parse( inobj )
  if inobj.kind_of?(String)
    generate_segments( message_parser.parse_string( inobj ))
  elsif inobj.respond_to?(:each)
    generate_segments_enumerable(inobj)
  else
    raise HL7::ParseError.new( "object to parse should be string or enumerable" )
  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



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/message.rb', line 182

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

    sequence_segments( s ) if s.has_children?

    last = s
  end
end

#to_hl7Object

provide a HL7 spec version of the message



170
171
172
# File 'lib/message.rb', line 170

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

#to_mllpObject

provide the HL7 spec version of the message wrapped in MLLP



175
176
177
178
# File 'lib/message.rb', line 175

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

#to_sObject

provide a screen-readable version of the message



165
166
167
# File 'lib/message.rb', line 165

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