class HappyMapper::AnonymousMapper
Public Instance Methods
parse(xml_content)
click to toggle source
# File lib/happymapper/anonymous_mapper.rb, line 5 def parse(xml_content) # TODO: this should be able to handle all the types of functionality that parse is able # to handle which includes the text, xml document, node, fragment, etc. xml = Nokogiri::XML(xml_content) klass = create_happymapper_class_from_node(xml.root) # With all the elements and attributes defined on the class it is time # for the class to actually use the normal HappyMapper powers to parse # the content. At this point this code is utilizing all of the existing # code implemented for parsing. klass.parse(xml_content, single: true) end
Private Instance Methods
create_happymapper_class_from_node(node)
click to toggle source
Used internally to create and define the necessary happymapper elements.
# File lib/happymapper/anonymous_mapper.rb, line 53 def create_happymapper_class_from_node(node) klass = create_happymapper_class_with_tag(node.name) klass.namespace node.namespace.prefix if node.namespace node.namespaces.each do |prefix, namespace| klass.register_namespace prefix, namespace end node.attributes.each_value do |attribute| define_attribute_on_class(klass, attribute) end node.children.each do |child| define_element_on_class(klass, child) end klass end
create_happymapper_class_with_tag(tag_name)
click to toggle source
Used internally when parsing to create a class that is capable of parsing the content. The name of the class is of course not likely going to match the content it will be able to parse so the tag value is set to the one provided.
# File lib/happymapper/anonymous_mapper.rb, line 40 def create_happymapper_class_with_tag(tag_name) klass = Class.new klass.class_eval do include HappyMapper tag tag_name end klass end
define_attribute_on_class(klass, attribute)
click to toggle source
Define a HappyMapper
attribute on the provided class based on the attribute provided.
# File lib/happymapper/anonymous_mapper.rb, line 113 def define_attribute_on_class(klass, attribute) klass.attribute underscore(attribute.name), String, tag: attribute.name end
define_element_on_class(klass, node)
click to toggle source
Define a HappyMapper
element on the provided class based on the node provided.
# File lib/happymapper/anonymous_mapper.rb, line 77 def define_element_on_class(klass, node) # When a text node has been provided create the necessary # HappyMapper content attribute if the text happens to contain # some content. if node.text? klass.content :content, String if node.content.strip != '' return end # When the node has child elements, that are not text # nodes, then we want to recursively define a new HappyMapper # class that will have elements and attributes. element_type = if node.elements.any? || node.attributes.any? create_happymapper_class_from_node(node) else String end element_name = underscore(node.name) method = klass.elements.find { |e| e.name == element_name } ? :has_many : :has_one options = {} options[:tag] = node.name namespace = node.namespace options[:namespace] = namespace.prefix if namespace options[:xpath] = './' unless element_type == String klass.send(method, element_name, element_type, options) end
underscore(camel_cased_word)
click to toggle source
Borrowed from Active Support to convert unruly element names into a format known and loved by Rubyists.
# File lib/happymapper/anonymous_mapper.rb, line 25 def underscore(camel_cased_word) word = camel_cased_word.to_s.dup word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') word.tr!('-', '_') word.downcase! word end