Skip to content

Commit

Permalink
Backported pull request savonrb#52 to v0.4.6
Browse files Browse the repository at this point in the history
  • Loading branch information
johankok committed Apr 22, 2015
1 parent 4eb0353 commit 0727915
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
47 changes: 40 additions & 7 deletions lib/gyoku/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,28 @@ 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 = {})
iterate_with_xml array, attributes do |xml, item, attrs, index|
case item
when ::Hash then xml.tag!(key, attrs) { xml << Hash.to_xml(item, options) }
when NilClass then xml.tag!(key, "xsi:nil" => "true")
else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }

self_closing = options.delete(:self_closing)
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
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
end
Expand All @@ -22,14 +39,30 @@ 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|
yield xml, item, tag_attributes(attributes, index), 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)
Expand Down
7 changes: 7 additions & 0 deletions spec/gyoku/array_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
to_xml(array, "user").should == result
end

it "returns the XML for an Array of Hashes unwrapped" do
array = [{ :name => "adam" }, { :name => "eve" }]
result = "<user><name>adam</name><name>eve</name></user>"

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 = "<value>symbol</value><value>string</value><value>123</value>"
Expand Down

0 comments on commit 0727915

Please sign in to comment.