diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 94c496c54b031..1ecee37c46fb2 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Fix that empty collections should be treated as empty arrays regardless of whitespace for Hash#from_xml #10255 [adamj] + * Time#time_with_datetime_fallback, Time#to_datetime, Date#to_datetime and String#to_datetime honor Ruby's default calendar reform setting. #10201 [Geoff Buesing] * Change Time and DateTime #end_of_month to return last second of month instead of beginning of last day of month. Closes #10200 [Geoff Buesing] diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index bbe35c25e45d6..e196c5d7b943b 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -174,20 +174,9 @@ def from_xml(xml) def typecast_xml_value(value) case value.class.to_s when 'Hash' - if value.has_key?("__content__") - content = value["__content__"] - if parser = XML_PARSING[value["type"]] - if parser.arity == 2 - XML_PARSING[value["type"]].call(content, value) - else - XML_PARSING[value["type"]].call(content) - end - else - content - end - elsif value['type'] == 'array' + if value['type'] == 'array' child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway - if entries.nil? + if entries.nil? || (c = value['__content__'] && c.blank?) [] else case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a? @@ -199,6 +188,17 @@ def typecast_xml_value(value) raise "can't typecast #{entries.inspect}" end end + elsif value.has_key?("__content__") + content = value["__content__"] + if parser = XML_PARSING[value["type"]] + if parser.arity == 2 + XML_PARSING[value["type"]].call(content, value) + else + XML_PARSING[value["type"]].call(content) + end + else + content + end elsif value['type'] == 'string' && value['nil'] != 'true' "" # blank or nil parsed values are represented by nil diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index fe728919cdbc9..2be9ab8999bf7 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -549,6 +549,17 @@ def test_empty_array_from_xml assert_equal expected_blog_hash, Hash.from_xml(blog_xml) end + def test_empty_array_with_whitespace_from_xml + blog_xml = <<-XML + + + + + XML + expected_blog_hash = {"blog" => {"posts" => []}} + assert_equal expected_blog_hash, Hash.from_xml(blog_xml) + end + def test_array_with_one_entry_from_xml blog_xml = <<-XML