diff --git a/lib/gyoku/array.rb b/lib/gyoku/array.rb
index 8be6cc8..4b1272d 100644
--- a/lib/gyoku/array.rb
+++ b/lib/gyoku/array.rb
@@ -9,8 +9,11 @@ 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)
@@ -18,7 +21,7 @@ def self.to_xml(array, key, escape_xml = true, attributes = {}, options = {})
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
@@ -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|
@@ -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
diff --git a/lib/gyoku/hash.rb b/lib/gyoku/hash.rb
index 6ff2509..0678baf 100644
--- a/lib/gyoku/hash.rb
+++ b/lib/gyoku/hash.rb
@@ -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
@@ -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
@@ -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
@@ -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
diff --git a/spec/gyoku/array_spec.rb b/spec/gyoku/array_spec.rb
index 1921dc0..431352a 100644
--- a/spec/gyoku/array_spec.rb
+++ b/spec/gyoku/array_spec.rb
@@ -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 = "\n adam\n\n\n eve\n\n"
+ to_xml(array, "user", true, {}, { :builder => {:indent => 2} }).should == result
+ end
end
def to_xml(*args)
diff --git a/spec/gyoku/hash_spec.rb b/spec/gyoku/hash_spec.rb
index c1f84cc..fe2afb7 100644
--- a/spec/gyoku/hash_spec.rb
+++ b/spec/gyoku/hash_spec.rb
@@ -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 = "\n user\n\n"
+ to_xml(hash, { :builder => {:indent => 2} }).should == result
+ end
end
it "doesn't modify original hash parameter by deleting its attribute keys" do