module Hobo::Dryml::Parser class TreeParser < REXML::Parsers::TreeParser def initialize( source, build_context = Document.new ) @build_context = build_context @parser = Hobo::Dryml::Parser::BaseParser.new(source) end def parse tag_stack = [] in_doctype = false entities = nil begin while true event = @parser.pull #STDERR.puts "TREEPARSER GOT #{event.inspect}" case event[0] when :end_document unless tag_stack.empty? #raise ParseException.new("No close tag for #{tag_stack.inspect}") raise ParseException.new("No close tag for #{@build_context.xpath}") end return when :start_element tag_stack.push(event[1]) el = @build_context = @build_context.add_element( event[1] ) event[2].each do |key, value| el.attributes[key]=Hobo::Dryml::Parser::Attribute.new(key,value,self) end @build_context.start_tag_source = event[3] @build_context.source_offset = event[4] when :end_element tag_stack.pop @build_context.has_end_tag = event[2] @build_context = @build_context.parent when :text if not in_doctype if @build_context[-1].instance_of? Text @build_context[-1] << event[1] else @build_context.add( Hobo::Dryml::Parser::Text.new(event[1], @build_context.whitespace, nil, true) ) unless ( @build_context.ignore_whitespace_nodes and event[1].strip.size==0 ) end end when :comment c = REXML::Comment.new( event[1] ) @build_context.add( c ) when :cdata c = REXML::CData.new( event[1] ) @build_context.add( c ) when :processing_instruction @build_context.add( Instruction.new( event[1], event[2] ) ) end end rescue REXML::Validation::ValidationException raise rescue raise REXML::ParseException.new( $!.message, @parser.source, @parser, $! ) end end end end