lib/X12/Parser.rb in X12-0.1.0 vs lib/X12/Parser.rb in X12-1.1.0
- old
+ new
@@ -19,60 +19,80 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#++
#
+
+require "rexml/document"
+include REXML
+
+require 'pp'
+
module X12
- # $Id: Parser.rb 54 2009-03-18 17:04:45Z ikk $
+ # $Id: Parser.rb 89 2009-05-13 19:36:20Z ikk $
#
# Main class for creating X12 parsers and factories.
class Parser
+ # These constitute prohibited file names under Microsoft
+ MS_DEVICES = [
+ 'CON',
+ 'PRN',
+ 'AUX',
+ 'CLOCK$',
+ 'NUL',
+ 'COM1',
+ 'LPT1',
+ 'LPT2',
+ 'LPT3',
+ 'COM2',
+ 'COM3',
+ 'COM4',
+ ]
+
# Creates a parser out of a definition
def initialize(file_name)
save_definition = @x12_definition
+
+ # Deal with Microsoft devices
+ base_name = File.basename(file_name, '.xml')
+ if MS_DEVICES.find{|i| i == base_name}
+ file_name = File.join(File.dirname, "#{base_name}_.xml")
+ end
#puts "Reading definition from #{file_name}"
+
+ # Read and parse the definition
str = File.open(file_name, 'r').read
- @dir_name = File.dirname(file_name) # to look up other files if needed
- treetop_parser = X12::X12syntaxParser.new
- res = treetop_parser.parse(str)
- throw Exception.new("Cannot parse X12 definition in #{file_name}") unless res
- @x12_definition = res.get
+ @dir_name = File.dirname(File.expand_path(file_name)) # to look up other files if needed
+ @x12_definition = X12::XMLDefinitions.new(str)
# Populate fields in all segments found in all the loops
@x12_definition[X12::Loop].each_pair{|k, v|
- #puts "Processing loop #{k}"
+ #puts "Populating definitions for loop #{k}"
process_loop(v)
} if @x12_definition[X12::Loop]
-# @x12_definition.keys.each{|t|
-# puts "**** #{t}"
-
-# case
-# when t==X12::Segment: @x12_definition[t].each{|i| puts i.inspect; puts i.regexp.source}
-# when t==X12::Loop: @x12_definition[t].each{|i| puts i.inspect.gsub(/\\*\"/, '"') ; puts i.regexp.source}
-# else
-# puts @x12_definition[t].inspect
-# end
-# puts "\n\n"
-# }
- # Merge the saved definition, if any, into the newly parsed one
- return unless save_definition
- save_definition.keys.each{|t|
- @x12_definition[t] ||= {}
- save_definition[t].keys.each{|u|
- @x12_definition[t][u] = save_definition[t][u]
+ # Merge the newly parsed definition into a saved one, if any.
+ if save_definition
+ @x12_definition.keys.each{|t|
+ save_definition[t] ||= {}
+ @x12_definition[t].keys.each{|u|
+ save_definition[t][u] = @x12_definition[t][u]
+ }
+ @x12_definition = save_definition
}
- }
+ end
- end
+ #puts PP.pp(self, '')
+ end # initialize
# Parse a loop of a given name out of a string. Throws an exception if the loop name is not defined.
def parse(loop_name, str)
loop = @x12_definition[X12::Loop][loop_name]
+ #puts "Loops to parse #{@x12_definition[X12::Loop].keys}"
throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
loop = loop.dup
loop.parse(str)
return loop
end # parse
@@ -83,10 +103,12 @@
throw Exception.new("Cannot find a definition for loop #{loop_name}") unless loop
loop = loop.dup
return loop
end # factory
+ private
+
# Recursively scan the loop and instantiate fields' definitions for all its
# segments
def process_loop(loop)
loop.nodes.each{|i|
case i
@@ -97,13 +119,14 @@
}
end
# Instantiate segment's fields as previously defined
def process_segment(segment)
+ #puts "Trying to process segment #{segment.inspect}"
unless @x12_definition[X12::Segment] && @x12_definition[X12::Segment][segment.name]
# Try to find it in a separate file if missing from the @x12_definition structure
- initialize(File.join(@dir_name, segment.name+'.d12'))
+ initialize(File.join(@dir_name, segment.name+'.xml'))
segment_definition = @x12_definition[X12::Segment][segment.name]
throw Exception.new("Cannot find a definition for segment #{segment.name}") unless segment_definition
else
segment_definition = @x12_definition[X12::Segment][segment.name]
end
@@ -111,10 +134,10 @@
segment.nodes[i] = segment_definition.nodes[i]
# Make sure we have the validation table if any for this field. Try to read one in if missing.
table = segment.nodes[i].validation
if table
unless @x12_definition[X12::Table] && @x12_definition[X12::Table][table]
- initialize(File.join(@dir_name, table+'.d12'))
+ initialize(File.join(@dir_name, table+'.xml'))
throw Exception.new("Cannot find a definition for table #{table}") unless @x12_definition[X12::Table] && @x12_definition[X12::Table][table]
end
end
}
end