lib/apricoteatsgorilla.rb in smacks-apricoteatsgorilla-0.3.61 vs lib/apricoteatsgorilla.rb in smacks-apricoteatsgorilla-0.3.91
- old
+ new
@@ -45,10 +45,25 @@
class << self # Class methods
# Flag to enable optional sorting of Hash keys.
attr_accessor :sort_keys
+ # Flag to disable conversion of tag names to lowerCamelCase.
+ attr_accessor :disable_tag_names_to_lower_camel_case
+
+ # Flag to disable conversion of Hash keys to snake_case.
+ attr_accessor :disable_hash_keys_to_snake_case
+
+ # Flag to disable conversion of Hash keys to Symbols.
+ attr_accessor :disable_hash_keys_to_symbol
+
+ # Array of XML nodes to add a namespace to.
+ attr_accessor :nodes_to_namespace
+
+ # The namespace for nodes in :nodes_to_namespace.
+ attr_accessor :node_namespace
+
# Shortcut method for translating between XML Strings and Ruby Hashes.
# Delegates to xml_to_hash in case +source+ is of type String or delegates
# to hash_to_xml in case +source+ is of type Hash. Returns nil otherwise.
#
# ==== Parameters
@@ -64,10 +79,16 @@
else
nil
end
end
+ # Yields this class object in case a +block+ was given. Nice way for setting
+ # multiple options at once.
+ def setup
+ yield self if block_given?
+ end
+
# Converts a given +xml+ String into a Ruby Hash. Starts parsing at root
# node by default. The optional +root_node+ parameter can be used to specify
# a custom root node to start parsing at via XPath (Hpricot search).
# The root node itself won't be included in the Hash.
#
@@ -149,10 +170,22 @@
yield if block_given?
end
end
end
+ # Converts a given +string+ from CamelCase/lowerCamelCase to snake_case.
+ def to_snake_case(string)
+ string = string.gsub(/[A-Z]+/, '\1_\0').downcase
+ string = string[1, string.length-1] if string[0, 1] == "_"
+ string
+ end
+
+ # Converts a given +string+ from snake_case to lowerCamelCase.
+ def to_lower_camel_case(string)
+ string.to_s.gsub(/_(.)/) { $1.upcase }
+ end
+
private
# Actual implementation for xml_to_hash. Takes and iterates through a given
# Hpricot +element+ and returns a Ruby Hash equal to the given content.
#
@@ -169,11 +202,13 @@
key, value = child.name, booleanize(child.children.first.to_html)
else
key, value = child.name, xml_node_to_hash(child)
end
- key = to_snake_case(remove_namespace(key)).intern
+ key = remove_namespace(key)
+ key = to_snake_case(key) unless disable_hash_keys_to_snake_case
+ key = key.intern unless disable_hash_keys_to_symbol
current = this_node[key]
case current
when Array
this_node[key] << value
when nil
@@ -192,20 +227,20 @@
#
# * +name+ - A Hash key to translate into an XML String.
# * +item+ - A Hash value to translate into an XML String.
def nested_data_to_xml(name, item)
case item
- when String
- tag(name) { item }
+ when String, Symbol
+ tag(name) { item.to_s }
when Array
item.map { |subitem| nested_data_to_xml(name, subitem) }.join
when Hash
tag(name) do
opt_order(item).map { |tag, value|
case value
- when String
- tag(tag) { value }
+ when String, Symbol
+ tag(tag) { value.to_s }
when Array
value.map { |subitem| nested_data_to_xml(tag, subitem) }.join
when Hash
nested_data_to_xml(tag, value)
end
@@ -220,32 +255,31 @@
# ==== Parameters
#
# * +name+ - The name of the XML tag.
# * +attributes+ - Optional. Hash of attributes for the XML tag.
def tag(name, attributes = {})
+ name = to_lower_camel_case(name) unless disable_tag_names_to_lower_camel_case
+ if nodes_to_namespace.kind_of? Array
+ name = "#{node_namespace}:#{name}" if node_namespace && nodes_to_namespace.include?(name)
+ end
return "<#{name} />" unless block_given?
attr = opt_order(attributes).map { |k, v| %Q( xmlns:#{k}="#{v}") }.to_s
body = (yield && !yield.empty?) ? yield : ""
"<#{name}#{attr}>" << body << "</#{name}>"
end
# Removes line breaks and whitespace between tags from a given +xml+ String.
def clean_xml(xml)
- xml = xml.gsub(/\n+/, "")
- xml.gsub(/(>)\s*(<)/, '\1\2')
+ xml.gsub!(/\n+/, "")
+ xml.gsub!(/(>)\s*(<)/, '\1\2')
+ xml
end
# Removes the namespace from a given XML +tag+.
def remove_namespace(tag)
- tag.sub(/.+:(.+)/, '\1')
- end
-
- # Converts a given +string+ from CamelCase/lowerCamelCase to snake_case.
- def to_snake_case(string)
- string = string.gsub(/[A-Z]+/, '\1_\0').downcase
- string = string[1, string.length-1] if string[0, 1] == "_"
- string
+ tag.sub!(/.+:(.+)/, '\1')
+ tag
end
# Checks to see if a given +string+ matches "true" or "false" and converts
# these values to actual Boolean objects. Returns the original string in
# case it does not match "true" or "false".
\ No newline at end of file