From 1f13c7f792f64fb7b30fa06e835e2ba027ceb0d2 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Thu, 22 Apr 2010 10:58:18 -0400 Subject: [PATCH] to_xml should behave similar to to_json for array and hash [state: proof of concept] --- .../active_support/core_ext/hash/conversions.rb | 38 ++++++++++++++++++- 1 files changed, 36 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index a43763f..6c174e9 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -37,7 +37,9 @@ module ActiveSupport #:nodoc: "Date" => "date", "DateTime" => "datetime", "Time" => "datetime", - "ActiveSupport::TimeWithZone" => "datetime" + "ActiveSupport::TimeWithZone" => "datetime", + "Hash" => "hash", + "Array" => "array" } unless defined?(XML_TYPE_NAMES) XML_FORMATTING = { @@ -45,9 +47,13 @@ module ActiveSupport #:nodoc: "date" => Proc.new { |date| date.to_s(:db) }, "datetime" => Proc.new { |time| time.xmlschema }, "binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) }, - "yaml" => Proc.new { |yaml| yaml.to_yaml } + "yaml" => Proc.new { |yaml| yaml.to_yaml }, + "hash" => Proc.new { |hash| hash2xml(hash) }, + "array" => Proc.new { |array| array2xml(array) } } unless defined?(XML_FORMATTING) + + # TODO: use Time.xmlschema instead of Time.parse; # use regexp instead of Date.parse unless defined?(XML_PARSING) @@ -81,6 +87,34 @@ module ActiveSupport #:nodoc: klass.extend(ClassMethods) end + def self.array2xml(array) + values = array.inject([]) do |sum, elem| + sum << "'" + xml_value(elem) + "'" + end + "[#{values.join(',')}]" + end + + def self.hash2xml(input) + values = input.inject([]) do |sum, (key, val)| + key_xmlified = xml_value(key) + val_xmlified = xml_value(val) + sum << "'" + key_xmlified + "'" + ' : ' + "'" + val_xmlified + "'" + end + "{#{values.join(',')}}" + end + + def self.xml_value(input) + if input.class.name == 'String' + input + else + type = XML_TYPE_NAMES[input.class.name] + formatter = XML_FORMATTING[type] + value = formatter ? (input ? formatter.call(input) : nil) : input + value.blank? ? '' : value + end + end + + # Converts a hash into a string suitable for use as a URL query string. An optional namespace can be # passed to enclose the param names (see example below). # -- 1.6.5.2