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