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