aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/xml_mini.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2009-03-09 19:00:21 +0100
committerDavid Heinemeier Hansson <david@loudthinking.com>2009-03-09 19:00:21 +0100
commita995a738ca10f9bef023689df70d26aad8931b9a (patch)
treeecf40bca380c8ed75880293435baf7ab42934d65 /activesupport/lib/active_support/xml_mini.rb
parent90dba00822acd1e01f7a39625668ee74ffe5f061 (diff)
downloadrails-a995a738ca10f9bef023689df70d26aad8931b9a.tar.gz
rails-a995a738ca10f9bef023689df70d26aad8931b9a.tar.bz2
rails-a995a738ca10f9bef023689df70d26aad8931b9a.zip
Revert "XmlMini supports different backend parsers, starting with libxml"
Spews a ton undefined method `default_keep_blanks=' for XML:Module errors. This reverts commit 822c41d69d9228c9912d29ac45155d3a16bb5c50.
Diffstat (limited to 'activesupport/lib/active_support/xml_mini.rb')
-rw-r--r--activesupport/lib/active_support/xml_mini.rb110
1 files changed, 101 insertions, 9 deletions
diff --git a/activesupport/lib/active_support/xml_mini.rb b/activesupport/lib/active_support/xml_mini.rb
index 8ae8e7cefe..ce3f50620d 100644
--- a/activesupport/lib/active_support/xml_mini.rb
+++ b/activesupport/lib/active_support/xml_mini.rb
@@ -1,21 +1,113 @@
# = XmlMini
+# This is a derivitive work of XmlSimple 1.0.11
+# Author:: Joseph Holsten <joseph@josephholsten.com>
+# Copyright:: Copyright (c) 2008 Joseph Holsten
+# Copyright:: Copyright (c) 2003-2006 Maik Schmidt <contact@maik-schmidt.de>
+# License:: Distributes under the same terms as Ruby.
module ActiveSupport
module XmlMini
extend self
CONTENT_KEY = '__content__'.freeze
- # Hook the correct parser into XmlMini
- def hook_parser
- begin
- require 'xml/libxml' unless defined? LibXML
- require "active_support/xml_mini/libxml.rb"
- rescue MissingSourceFile => e
- require "active_support/xml_mini/rexml.rb"
- end
+ # Parse an XML Document string into a simple hash
+ #
+ # Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
+ # and uses the defaults from ActiveSupport
+ #
+ # string::
+ # XML Document string to parse
+ def parse(string)
+ require 'rexml/document' unless defined?(REXML::Document)
+ doc = REXML::Document.new(string)
+ merge_element!({}, doc.root)
end
- hook_parser
+ private
+ # Convert an XML element and merge into the hash
+ #
+ # hash::
+ # Hash to merge the converted element into.
+ # element::
+ # XML element to merge into hash
+ def merge_element!(hash, element)
+ merge!(hash, element.name, collapse(element))
+ end
+
+ # Actually converts an XML document element into a data structure.
+ #
+ # element::
+ # The document element to be collapsed.
+ def collapse(element)
+ hash = get_attributes(element)
+
+ if element.has_elements?
+ element.each_element {|child| merge_element!(hash, child) }
+ merge_texts!(hash, element) unless empty_content?(element)
+ hash
+ else
+ merge_texts!(hash, element)
+ end
+ end
+
+ # Merge all the texts of an element into the hash
+ #
+ # hash::
+ # Hash to add the converted emement to.
+ # element::
+ # XML element whose texts are to me merged into the hash
+ def merge_texts!(hash, element)
+ unless element.has_text?
+ hash
+ else
+ # must use value to prevent double-escaping
+ merge!(hash, CONTENT_KEY, element.texts.sum(&:value))
+ end
+ end
+
+ # Adds a new key/value pair to an existing Hash. If the key to be added
+ # already exists and the existing value associated with key is not
+ # an Array, it will be wrapped in an Array. Then the new value is
+ # appended to that Array.
+ #
+ # hash::
+ # Hash to add key/value pair to.
+ # key::
+ # Key to be added.
+ # value::
+ # Value to be associated with key.
+ def merge!(hash, key, value)
+ if hash.has_key?(key)
+ if hash[key].instance_of?(Array)
+ hash[key] << value
+ else
+ hash[key] = [hash[key], value]
+ end
+ elsif value.instance_of?(Array)
+ hash[key] = [value]
+ else
+ hash[key] = value
+ end
+ hash
+ end
+ # Converts the attributes array of an XML element into a hash.
+ # Returns an empty Hash if node has no attributes.
+ #
+ # element::
+ # XML element to extract attributes from.
+ def get_attributes(element)
+ attributes = {}
+ element.attributes.each { |n,v| attributes[n] = v }
+ attributes
+ end
+
+ # Determines if a document element has text content
+ #
+ # element::
+ # XML element to be checked.
+ def empty_content?(element)
+ element.texts.join.blank?
+ end
end
end \ No newline at end of file