Class: Xmlcellent::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/xmlcellent/parser.rb

Overview

Handles the parsing of XML data using Xmlcellent::Format objects.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.formatsObject

Returns the value of attribute formats.



13
14
15
# File 'lib/xmlcellent/parser.rb', line 13

def formats
  @formats
end

Class Method Details

.define_format(name, model = nil, config = {}) ⇒ Object

Creates a format on the Xmlcellent::Parser object to be used to convert XML to models.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/xmlcellent/parser.rb', line 35

def define_format(name, model = nil, config = {})
  @formats ||= {}
  raise "Format already exists!" if @formats.has_key? name
  @formats[name] = Format.new(config)

  # This ugly piece of code is used to dynamically generate
  # class methods in a way that Ruby 1.8 understands.
  singleton = class << self; self; end
  singleton.instance_eval do
    define_method("parse_#{name.to_s}".to_sym) do |doc|
      document = doc.class == Nokogiri::XML::Document ?
        doc :
        Nokogiri::XML(doc).remove_namespaces!
      results  = []

      document.xpath(@formats[name].finder).each do |obj|
        m = model.new
        @formats[name].lexicon.each do |key, path|
          next if path.nil? # fail silently if given a bad path

          value = path.class == Proc ? path.call(obj) : obj.xpath(path).text
          m.send("#{key.to_s}=".to_sym, value)
        end
        results << m
      end
      results
    end
  end
end

.delete_formats!Object

Erases all existing formats



16
17
18
# File 'lib/xmlcellent/parser.rb', line 16

def delete_formats!
  @formats = {}
end

.parse(doc) ⇒ Object

Given a string of XML, this method loops through the defined Formats and, if it finds a match, calls that method to parse the XML into objects.



23
24
25
26
27
28
29
30
31
# File 'lib/xmlcellent/parser.rb', line 23

def parse(doc)
  document = Nokogiri::XML(doc).remove_namespaces!
  @formats.each do |key, format|
    if document.xpath(format.finder).length > 0
      return self.send("parse_#{key}".to_sym, doc)
    end
  end
  raise "Error: Parser not found!"
end