0
@@ -78,3 +78,215 @@ class String
0
+require 'rexml/parsers/streamparser'
0
+require 'rexml/parsers/baseparser'
0
+require 'rexml/light/node'
0
+# This is a slighly modified version of the XMLUtilityNode from
0
+# http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)
0
+# It's mainly just adding vowels, as I ht cd wth n vwls :)
0
+# This represents the hard part of the work, all I did was change the
0
+ attr_accessor :name, :attributes, :children, :type
0
+ def self.typecasts=(obj)
0
+ def self.available_typecasts
0
+ def self.available_typecasts=(obj)
0
+ self.typecasts["integer"] = lambda{|v| v.nil? ? nil : v.to_i}
0
+ self.typecasts["boolean"] = lambda{|v| v.nil? ? nil : (v.strip != "false")}
0
+ self.typecasts["datetime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
0
+ self.typecasts["date"] = lambda{|v| v.nil? ? nil : Date.parse(v)}
0
+ self.typecasts["dateTime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc}
0
+ self.typecasts["decimal"] = lambda{|v| BigDecimal(v)}
0
+ self.typecasts["double"] = lambda{|v| v.nil? ? nil : v.to_f}
0
+ self.typecasts["float"] = lambda{|v| v.nil? ? nil : v.to_f}
0
+ self.typecasts["symbol"] = lambda{|v| v.to_sym}
0
+ self.typecasts["string"] = lambda{|v| v.to_s}
0
+ self.typecasts["yaml"] = lambda{|v| v.nil? ? nil : YAML.load(v)}
0
+ self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first }
0
+ self.available_typecasts = self.typecasts.keys
0
+ def initialize(name, attributes = {})
0
+ @name = name.tr("-", "_")
0
+ # leave the type alone if we don't know what it is
0
+ @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"]
0
+ @nil_element = attributes.delete("nil") == "true"
0
+ @attributes = undasherize_keys(attributes)
0
+ @text = true if node.is_a? String
0
+ f = StringIO.new((@children.first || '').unpack('m').first)
0
+ attr_accessor :original_filename, :content_type
0
+ f.original_filename = attributes['name'] || 'untitled'
0
+ f.content_type = attributes['content_type'] || 'application/octet-stream'
0
+ return { name => typecast_value( translate_xml_entities( inner_html ) ) }
0
+ #change repeating groups into an array
0
+ groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s }
0
+ out << v.first.to_hash.entries.first.last
0
+ out << v.map{|e| e.to_hash[k]}
0
+ out.merge!( k => v.map{|e| e.to_hash[k]})
0
+ out.merge! attributes unless attributes.empty?
0
+ out = out.empty? ? nil : out
0
+ { name => typecast_value(out) }
0
+ # Typecasts a value based upon its type. For instance, if
0
+ # +node+ has #type == "integer",
0
+ # {{[node.typecast_value("12") #=> 12]}}
0
+ # @param value<String> The value that is being typecast.
0
+ # @details [:type options]
0
+ # converts +value+ to an integer with #to_i
0
+ # checks whether +value+, after removing spaces, is the literal
0
+ # Parses +value+ using Time.parse, and returns a UTC Time
0
+ # Parses +value+ using Date.parse
0
+ # @return <Integer, TrueClass, FalseClass, Time, Date, Object>
0
+ # The result of typecasting +value+.
0
+ # If +self+ does not have a "type" key, or if it's not one of the
0
+ # options specified above, the raw +value+ will be returned.
0
+ def typecast_value(value)
0
+ return value unless @type
0
+ proc = self.class.typecasts[@type]
0
+ proc.nil? ? value : proc.call(value)
0
+ # Convert basic XML entities into their literal values.
0
+ # @param value<#gsub> An XML fragment.
0
+ # @return <#gsub> The XML fragment after converting entities.
0
+ def translate_xml_entities(value)
0
+ value.gsub(/</, "<").
0
+ # Take keys of the form foo-bar and convert them to foo_bar
0
+ def undasherize_keys(params)
0
+ params.keys.each do |key, value|
0
+ params[key.tr("-", "_")] = params.delete(key)
0
+ # Get the inner_html of the REXML node.
0
+ # Converts the node into a readable HTML node.
0
+ # @return <String> The HTML node in text form.
0
+ attributes.merge!(:type => @type ) if @type
0
+ "<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
0
+ # @alias #to_html #to_s
0
+ def self.from_xml(xml)
0
+ parser = REXML::Parsers::BaseParser.new(xml)
0
+ when :end_doctype, :start_doctype
0
+ stack.push REXMLUtilityNode.new(event[1], event[2])
0
+ stack.last.add_node(temp)
0
+ stack.last.add_node(event[1]) unless event[1].strip.length == 0
0
+ def self.from_xml(xml)
0
+ ToHashParser.from_xml(xml)
0
\ No newline at end of file