summaryrefslogtreecommitdiff
path: root/jni/ruby/lib/rexml/parsers/treeparser.rb
diff options
context:
space:
mode:
authorJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-16 18:49:26 +0900
committerJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-30 00:39:06 +0900
commitfcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch)
tree64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/rexml/parsers/treeparser.rb
Fresh start
Diffstat (limited to 'jni/ruby/lib/rexml/parsers/treeparser.rb')
-rw-r--r--jni/ruby/lib/rexml/parsers/treeparser.rb100
1 files changed, 100 insertions, 0 deletions
diff --git a/jni/ruby/lib/rexml/parsers/treeparser.rb b/jni/ruby/lib/rexml/parsers/treeparser.rb
new file mode 100644
index 0000000..68edb77
--- /dev/null
+++ b/jni/ruby/lib/rexml/parsers/treeparser.rb
@@ -0,0 +1,100 @@
+require 'rexml/validation/validationexception'
+require 'rexml/undefinednamespaceexception'
+
+module REXML
+ module Parsers
+ class TreeParser
+ def initialize( source, build_context = Document.new )
+ @build_context = build_context
+ @parser = Parsers::BaseParser.new( source )
+ end
+
+ def add_listener( listener )
+ @parser.add_listener( listener )
+ 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 #{@build_context.xpath}",
+ @parser.source, @parser)
+ 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]=Attribute.new(key,value,self)
+ end
+ when :end_element
+ tag_stack.pop
+ @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(
+ 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 = Comment.new( event[1] )
+ @build_context.add( c )
+ when :cdata
+ c = CData.new( event[1] )
+ @build_context.add( c )
+ when :processing_instruction
+ @build_context.add( Instruction.new( event[1], event[2] ) )
+ when :end_doctype
+ in_doctype = false
+ entities.each { |k,v| entities[k] = @build_context.entities[k].value }
+ @build_context = @build_context.parent
+ when :start_doctype
+ doctype = DocType.new( event[1..-1], @build_context )
+ @build_context = doctype
+ entities = {}
+ in_doctype = true
+ when :attlistdecl
+ n = AttlistDecl.new( event[1..-1] )
+ @build_context.add( n )
+ when :externalentity
+ n = ExternalEntity.new( event[1] )
+ @build_context.add( n )
+ when :elementdecl
+ n = ElementDecl.new( event[1] )
+ @build_context.add(n)
+ when :entitydecl
+ entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/
+ @build_context.add(Entity.new(event))
+ when :notationdecl
+ n = NotationDecl.new( *event[1..-1] )
+ @build_context.add( n )
+ when :xmldecl
+ x = XMLDecl.new( event[1], event[2], event[3] )
+ @build_context.add( x )
+ end
+ end
+ rescue REXML::Validation::ValidationException
+ raise
+ rescue REXML::ParseException
+ raise
+ rescue
+ raise ParseException.new( $!.message, @parser.source, @parser, $! )
+ end
+ end
+ end
+ end
+end