PageRenderTime 234ms CodeModel.GetById 222ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/Ruby/lib/ruby/1.8/rexml/parsers/treeparser.rb

http://github.com/agross/netopenspace
Ruby | 97 lines | 92 code | 3 blank | 2 comment | 4 complexity | e4ba711b20e726c25c10f36ee8470ff6 MD5 | raw file
 1require 'rexml/validation/validationexception'
 2require 'rexml/undefinednamespaceexception'
 3
 4module REXML
 5  module Parsers
 6    class TreeParser
 7      def initialize( source, build_context = Document.new )
 8        @build_context = build_context
 9        @parser = Parsers::BaseParser.new( source )
10      end
11
12      def add_listener( listener )
13        @parser.add_listener( listener )
14      end
15
16      def parse
17        tag_stack = []
18        in_doctype = false
19        entities = nil
20        begin
21          while true
22            event = @parser.pull
23            #STDERR.puts "TREEPARSER GOT #{event.inspect}"
24            case event[0]
25            when :end_document
26              unless tag_stack.empty?
27                #raise ParseException.new("No close tag for #{tag_stack.inspect}")
28                raise ParseException.new("No close tag for #{@build_context.xpath}")
29              end
30              return
31            when :start_element
32              tag_stack.push(event[1])
33              el = @build_context = @build_context.add_element( event[1], event[2] )
34            when :end_element
35              tag_stack.pop
36              @build_context = @build_context.parent
37            when :text
38              if not in_doctype
39                if @build_context[-1].instance_of? Text
40                  @build_context[-1] << event[1]
41                else
42                  @build_context.add( 
43                    Text.new(event[1], @build_context.whitespace, nil, true) 
44                  ) unless (
45                    @build_context.ignore_whitespace_nodes and
46                    event[1].strip.size==0
47                  )
48                end
49              end
50            when :comment
51              c = Comment.new( event[1] )
52              @build_context.add( c )
53            when :cdata
54              c = CData.new( event[1] )
55              @build_context.add( c )
56            when :processing_instruction
57              @build_context.add( Instruction.new( event[1], event[2] ) )
58            when :end_doctype
59              in_doctype = false
60              entities.each { |k,v| entities[k] = @build_context.entities[k].value }
61              @build_context = @build_context.parent
62            when :start_doctype
63              doctype = DocType.new( event[1..-1], @build_context )
64              @build_context = doctype
65              entities = {}
66              in_doctype = true
67            when :attlistdecl
68              n = AttlistDecl.new( event[1..-1] )
69              @build_context.add( n )
70            when :externalentity
71              n = ExternalEntity.new( event[1] )
72              @build_context.add( n )
73            when :elementdecl
74              n = ElementDecl.new( event[1] )
75              @build_context.add(n)
76            when :entitydecl
77              entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
78              @build_context.add(Entity.new(event))
79            when :notationdecl
80              n = NotationDecl.new( *event[1..-1] )
81              @build_context.add( n )
82            when :xmldecl
83              x = XMLDecl.new( event[1], event[2], event[3] )
84              @build_context.add( x )
85            end
86          end
87        rescue REXML::Validation::ValidationException
88          raise
89        rescue REXML::UndefinedNamespaceException
90          raise
91        rescue
92          raise ParseException.new( $!.message, @parser.source, @parser, $! )
93        end
94      end
95    end
96  end
97end