Sha256: da2ab4277e21d1cb97adbd6fb457f6b9f72c1f01afc18e7e30baef14005d92d5

Contents?: true

Size: 1.8 KB

Versions: 2

Compression:

Stored size: 1.8 KB

Contents

module Relief
  class Element
    attr_reader :name, :options, :children

    def initialize(name=nil, options={}, &block)
      @name = name
      @options = options
      @children = []

      instance_eval(&block) if block_given?
    end

    def parse(document)
      @children.inject({}) do |values, element|
        key = element.options[:as] || element.name
        type = element.options[:type]

        values[key] = begin
          target = (document / element.xpath)

          parse_node = lambda { |target|
            if element.children.any?
              element.parse(target)
            else
              value = target.to_s

              if type == Integer then value.to_i
              elsif type == Float then value.to_f
              elsif type == Date then Date.parse(value)
              elsif type.is_a?(Parser) then type.parse(document)
              else value
              end
            end
          }

          if element.options[:collection]
            target.collect { |child| parse_node.call(child) }
          else
            parse_node.call(target)
          end
        end

        values
      end
    end

    def element(name, options={}, &block)
      options[:xpath] ||= name if name =~ %r([/.])
      @children << self.class.new(name, options, &block)
    end

    def elements(name, options={}, &block)
      element(name, options.merge(:collection => true), &block)
    end

    def attribute(name, options={}, &block)
      element(name, options.merge(:attribute => true), &block)
    end

    def xpath
      if options.has_key?(:xpath)
        options[:xpath]
      elsif @children.any?
        name.to_s
      else
        attribute = @options[:attribute]
        attribute = name if attribute == true
        !attribute ? "#{name}/text()" : "@#{attribute}"
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 2 rubygems

Version Path
tylerhunt-relief-0.0.4 lib/relief/element.rb
relief-0.0.4 lib/relief/element.rb