Class: Xmlmap
- Inherits:
-
Object
- Object
- Xmlmap
- Defined in:
- lib/xmlmap.rb
Class Method Summary collapse
-
.all ⇒ Object
the #all method, which will create an array of fresh instances for all the elements that match the chosen path.
- .find_many(path_parts) ⇒ Object
- .get_destination_relative_path_to_self(destination_name) ⇒ Object
- .get_xml_path ⇒ Object
-
.has_many(what, opts = {}) ⇒ Object
lets build a method with the name of the associated entity (yay metaprogramming!), that searches for subelements using the part that is relative to the base (the last) or in the case that the destination entity is not nested into the origin one (that happens when we receive the :non_descendant_path option), calling the ::all method on the associated class.
-
.inherited(subclass) ⇒ Object
when Xmlmap is inherited, we create the @xml_map variable in the context of the inheritor metaclass, this variable will contain the results of configuration.
- .set_path(path, opts = {}) ⇒ Object
- .set_url(url) ⇒ Object
- .stringify_path(path_parts) ⇒ Object
Instance Method Summary collapse
-
#find_many(subpath, class_name) ⇒ Object
find_many simpy passes the call to the #search Nokogiri method, to bring subelelements by a css string or xpath and creates instances for the corresponding class.
-
#initialize(element) ⇒ Xmlmap
constructor
this is the method that will run when an inheritor class receives a ::new message.
-
#method_missing(name, *args, &block) ⇒ Object
we divert all calls to unknown methods of instances of classes that inherit Xmlmap to the associated Nokogiri object for that instance.
Constructor Details
#initialize(element) ⇒ Xmlmap
this is the method that will run when an inheritor class receives a ::new message
98 99 100 |
# File 'lib/xmlmap.rb', line 98 def initialize(element) @xml_element = element end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
we divert all calls to unknown methods of instances of classes that inherit Xmlmap to the associated Nokogiri object for that instance. That way you can use Nokogiri methods like #at, #inner_text, etc directly against the Xmlmap objects
103 104 105 |
# File 'lib/xmlmap.rb', line 103 def method_missing(name, *args, &block) @xml_element.send(name, *args, &block) end |
Class Method Details
.all ⇒ Object
the #all method, which will create an array of fresh instances for all the elements that match the chosen path
40 41 42 43 44 |
# File 'lib/xmlmap.rb', line 40 def all find_many(self.get_xml_path).map do |xml_element| self.new(xml_element) end end |
.find_many(path_parts) ⇒ Object
50 51 52 |
# File 'lib/xmlmap.rb', line 50 def find_many(path_parts) @xml_map[:xml_object].search stringify_path(path_parts) end |
.get_destination_relative_path_to_self(destination_name) ⇒ Object
67 68 69 70 71 72 73 74 |
# File 'lib/xmlmap.rb', line 67 def get_destination_relative_path_to_self(destination_name) destination_path = destination_name.classify.constantize.get_xml_path if destination_path.is_a? Array destination_path.last else destination_path end end |
.get_xml_path ⇒ Object
46 47 48 |
# File 'lib/xmlmap.rb', line 46 def get_xml_path @xml_map[:path] end |
.has_many(what, opts = {}) ⇒ Object
lets build a method with the name of the associated entity (yay metaprogramming!), that searches for subelements using the part that is relative to the base (the last) or in the case that the destination entity is not nested into the origin one (that happens when we receive the :non_descendant_path option), calling the ::all method on the associated class. If an anonymous function (Proc) called :conditions is present in options, the found instances will be filtered by it.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/xmlmap.rb', line 78 def has_many(what, opts={}) define_method(what) do if opts[:non_descendant_path] result_instances = what.to_s.classify.constantize.all else subpath = self.class.get_destination_relative_path_to_self(what.to_s) result_instances = find_many(subpath, what.to_s) end if opts[:conditions] result_instances = result_instances.select {|result_instance| opts[:conditions].call(self, result_instance) } end result_instances end end |
.inherited(subclass) ⇒ Object
when Xmlmap is inherited, we create the @xml_map variable in the context of the inheritor metaclass, this variable will contain the results of configuration
19 20 21 22 23 |
# File 'lib/xmlmap.rb', line 19 def inherited(subclass) subclass.class_eval do @xml_map = {} end end |
.set_path(path, opts = {}) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/xmlmap.rb', line 30 def set_path(path, opts = {}) #if there is an established base we'll build an anonymous function (Proc) that triggers the construction of the route that corresponds to taht base function, else the path for this class will simply be the string in the path parameter. Pay attention to the fact that the xml_path method we call here simpy returns the contents of @xml_map[:path] in the base class. So what we are doing is we are going up the hierarchy until we reeach a "patriarch" class that contains an absolute path and then we add strings for routes as we go down. if opts[:base] @xml_map[:path] = [ Proc.new { opts[:base].to_s.classify.constantize.get_xml_path }, path ] else @xml_map[:path] = path end end |
.set_url(url) ⇒ Object
25 26 27 28 |
# File 'lib/xmlmap.rb', line 25 def set_url(url) @xml_map[:url] = url @xml_map[:xml_object] = Nokogiri::XML(open(@xml_map[:url])) end |
.stringify_path(path_parts) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/xmlmap.rb', line 54 def stringify_path(path_parts) #if this is a single element, we'll still create an array with a single element just like when we receive an array - we verify in Duck Typing fashion path_parts = [path_parts] unless path_parts.respond_to?(:join) path_parts = path_parts.flatten.map do |path_part| if path_part.respond_to?(:call) path_part.call else path_part end end path_parts.join(' ') end |
Instance Method Details
#find_many(subpath, class_name) ⇒ Object
find_many simpy passes the call to the #search Nokogiri method, to bring subelelements by a css string or xpath and creates instances for the corresponding class
108 109 110 |
# File 'lib/xmlmap.rb', line 108 def find_many(subpath, class_name) self.search(subpath).map {|xml_element| class_name.classify.constantize.new(xml_element) } end |