class HappyMapper::Item
Attributes
Public Class Methods
options:
:deep => Boolean False to only parse element's children, True to include grandchildren and all others down the chain (// in xpath) :namespace => String Element's namespace if it's not the global or inherited default :parser => Symbol Class method to use for type coercion. :raw => Boolean Use raw node value (inc. tags) when parsing. :single => Boolean False if object should be collection, True for single object :tag => String Element name if it doesn't match the specified name.
# File lib/happymapper/item.rb, line 14 def initialize(name, type, o={}) self.name = name.to_s self.type = type #self.tag = o.delete(:tag) || name.to_s self.tag = o[:tag] || name.to_s self.options = { :single => true }.merge(o.merge(:name => self.name)) @xml_type = self.class.to_s.split('::').last.downcase end
Public Instance Methods
# File lib/happymapper/item.rb, line 24 def constant @constant ||= constantize(type) end
@param [XMLNode] node the xml node that is being parsed @param [String] namespace the name of the namespace @param [Hash] xpath_options additional xpath options
# File lib/happymapper/item.rb, line 33 def from_xml_node(node, namespace, xpath_options) namespace = options[:namespace] if options.key?(:namespace) if suported_type_registered? find(node, namespace, xpath_options) { |n| process_node_as_supported_type(n) } elsif constant == XmlContent find(node, namespace, xpath_options) { |n| process_node_as_xml_content(n) } elsif custom_parser_defined? find(node, namespace, xpath_options) { |n| process_node_with_custom_parser(n) } else process_node_with_default_parser(node,:namespaces => xpath_options) end end
# File lib/happymapper/item.rb, line 58 def method_name @method_name ||= name.tr('-', '_') end
Convert the value into the correct type.
@param [String] value the string value parsed from the XML value that will
be converted to the particular primitive type.
@return [String,Float,Time,Date,DateTime,Boolean,Integer] the converted value
to the new type.
# File lib/happymapper/item.rb, line 71 def typecast(value) typecaster(value).apply(value) end
# File lib/happymapper/item.rb, line 49 def xpath(namespace = self.namespace) xpath = '' xpath += './/' if options[:deep] xpath += "#{namespace}:" if namespace xpath += tag #puts "xpath: #{xpath}" xpath end
Private Instance Methods
Convert any String defined types into their constant version so that the method parse or the custom defined parser method would be used.
@param [String,Constant] type is the name of the class or the constant
for the class.
@return [Constant] the constant of the type
# File lib/happymapper/item.rb, line 141 def constantize(type) type.is_a?(String) ? convert_string_to_constant(type) : type end
# File lib/happymapper/item.rb, line 145 def convert_string_to_constant(type) names = type.split('::') constant = Object names.each do |name| constant = if constant.const_defined?(name) constant.const_get(name) else constant.const_missing(name) end end constant end
A custom parser is a custom parse method on the class. When the parser option has been set this value is the name of the method which will be used to parse the node content.
# File lib/happymapper/item.rb, line 111 def custom_parser_defined? options[:parser] end
Processes a Nokogiri::XML::Node as a supported type
# File lib/happymapper/item.rb, line 93 def process_node_as_supported_type(node) content = node.respond_to?(:content) ? node.content : node typecast(content) end
Process a Nokogiri::XML::Node as XML Content
# File lib/happymapper/item.rb, line 101 def process_node_as_xml_content(node) node = node.children if node.respond_to?(:children) node.respond_to?(:to_xml) ? node.to_xml : node.to_s end
# File lib/happymapper/item.rb, line 115 def process_node_with_custom_parser(node) if node.respond_to?(:content) && !options[:raw] value = node.content else value = node.to_s end begin constant.send(options[:parser].to_sym, value) rescue nil end end
# File lib/happymapper/item.rb, line 129 def process_node_with_default_parser(node,parse_options) constant.parse(node,options.merge(parse_options)) end
@return [Boolean] true if the type defined for the item is defined in the
list of support types.
# File lib/happymapper/item.rb, line 80 def suported_type_registered? SupportedTypes.types.map {|caster| caster.type }.include?(constant) end
@return [#apply] the typecaster object that will be able to convert
the value into a value with the correct type.
# File lib/happymapper/item.rb, line 86 def typecaster(value) SupportedTypes.types.find { |caster| caster.apply?(value,constant) } end