Sha256: 676da14b7c1af0f2ca40d05fcc42d0904d2c4893fe34aaf8467b83ac693c1418

Contents?: true

Size: 1.71 KB

Versions: 2

Compression:

Stored size: 1.71 KB

Contents

require 'nokogiri'

module Saxy
  class Parser < Nokogiri::XML::SAX::Document
    include Enumerable

    # Stack of XML tags built while traversing XML tree
    attr_reader :tags

    # Stack of elements built while traversing XML tree
    #
    # First element is pushed to the stack only after finding the object_tag in
    # the XML tree.
    attr_reader :elements

    # Will yield objects inside the callback after they're built
    attr_reader :callback

    def initialize(xml_file, object_tag)
      @xml_file, @object_tag = xml_file, object_tag
      @tags, @elements = [], []
    end

    def start_element(tag, attributes=[])
      @tags << tag

      if tag == @object_tag || elements.any?
        elements << Element.new

        attributes.each do |(attr, value)|
          current_element.set_attribute(attr, value)
        end
      end
    end

    def end_element(tag)
      tags.pop
      if element = elements.pop
        object = element.as_object

        if current_element
          current_element.set_attribute(tag, object)
        elsif callback
          callback.call(object)
        end
      end
    end

    def cdata_block(cdata)
      current_element.append_value(cdata) if current_element
    end

    def characters(chars)
      current_element.append_value(chars) if current_element
    end

    def error(message)
      raise ParsingError.new(message)
    end

    def current_element
      elements.last
    end

    def each(&blk)
      if blk
        @callback = blk

        parser = Nokogiri::XML::SAX::Parser.new(self)

        if @xml_file.is_a?(IO)
          parser.parse_io(@xml_file)
        else
          parser.parse_file(@xml_file)
        end
      else
        to_enum
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
saxy-0.2.3 lib/saxy/parser.rb
saxy-0.2.2 lib/saxy/parser.rb