Advertisement
Guest User

Untitled

a guest
Jul 30th, 2018
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.70 KB | None | 0 0
  1. From 2b15322f7bd46381591bbaafb9f3a274bf362f34 Mon Sep 17 00:00:00 2001
  2. From: Peter Wagenet <peter.wagenet@gmail.com>
  3. Date: Thu, 12 Mar 2009 21:02:22 -0400
  4. Subject: [PATCH] Attribute Preserving Hash and XML
  5.  
  6. ---
  7. activeresource/lib/active_resource/formats.rb | 1 +
  8. .../formats/attribute_preserving_xml_format.rb | 11 ++++++
  9. activeresource/test/format_test.rb | 18 ++++++++++
  10. .../active_support/core_ext/hash/conversions.rb | 20 +++++++----
  11. activesupport/test/core_ext/hash_ext_test.rb | 34 +++++++++++++++++++-
  12. 5 files changed, 76 insertions(+), 8 deletions(-)
  13. create mode 100644 activeresource/lib/active_resource/formats/attribute_preserving_xml_format.rb
  14.  
  15. diff --git a/activeresource/lib/active_resource/formats.rb b/activeresource/lib/active_resource/formats.rb
  16. index 28864cf..1fb30fe 100644
  17. --- a/activeresource/lib/active_resource/formats.rb
  18. +++ b/activeresource/lib/active_resource/formats.rb
  19. @@ -11,4 +11,5 @@ module ActiveResource
  20. end
  21.  
  22. require 'active_resource/formats/xml_format'
  23. +require 'active_resource/formats/attribute_preserving_xml_format'
  24. require 'active_resource/formats/json_format'
  25. \ No newline at end of file
  26. diff --git a/activeresource/lib/active_resource/formats/attribute_preserving_xml_format.rb b/activeresource/lib/active_resource/formats/attribute_preserving_xml_format.rb
  27. new file mode 100644
  28. index 0000000..86851ed
  29. --- /dev/null
  30. +++ b/activeresource/lib/active_resource/formats/attribute_preserving_xml_format.rb
  31. @@ -0,0 +1,11 @@
  32. +module ActiveResource
  33. + module Formats
  34. + module AttributePreservingXmlFormat
  35. + extend XmlFormat
  36. +
  37. + def self.decode(xml)
  38. + from_xml_data(Hash.from_xml(xml, :preserve_attributes => true))
  39. + end
  40. + end
  41. + end
  42. +end
  43. \ No newline at end of file
  44. diff --git a/activeresource/test/format_test.rb b/activeresource/test/format_test.rb
  45. index c3733e1..eb5e17a 100644
  46. --- a/activeresource/test/format_test.rb
  47. +++ b/activeresource/test/format_test.rb
  48. @@ -100,6 +100,24 @@ class FormatTest < Test::Unit::TestCase
  49. end
  50. end
  51.  
  52. + def test_attribute_preserving_xml_format
  53. + xml = <<-EOT
  54. + <person>
  55. + <name type="first">David</name>
  56. + <email-address location="home">david@loudthinking.com</email-address>
  57. + </person>
  58. + EOT
  59. +
  60. + using_format(Person, :attribute_preserving_xml) do
  61. + ActiveResource::HttpMock.respond_to.get "/people/1.xml", {'Accept' => ActiveResource::Formats[:xml].mime_type}, xml
  62. + person = Person.find(1)
  63. + assert_equal "first", person.name.attributes["type"] # The type method is already in use (though deprecated)
  64. + assert_equal "David", person.name.content
  65. + assert_equal "home", person.email_address.location
  66. + assert_equal "david@loudthinking.com", person.email_address.content
  67. + end
  68. + end
  69. +
  70. private
  71. def using_format(klass, mime_type_reference)
  72. previous_format = klass.format
  73. diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
  74. index 991a5a6..7eb92c6 100644
  75. --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
  76. +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
  77. @@ -149,12 +149,15 @@ module ActiveSupport #:nodoc:
  78. end
  79.  
  80. module ClassMethods
  81. - def from_xml(xml)
  82. - typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
  83. + def from_xml(xml, options = {})
  84. + typecast_xml_value(unrename_keys(XmlMini.parse(xml)), options)
  85. end
  86.  
  87. private
  88. - def typecast_xml_value(value)
  89. + def typecast_xml_value(value, options = {})
  90. + options.symbolize_keys!
  91. + options.reverse_merge!(:preserve_attributes => false)
  92. +
  93. case value.class.to_s
  94. when 'Hash'
  95. if value['type'] == 'array'
  96. @@ -164,9 +167,9 @@ module ActiveSupport #:nodoc:
  97. else
  98. case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
  99. when "Array"
  100. - entries.collect { |v| typecast_xml_value(v) }
  101. + entries.collect { |v| typecast_xml_value(v, options) }
  102. when "Hash"
  103. - [typecast_xml_value(entries)]
  104. + [typecast_xml_value(entries, options)]
  105. else
  106. raise "can't typecast #{entries.inspect}"
  107. end
  108. @@ -179,6 +182,9 @@ module ActiveSupport #:nodoc:
  109. else
  110. XML_PARSING[value["type"]].call(content)
  111. end
  112. + elsif options[:preserve_attributes] && value.keys.size > 1
  113. + value["content"] = value.delete("__content__")
  114. + value
  115. else
  116. content
  117. end
  118. @@ -194,7 +200,7 @@ module ActiveSupport #:nodoc:
  119. nil
  120. else
  121. xml_value = value.inject({}) do |h,(k,v)|
  122. - h[k] = typecast_xml_value(v)
  123. + h[k] = typecast_xml_value(v, options)
  124. h
  125. end
  126.  
  127. @@ -203,7 +209,7 @@ module ActiveSupport #:nodoc:
  128. xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
  129. end
  130. when 'Array'
  131. - value.map! { |i| typecast_xml_value(i) }
  132. + value.map! { |i| typecast_xml_value(i, options) }
  133. case value.length
  134. when 0 then nil
  135. when 1 then value.first
  136. diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
  137. index b63ab30..2c4adca 100644
  138. --- a/activesupport/test/core_ext/hash_ext_test.rb
  139. +++ b/activesupport/test/core_ext/hash_ext_test.rb
  140. @@ -490,7 +490,7 @@ class HashToXmlTest < Test::Unit::TestCase
  141. assert xml.include?(%(<addresses type="array"><address><streets type="array"><street><name>))
  142. end
  143.  
  144. - def test_single_record_from_xml
  145. + def test_single_record_from_xml_with_and_without_preserving_attributes
  146. topic_xml = <<-EOT
  147. <topic>
  148. <title>The First Topic</title>
  149. @@ -527,8 +527,40 @@ class HashToXmlTest < Test::Unit::TestCase
  150. :resident => :yes
  151. }.stringify_keys
  152.  
  153. + [false, true].each{|preserve| assert_equal expected_topic_hash, Hash.from_xml(topic_xml, :preserve_attributes => preserve)["topic"] }
  154. + end
  155. +
  156. + def test_single_record_from_xml_with_attributes_and_without_preservation
  157. + topic_xml = <<-EOT
  158. + <topic>
  159. + <title type="main">The First Topic</title>
  160. + <author-email-address location="home">david@loudthinking.com</author-email-address>
  161. + </topic>
  162. + EOT
  163. +
  164. + expected_topic_hash = {
  165. + :title => "The First Topic",
  166. + :author_email_address => "david@loudthinking.com"
  167. + }.stringify_keys
  168. +
  169. assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["topic"]
  170. end
  171. +
  172. + def test_single_record_from_xml_with_attributes_and_with_preservation
  173. + topic_xml = <<-EOT
  174. + <topic>
  175. + <title type="main">The First Topic</title>
  176. + <author-email-address location="home">david@loudthinking.com</author-email-address>
  177. + </topic>
  178. + EOT
  179. +
  180. + expected_topic_hash = {
  181. + :title => { "type" => "main", "content" => "The First Topic" },
  182. + :author_email_address => { "location" => "home", "content" => "david@loudthinking.com" }
  183. + }.stringify_keys
  184. +
  185. + assert_equal expected_topic_hash, Hash.from_xml(topic_xml, :preserve_attributes => true)["topic"]
  186. + end
  187.  
  188. def test_single_record_from_xml_with_nil_values
  189. topic_xml = <<-EOT
  190. --
  191. 1.5.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement