mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Extract XmlMini. Namespace FileLike extension.
This commit is contained in:
parent
d1213fa402
commit
b7fef2610b
2 changed files with 125 additions and 128 deletions
|
@ -1,137 +1,23 @@
|
|||
require 'date'
|
||||
|
||||
# = 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.
|
||||
class XmlMini
|
||||
require 'rexml/document'
|
||||
include REXML
|
||||
|
||||
CONTENT_KEY = '__content__'
|
||||
|
||||
# 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 self.parse(string)
|
||||
doc = REXML::Document.new(string)
|
||||
merge_element!({}, doc.root)
|
||||
end
|
||||
|
||||
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 self.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 self.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)
|
||||
else
|
||||
return merge_texts!(hash, element)
|
||||
end
|
||||
hash
|
||||
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 self.merge_texts!(hash, element)
|
||||
unless element.has_text?
|
||||
hash
|
||||
else
|
||||
# must use value to prevent double-escaping
|
||||
text_values = element.texts.map {|t| t.value }
|
||||
merge!(hash, CONTENT_KEY, text_values.join)
|
||||
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 self.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 self.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 self.empty_content?(element)
|
||||
element.texts.join.strip.empty?
|
||||
end
|
||||
end
|
||||
|
||||
# This module exists to decorate files deserialized using Hash.from_xml with
|
||||
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
||||
module FileLike #:nodoc:
|
||||
attr_writer :original_filename, :content_type
|
||||
|
||||
def original_filename
|
||||
@original_filename || 'untitled'
|
||||
end
|
||||
|
||||
def content_type
|
||||
@content_type || 'application/octet-stream'
|
||||
end
|
||||
end
|
||||
require 'active_support/xml_mini'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Hash #:nodoc:
|
||||
module Conversions
|
||||
# This module exists to decorate files deserialized using Hash.from_xml with
|
||||
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
||||
module FileLike #:nodoc:
|
||||
attr_writer :original_filename, :content_type
|
||||
|
||||
def original_filename
|
||||
@original_filename || 'untitled'
|
||||
end
|
||||
|
||||
def content_type
|
||||
@content_type || 'application/octet-stream'
|
||||
end
|
||||
end
|
||||
|
||||
XML_TYPE_NAMES = {
|
||||
"Symbol" => "symbol",
|
||||
|
|
111
activesupport/lib/active_support/xml_mini.rb
Normal file
111
activesupport/lib/active_support/xml_mini.rb
Normal file
|
@ -0,0 +1,111 @@
|
|||
# = 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 XmlMini
|
||||
extend self
|
||||
|
||||
CONTENT_KEY = '__content__'.freeze
|
||||
|
||||
# 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'
|
||||
doc = REXML::Document.new(string)
|
||||
merge_element!({}, doc.root)
|
||||
end
|
||||
|
||||
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
|
Loading…
Reference in a new issue