1# frozen_string_literal: false 2require_relative 'streamparser' 3require_relative 'baseparser' 4require_relative '../light/node' 5 6module REXML 7 module Parsers 8 class LightParser 9 def initialize stream 10 @stream = stream 11 @parser = REXML::Parsers::BaseParser.new( stream ) 12 end 13 14 def add_listener( listener ) 15 @parser.add_listener( listener ) 16 end 17 18 def rewind 19 @stream.rewind 20 @parser.stream = @stream 21 end 22 23 def parse 24 root = context = [ :document ] 25 while true 26 event = @parser.pull 27 case event[0] 28 when :end_document 29 break 30 when :start_element, :start_doctype 31 new_node = event 32 context << new_node 33 new_node[1,0] = [context] 34 context = new_node 35 when :end_element, :end_doctype 36 context = context[1] 37 else 38 new_node = event 39 context << new_node 40 new_node[1,0] = [context] 41 end 42 end 43 root 44 end 45 end 46 47 # An element is an array. The array contains: 48 # 0 The parent element 49 # 1 The tag name 50 # 2 A hash of attributes 51 # 3..-1 The child elements 52 # An element is an array of size > 3 53 # Text is a String 54 # PIs are [ :processing_instruction, target, data ] 55 # Comments are [ :comment, data ] 56 # DocTypes are DocType structs 57 # The root is an array with XMLDecls, Text, DocType, Array, Text 58 end 59end 60