diff --git a/lib/gyoku/array.rb b/lib/gyoku/array.rb index db8e695..46dd739 100644 --- a/lib/gyoku/array.rb +++ b/lib/gyoku/array.rb @@ -11,17 +11,27 @@ class Array # Translates a given +array+ to XML. Accepts the XML +key+ to add the elements to, # whether to +escape_xml+ and an optional Hash of +attributes+. def self.to_xml(array, key, escape_xml = true, attributes = {}, options = {}) + self_closing = options.delete(:self_closing) - iterate_with_xml array, attributes do |xml, item, attrs, index| + unwrap = options[:unwrap] || false + + iterate_with_xml array, key, attributes, options do |xml, item, attrs, index| if self_closing xml.tag!(key, attrs) - else case item - when ::Hash then xml.tag!(key, attrs) { xml << Hash.to_xml(item, options) } - when ::Array then xml.tag!(key, attrs) { xml << Array.to_xml(item, NESTED_ELEMENT_NAME) } - when NilClass then xml.tag!(key, "xsi:nil" => "true") - else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) } + when ::Hash then + if unwrap + xml << Hash.to_xml(item, options) + else + xml.tag!(key, attrs) { xml << Hash.to_xml(item, options) } + end + when ::Array then + xml.tag!(key, attrs) { xml << Array.to_xml(item, NESTED_ELEMENT_NAME) } + when NilClass then + xml.tag!(key, "xsi:nil" => "true") + else + xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) } end end end @@ -31,8 +41,24 @@ def self.to_xml(array, key, escape_xml = true, attributes = {}, options = {}) # Iterates over a given +array+ with a Hash of +attributes+ and yields a builder +xml+ # instance, the current +item+, any XML +attributes+ and the current +index+. - def self.iterate_with_xml(array, attributes) + def self.iterate_with_xml(array, key, attributes, options, &block) + xml = Builder::XmlMarkup.new + unwrap = options[:unwrap] || false + + if (unwrap) + xml.tag!(key) { iterate_array(xml, array, attributes, &block) } + else + iterate_array(xml, array, attributes, &block) + end + + xml.target! + end + + + # Iterates over a given +array+ with a Hash of +attributes+ and yields a builder +xml+ + # instance, the current +item+, any XML +attributes+ and the current +index+. + def self.iterate_array(xml, array, attributes, &block) array.each_with_index do |item, index| if item.respond_to?(:keys) attrs = item.reduce({}) do |st, v| @@ -45,9 +71,9 @@ def self.iterate_with_xml(array, attributes) end yield xml, item, tag_attributes(attributes, index).merge(attrs), index end - xml.target! end + # Takes a Hash of +attributes+ and the +index+ for which to return attributes # for duplicate tags. def self.tag_attributes(attributes, index) diff --git a/spec/gyoku/array_spec.rb b/spec/gyoku/array_spec.rb index 26b5b31..5667274 100644 --- a/spec/gyoku/array_spec.rb +++ b/spec/gyoku/array_spec.rb @@ -10,6 +10,13 @@ expect(to_xml(array, "user")).to eq(result) end + it "returns the XML for an Array of Hashes unwrapped" do + array = [{ :name => "adam" }, { :name => "eve" }] + result = "adameve" + + expect(to_xml(array, "user", true, {}, :unwrap => true)).to eq(result) + end + it "returns the XML for an Array of different Objects" do array = [:symbol, "string", 123] result = "symbolstring123"