aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2009-03-09 17:27:39 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2009-03-10 11:56:19 -0700
commit694998ee4fb8d257ba78424cab630846327a0889 (patch)
tree42639216568af741a4d484c486336131c1c7d6d5 /activesupport/lib
parentd4091d3bc79731f55491cfb51c604a66502c944f (diff)
downloadrails-694998ee4fb8d257ba78424cab630846327a0889.tar.gz
rails-694998ee4fb8d257ba78424cab630846327a0889.tar.bz2
rails-694998ee4fb8d257ba78424cab630846327a0889.zip
Nokogiri backend for XmlMini
[#2190 state:committed] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/xml_mini.rb4
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb67
2 files changed, 71 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index 99158e4ff7..0513c0d4d0 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -8,6 +8,10 @@ module ActiveSupport
extend self
delegate :parse, :to => :@backend
+ class << self
+ attr_reader :backend
+ end
+
def backend=(name)
require "active_support/xml_mini/#{name.to_s.downcase}.rb"
@backend = ActiveSupport.const_get("XmlMini_#{name}")
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
new file mode 100644
index 0000000000..bfafa29dd5
--- /dev/null
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -0,0 +1,67 @@
+# = XML Mini Nokogiri implementation
+module ActiveSupport
+ module XmlMini_Nokogiri #:nodoc:
+ extend self
+
+ # Parse an XML Document string into a simple hash using libxml / nokogiri.
+ # string::
+ # XML Document string to parse
+ def parse(string)
+ return {} if string.blank?
+ doc = Nokogiri::XML(string).to_hash
+ end
+
+ module Conversions
+ module Document
+ def to_hash
+ root.to_hash
+ end
+ end
+
+ module Node
+ CONTENT_ROOT = '__content__'
+
+ # Convert XML document to hash
+ #
+ # hash::
+ # Hash to merge the converted element into.
+ def to_hash(hash = {})
+ hash[name] ||= attributes_as_hash
+
+ walker = lambda { |child, memo, callback|
+ next if child.blank?
+
+ if child.text?
+ (memo[CONTENT_ROOT] ||= '') << child.content
+ next
+ end
+
+ name = child.name
+
+ if memo[name]
+ memo[name] = [memo[name]].flatten
+ memo[name] << child.attributes_as_hash
+ else
+ memo[name] = child.attributes_as_hash
+ end
+
+ # Recusively walk children
+ child.children.each { |c| callback.call(c, memo[name], callback) }
+ }
+
+ children.each { |c| walker.call(c, hash[name], walker) }
+ hash
+ end
+
+ def attributes_as_hash
+ Hash[*(attribute_nodes.map { |node|
+ [node.node_name, node.value]
+ }.flatten)]
+ end
+ end
+ end
+
+ Nokogiri::XML::Document.send(:include, Conversions::Document)
+ Nokogiri::XML::Node.send(:include, Conversions::Node)
+ end
+end