Last active
October 7, 2015 07:00
-
-
Save larrylv/a67e11a7e9ec6b0b7697 to your computer and use it in GitHub Desktop.
Convert Hash to XML
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
require "builder" | |
class Converter | |
XML_DECLARATION = %q(<?xml version="1.0" encoding="UTF-8"?>) | |
def self.to_xml(h) | |
raise unless h.kind_of? Hash | |
h.inject("") { |s, (k, v)| s += node_with(k, v) } | |
end | |
private | |
def self.node_with(k, v) | |
case v | |
when Hash then node_with_hash(k, v) | |
when Array then node_with_array(k, v) | |
else node_with_string(k, v) | |
end | |
end | |
def self.node_with_hash(k, v) | |
node_with_string(k, to_xml(v)) | |
end | |
def self.node_with_array(k, v) | |
v.map { |elt| node_with(k, elt) }.join("") | |
end | |
def self.node_with_string(k, v) | |
"<#{k}>#{v}</#{k}>" | |
end | |
end | |
class TestConverter < Minitest::Test | |
def setup | |
@profile = {:name => "Larry", :twitter => "@larrylv", :github => "@larrylv"} | |
end | |
def test_string_values | |
expected_value = <<-XML | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
XML | |
assert_equal format_xml_string(expected_value), Converter.to_xml(@profile) | |
end | |
def test_hash_values | |
@profile[:blog] = { | |
:tech => "blog.larrylv.com", | |
:journey => "journey.larrylv.com", | |
:homepage => "larrylv.com" | |
} | |
expected_value = <<-XML | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blog> | |
<tech>blog.larrylv.com</tech> | |
<journey>journey.larrylv.com</journey> | |
<homepage>larrylv.com</homepage> | |
</blog> | |
XML | |
assert_equal format_xml_string(expected_value), Converter.to_xml(@profile) | |
end | |
def test_array_values | |
@profile[:blogs] = {:blog => %w(blog.larrylv.com journey.larrylv.com larrylv.com)} | |
expected_value = <<-XML | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blogs> | |
<blog>blog.larrylv.com</blog> | |
<blog>journey.larrylv.com</blog> | |
<blog>larrylv.com</blog> | |
</blogs> | |
XML | |
assert_equal format_xml_string(expected_value), Converter.to_xml(@profile) | |
end | |
private | |
def format_xml_string(s) | |
s.split("\n").map(&:strip).join("") | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
require "active_support/core_ext/string/strip" | |
require "builder" | |
class Converter | |
def self.hash_to_xml(hash, options = {}) | |
raise unless hash.kind_of? Hash | |
if options[:builder] | |
builder = options[:builder] | |
else | |
builder = Builder::XmlMarkup.new(indent: 2) | |
builder.instruct! | |
end | |
hash.each do |k, v| | |
node_with(builder, k, v) | |
end | |
builder.target! | |
end | |
def self.array_to_xml(array, key, attributes = {}, options = {}) | |
raise unless array.kind_of? Array | |
builder = options[:builder] || Builder::XmlMarkup.new(indent: 2) | |
array.each do |elt| | |
node_with(builder, key, elt, attributes) | |
end | |
builder.target! | |
end | |
private | |
def self.node_with(builder, k, v, attributes = {}) | |
case v | |
when Hash | |
if v.keys.include? :content! | |
attributes = v.inject({}) do |attrs, (kk, vv)| | |
next attrs unless kk.to_s =~ /^@/ | |
attrs[kk.to_s[1..-1]] = vv | |
attrs | |
end | |
node_with(builder, k, v[:content!], attributes) | |
else | |
builder.tag!(k, attributes) { hash_to_xml(v, :builder => builder) } | |
end | |
when Array | |
array_to_xml(v, k, attributes, :builder => builder) | |
else | |
builder.tag!(k, v, attributes) | |
end | |
end | |
end | |
class TestConverter < Minitest::Test | |
def setup | |
@profile = {:name => "Larry", :twitter => "@larrylv", :github => "@larrylv"} | |
end | |
def test_string_values | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_hash_values | |
@profile[:blog] = { | |
:tech => "blog.larrylv.com", | |
:journey => "journey.larrylv.com", | |
:homepage => "larrylv.com" | |
} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blog> | |
<tech>blog.larrylv.com</tech> | |
<journey>journey.larrylv.com</journey> | |
<homepage>larrylv.com</homepage> | |
</blog> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_array_values | |
@profile[:blogs] = {:blog => %w(blog.larrylv.com journey.larrylv.com larrylv.com)} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blogs> | |
<blog>blog.larrylv.com</blog> | |
<blog>journey.larrylv.com</blog> | |
<blog>larrylv.com</blog> | |
</blogs> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_attributes | |
@profile[:blog] = { | |
:content! => { | |
:tech => "blog.larrylv.com", | |
:journey => "journey.larrylv.com", | |
:homepage => "larrylv.com" | |
}, | |
:@count => 3, | |
:@readers => "few" | |
} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blog count="3" readers="few"> | |
<tech>blog.larrylv.com</tech> | |
<journey>journey.larrylv.com</journey> | |
<homepage>larrylv.com</homepage> | |
</blog> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_array_with_attributes | |
@profile[:blogs] = { | |
:blog => { | |
:content! => %w(blog.larrylv.com journey.larrylv.com larrylv.com), | |
:@count => 3, | |
:@readers => "few" | |
} | |
} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blogs> | |
<blog count="3" readers="few">blog.larrylv.com</blog> | |
<blog count="3" readers="few">journey.larrylv.com</blog> | |
<blog count="3" readers="few">larrylv.com</blog> | |
</blogs> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
require "active_support/core_ext/string/strip" | |
require "builder" | |
class Converter | |
def self.hash_to_xml(hash, options = {}) | |
raise unless hash.kind_of? Hash | |
if options[:builder] | |
builder = options[:builder] | |
else | |
builder = Builder::XmlMarkup.new(indent: 2) | |
builder.instruct! | |
end | |
hash.each do |k, v| | |
node_with(builder, k, v) | |
end | |
builder.target! | |
end | |
def self.array_to_xml(array, key, options = {}) | |
raise unless array.kind_of? Array | |
builder = options[:builder] || Builder::XmlMarkup.new(indent: 2) | |
array.each do |elt| | |
node_with(builder, key, elt) | |
end | |
builder.target! | |
end | |
private | |
def self.node_with(builder, k, v) | |
case v | |
when Hash | |
builder.tag!(k) { hash_to_xml(v, :builder => builder) } | |
when Array | |
array_to_xml(v, k, :builder => builder) | |
else | |
builder.tag!(k, v) | |
end | |
end | |
end | |
class TestConverter < Minitest::Test | |
def setup | |
@profile = {:name => "Larry", :twitter => "@larrylv", :github => "@larrylv"} | |
end | |
def test_string_values | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_hash_values | |
@profile[:blog] = { | |
:tech => "blog.larrylv.com", | |
:journey => "journey.larrylv.com", | |
:homepage => "larrylv.com" | |
} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blog> | |
<tech>blog.larrylv.com</tech> | |
<journey>journey.larrylv.com</journey> | |
<homepage>larrylv.com</homepage> | |
</blog> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
def test_array_values | |
@profile[:blogs] = {:blog => %w(blog.larrylv.com journey.larrylv.com larrylv.com)} | |
expected_value = <<-XML.strip_heredoc | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<name>Larry</name> | |
<twitter>@larrylv</twitter> | |
<github>@larrylv</github> | |
<blogs> | |
<blog>blog.larrylv.com</blog> | |
<blog>journey.larrylv.com</blog> | |
<blog>larrylv.com</blog> | |
</blogs> | |
XML | |
assert_equal expected_value, Converter.hash_to_xml(@profile) | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment