require 'nqxml/streamingparser' module XML class ParserError < Exception; end class Parser DEFAULT = 0 START_ELEM = 1 END_ELEM = 2 CDATA = 3 PI = 4 UNPARSED_ENTITY_DECL = 5 NOTATION_DECL = 6 EXTERNAL_ENTITY_REF = 7 COMMENT = 8 START_CDATA = 9 END_CDATA = 10 START_NAMESPACE_DECL = 11 END_NAMESPACE_DECL = 12 UNKNOWN_ENCODING = 13 def initialize(*args) @inDocument = false @exception = nil end def parse(stream, *rest) @nqparser = NQXML::StreamingParser.new(stream) begin if block_given? @nqparser.each do |e| case e when NQXML::Tag if e.isTagStart @inDocument = e.name unless @inDocument yield(START_ELEM, e.name, e.attrs) else @inDocument = false if @inDocument == e.name yield(END_ELEM, e.name, nil) end when NQXML::Text next unless @inDocument yield(CDATA, nil, e.text) when NQXML::ProcessingInstruction data = e.source.sub(/<\?[^ \t\n\r]+[ \t\n\r]+(.*)\?>/m, '\1') yield(PI, e.name, data) when NQXML::Comment if respond_to?(:comment) data = e.source.sub(//m, '\1') yield(COMMENT, nil, data) end else ## ignore end end else @nqparser.each do |e| case e when NQXML::Tag if e.isTagStart @inDocument = e.name unless @inDocument startElement(e.name, e.attrs) if respond_to?(:startElement) else @inDocument = false if @inDocument == e.name endElement(e.name) if respond_to?(:endElement) end when NQXML::Text next unless @inDocument character(e.text) if respond_to?(:character) when NQXML::ProcessingInstruction next if e.name == 'xml' ## XML decraration is not a PI if respond_to?(:processingInstruction) data = e.source.sub(/<\?[^ \t\n\r]+[ \t\n\r]+(.*)\?>/m, '\1') processingInstruction(e.name, data) end when NQXML::Comment if respond_to?(:comment) data = e.source.sub(//m, '\1') comment(data) end else ## ignore end end ## each end ## if rescue NQXML::ParserError @exception = $! raise ParserError.new(@exception.message) end ## begin end ## parse def done; end def defaultCurrent; end def line return @exception.line if @exception 0 end def column return @exception.column if @exception 0 end def byteIndex return @exception.pos if @exception 0 end def setBase(baseURL); end end end