class Nori::XMLUtilityNode
This is a slighly modified version of the XMLUtilityNode from merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)
John Nunemaker: It's mainly just adding vowels, as I ht cd wth n vwls :) This represents the hard part of the work, all I did was change the underlying parser.
Constants
- XS_DATE
Simple xs:date Regexp. Valid xs:date formats 2004-04-12 April 12, 2004 -0045-01-01 January 1, 45 BC 12004-04-12 April 12, 12004 2004-04-12-05:00 April 12, 2004, US Eastern Standard Time, which is 5 hours behind Coordinated Universal Time (UTC) 2004-04-12+02:00 April 12, 2004, Central European Summer Time, which is 2 hours ahead of Coordinated Universal Time (UTC) 2004-04-12Z April 12, 2004, Coordinated Universal Time (UTC)
- XS_DATE_TIME
Simple xs:dateTime Regexp. Valid xs:dateTime formats 2004-04-12T13:20:00 1:20 pm on April 12, 2004 2004-04-12T13:20:15.5 1:20 pm and 15.5 seconds on April 12, 2004 2004-04-12T13:20:00-05:00 1:20 pm on April 12, 2004, US Eastern Standard Time 2004-04-12T13:20:00+02:00 1:20 pm on April 12, 2004, Central European Summer Time 2004-04-12T13:20:15.5-05:00 1:20 pm and 15.5 seconds on April 12, 2004, US Eastern Standard Time 2004-04-12T13:20:00Z 1:20 pm on April 12, 2004, Coordinated Universal Time (UTC) 2004-04-12T13:20:15.5Z 1:20 pm and 15.5 seconds on April 12, 2004, Coordinated Universal Time (UTC)
- XS_TIME
Simple xs:time Regexp. Valid xs:time formats 13:20:00 1:20 PM 13:20:30.5555 1:20 PM and 30.5555 seconds 13:20:00-05:00 1:20 PM, US Eastern Standard Time 13:20:00+02:00 1:20 PM, Central European Standard Time 13:20:00Z 1:20 PM, Coordinated Universal Time (UTC) 13:20:30.5555Z 1:20 PM and 30.5555 seconds, Coordinated Universal Time (UTC) 00:00:00 midnight 24:00:00 midnight
Attributes
Public Class Methods
# File lib/nori/xml_utility_node.rb, line 64 def self.available_typecasts @@available_typecasts end
# File lib/nori/xml_utility_node.rb, line 68 def self.available_typecasts=(obj) @@available_typecasts = obj end
# File lib/nori/xml_utility_node.rb, line 86 def initialize(options, name, attributes = {}) @options = options @name = Nori.hash_key(name, options) if converter = options[:convert_attributes_to] intermediate = attributes.map {|k, v| converter.call(k, v) }.flatten attributes = Hash[*intermediate] end # leave the type alone if we don't know what it is @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"] @nil_element = false attributes.keys.each do |key| if result = /^((.*):)?nil$/.match(key) @nil_element = attributes.delete(key) == "true" attributes.delete("xmlns:#{result[2]}") if result[1] end attributes.delete(key) if @options[:delete_namespace_attributes] && key[/^(xmlns|xsi)/] end @attributes = undasherize_keys(attributes) @children = [] @text = false end
# File lib/nori/xml_utility_node.rb, line 56 def self.typecasts @@typecasts end
# File lib/nori/xml_utility_node.rb, line 60 def self.typecasts=(obj) @@typecasts = obj end
Public Instance Methods
# File lib/nori/xml_utility_node.rb, line 125 def add_node(node) @text = true if node.is_a? String @children << node end
# File lib/nori/xml_utility_node.rb, line 214 def advanced_typecasting(value) split = value.split return value if split.size > 1 case split.first when "true" then true when "false" then false when XS_DATE_TIME then try_to_convert(value) {|x| DateTime.parse(x)} when XS_DATE then try_to_convert(value) {|x| Date.parse(x)} when XS_TIME then try_to_convert(value) {|x| Time.parse(x)} else value end end
Get the #inner_html of the REXML node.
# File lib/nori/xml_utility_node.rb, line 237 def inner_html @children.join end
# File lib/nori/xml_utility_node.rb, line 120 def prefixed_attribute_name(attribute) return attribute unless @options[:convert_tags_to].respond_to? :call @options[:convert_tags_to].call(attribute) end
# File lib/nori/xml_utility_node.rb, line 113 def prefixed_attributes attributes.inject({}) do |memo, (key, value)| memo[prefixed_attribute_name("@#{key}")] = value memo end end
# File lib/nori/xml_utility_node.rb, line 130 def to_hash if @type == "file" f = StringIOFile.new((@children.first || '').unpack('m').first) f.original_filename = attributes['name'] || 'untitled' f.content_type = attributes['content_type'] || 'application/octet-stream' return { name => f } end if @text t = typecast_value(inner_html) t = advanced_typecasting(t) if t.is_a?(String) && @options[:advanced_typecasting] if t.is_a?(String) t = StringWithAttributes.new(t) t.attributes = attributes end return { name => t } else #change repeating groups into an array groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s } out = nil if @type == "array" out = [] groups.each do |k, v| if v.size == 1 out << v.first.to_hash.entries.first.last else out << v.map{|e| e.to_hash[k]} end end out = out.flatten else # If Hash out = {} groups.each do |k,v| if v.size == 1 out.merge!(v.first) else out.merge!( k => v.map{|e| e.to_hash[k]}) end end out.merge! prefixed_attributes unless attributes.empty? out = out.empty? ? @options[:empty_tag_value] : out end if @type && out.nil? { name => typecast_value(out) } else { name => out } end end end
Converts the node into a readable HTML node.
@return <String> The HTML node in text form.
# File lib/nori/xml_utility_node.rb, line 244 def to_html attributes.merge!(:type => @type ) if @type "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>" end
Typecasts a value based upon its type. For instance, if node
has type == “integer”,
{{[node.typecast_value(“12”) #=> 12]}}
@param value<String> The value that is being typecast.
@details [:type options]
"integer":: converts +value+ to an integer with #to_i "boolean":: checks whether +value+, after removing spaces, is the literal "true" "datetime":: Parses +value+ using Time.parse, and returns a UTC Time "date":: Parses +value+ using Date.parse
@return <Integer, TrueClass, FalseClass, Time, Date, Object>
The result of typecasting +value+.
@note
If +self+ does not have a "type" key, or if it's not one of the options specified above, the raw +value+ will be returned.
# File lib/nori/xml_utility_node.rb, line 208 def typecast_value(value) return value unless @type proc = self.class.typecasts[@type] proc.nil? ? value : proc.call(value) end
Take keys of the form foo-bar and convert them to foo_bar
# File lib/nori/xml_utility_node.rb, line 229 def undasherize_keys(params) params.keys.each do |key, value| params[key.tr("-", "_")] = params.delete(key) end params end
Private Instance Methods
# File lib/nori/xml_utility_node.rb, line 257 def strip_namespace(string) string.split(":").last end
# File lib/nori/xml_utility_node.rb, line 251 def try_to_convert(value, &block) block.call(value) rescue ArgumentError value end