Skip to content

Commit

Permalink
Merge d55cb6a into 93264ee
Browse files Browse the repository at this point in the history
  • Loading branch information
davispuh committed Sep 28, 2013
2 parents 93264ee + d55cb6a commit 64d2bc3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
13 changes: 9 additions & 4 deletions lib/gyoku/array.rb
Expand Up @@ -9,16 +9,19 @@ 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 = {})
options[:builder] ||= {}
options[:builder][:indent] ||= 0
options[:builder][:margin] ||= 0
self_closing = options.delete(:self_closing)
iterate_with_xml array, attributes do |xml, item, attrs, index|
iterate_with_xml array, 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 NilClass then xml.tag!(key, "xsi:nil" => "true")
else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }
else xml.tag!(key, attrs, false, XMLValue.create(item, escape_xml))
end
end
end
Expand All @@ -28,8 +31,9 @@ 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)
xml = Builder::XmlMarkup.new
def self.iterate_with_xml(array, attributes, options = {})
xml = Builder::XmlMarkup.new(options[:builder] || {})
options[:builder][:margin] += 1
array.each_with_index do |item, index|
if item.respond_to?(:keys)
attrs = item.reduce({}) do |st, v|
Expand All @@ -42,6 +46,7 @@ def self.iterate_with_xml(array, attributes)
end
yield xml, item, tag_attributes(attributes, index).merge(attrs), index
end
options[:builder][:margin] -= 1
xml.target!
end

Expand Down
13 changes: 9 additions & 4 deletions lib/gyoku/hash.rb
Expand Up @@ -9,7 +9,10 @@ class Hash

# Translates a given +hash+ with +options+ to XML.
def self.to_xml(hash, options = {})
iterate_with_xml hash do |xml, key, value, attributes|
options[:builder] ||= {}
options[:builder][:indent] ||= 0
options[:builder][:margin] ||= 0
iterate_with_xml hash, options do |xml, key, value, attributes|
self_closing = key.to_s[-1, 1] == "/"
escape_xml = key.to_s[-1, 1] != "!"
xml_key = XMLKey.create key, options
Expand All @@ -20,7 +23,7 @@ def self.to_xml(hash, options = {})
when ::Hash === value then xml.tag!(xml_key, attributes) { xml << Hash.to_xml(value, options) }
when self_closing then xml.tag!(xml_key, attributes)
when NilClass === value then xml.tag!(xml_key, "xsi:nil" => "true")
else xml.tag!(xml_key, attributes) { xml << XMLValue.create(value, escape_xml) }
else xml.tag!(xml_key, attributes, false, XMLValue.create(value, escape_xml))
end
end
end
Expand All @@ -33,11 +36,12 @@ def self.to_xml(hash, options = {})
# Keys beginning with "@" are treated as explicit attributes for their container.
# You can use both :attributes! and "@" keys to specify attributes.
# In the event of a conflict, the "@" key takes precedence.
def self.iterate_with_xml(hash)
xml = Builder::XmlMarkup.new
def self.iterate_with_xml(hash, options = {})
xml = Builder::XmlMarkup.new(options[:builder] || {})
attributes = hash[:attributes!] || {}
hash_without_attributes = hash.reject { |key, value| key == :attributes! }

options[:builder][:margin] += 1
order(hash_without_attributes).each do |key|
node_attr = attributes[key] || {}
# node_attr must be kind of ActiveSupport::HashWithIndifferentAccess
Expand All @@ -57,6 +61,7 @@ def self.iterate_with_xml(hash)

yield xml, key, node_value, node_attr
end
options[:builder][:margin] -= 1

xml.target!
end
Expand Down
6 changes: 6 additions & 0 deletions spec/gyoku/array_spec.rb
Expand Up @@ -51,6 +51,12 @@

to_xml(array, "value", :escape_xml, :id => [1, 2]).should == result
end

it "should pass options to XML Builder" do
array = [{ :name => "adam" }, { :name => "eve" }]
result = "<user>\n <name>adam</name>\n</user>\n<user>\n <name>eve</name>\n</user>\n"
to_xml(array, "user", true, {}, { :builder => {:indent => 2} }).should == result
end
end

def to_xml(*args)
Expand Down
6 changes: 6 additions & 0 deletions spec/gyoku/hash_spec.rb
Expand Up @@ -298,6 +298,12 @@ def singleton.to_datetime
:attributes! => { :countries => { :array => true } }
}
end

it "should pass options to XML Builder" do
hash = {:some => { :new => "user" }}
result = "<some>\n <new>user</new>\n</some>\n"
to_xml(hash, { :builder => {:indent => 2} }).should == result
end
end

it "doesn't modify original hash parameter by deleting its attribute keys" do
Expand Down

0 comments on commit 64d2bc3

Please sign in to comment.