class KXML::SAXParser

Constants

COMMENTS
CONTENT
DOCUMENT_STATEMENT
END_TAG
SELF_CLOSE_TAG
START_TAG

Attributes

handler[RW]

Public Class Methods

new() click to toggle source
# File lib/xml/xml_parser.rb, line 11
def initialize
    reset()
end

Public Instance Methods

<<(data) click to toggle source
# File lib/xml/xml_parser.rb, line 21
def <<(data)
    push(data)
end
finish() click to toggle source
# File lib/xml/xml_parser.rb, line 30
def finish
    @finish = true
    parse()
end
push(data) click to toggle source
# File lib/xml/xml_parser.rb, line 25
def push(data)
    @data += data
    parse()
end
reset() click to toggle source
# File lib/xml/xml_parser.rb, line 15
def reset
    @state = :NONE
    @data = ''
    @finish = false
end

Private Instance Methods

dispath_content(data) click to toggle source
# File lib/xml/xml_parser.rb, line 87
def dispath_content(data)
    @handler.call({:type => CONTENT , :name => data})
end
dispath_tag(data) click to toggle source
# File lib/xml/xml_parser.rb, line 59
def dispath_tag(data)
    if data =~ /<\?xml\s+(.*?)\?>/
        param = parse_tag("STATEMENT #{data.match(/<\?xml\s+(.*?)\?>/)[1]}")
        param[:type] = DOCUMENT_STATEMENT
        @handler.call(param)
        return
    end
    if data =~ /<([\s\S.]*?)\/>/
        param = parse_tag(data.match(/<([\s\S.]*?)\/>/)[1])
        param[:type] = SELF_CLOSE_TAG
        @handler.call(param)
        return
    end
    if data =~ /<\/([\s\S.]*?)>/
        param = parse_tag(data.match(/<\/([\s\S.]*?)>/)[1])
        param[:type] = END_TAG
        @handler.call(param)
        return
    end
    if data =~ /<\!--([\s\S.]*?)-->/
        @handler.call({:type => COMMENTS , :name => data.match(/<\!--([\s\S.]*?)-->/)[1]})
        return
    end
    param = parse_tag(data.match(/<([\s\S.]*?)>/)[1])
    param[:type] = START_TAG
    @handler.call(param)
end
parse() click to toggle source
# File lib/xml/xml_parser.rb, line 37
def parse
    raise "Cannot parse without handler" if @handler == nil
    return if @data == nil || @data == ''
    
    while(true)
        result = @data.match(/^<([\s\S.]*?)>/)
        if result !=nil && @data[0] == '<'
            dispath_tag(result.to_s)
            @data = @data[result[1].size+2,@data.size]
            next
        end
        result = @data.match(/([\s\S.]+?)</)
        if result !=nil
            dispath_content(result[1])
            @data = @data[result[1].size,@data.size]
            next
        end
        break
    end
    dispath_content(@data) if @finish && @data != nil && @data != ''
end
parse_tag(data) click to toggle source
# File lib/xml/xml_parser.rb, line 91
def parse_tag(data)
    data.strip!
    i = data.index(' ')
    if i == nil then
        return {:name => data}
    else
        ret = {}
        ret[:name] = data[0,i]
        ret[:attributes] = {}
        
        data.scan(/[a-zA-Z0-9\_\-]+=\"[\w\W]*?\"/){|s|
            k = /[a-zA-Z0-9\_\-]+(?=(\b*=))/.match(s).to_s
            di = s.index('"')
            si = s.index("'")
            if di == nil then
                i = si
            elsif si == nil then
                i = di
            else
                i = si < di ? si : di
            end
            v = s[i+1,s.size-i-2]
            ret[:attributes][k] = v
        }
        return ret
    end
end