File: rexml/parsers/treeparser.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: REXML#4
  module: Parsers#5
  class: TreeParser#6
inherits from
  Object ( Builtin-Module )
has properties
method: initialize / 2 #7
method: add_listener / 1 #12
method: parse #16

Class Hierarchy

Code

   1  require 'rexml/validation/validationexception'
   2  require 'rexml/undefinednamespaceexception'
   3 
   4  module 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
  97  end