Created
October 25, 2012 15:38
-
-
Save altamic/3953435 to your computer and use it in GitHub Desktop.
Hash structure for xml conversion
This file contains 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
class Hash | |
def to_xml | |
case keys.size | |
when 0 | |
"" | |
when 1 | |
result = nil | |
each_pair do |k, v| | |
case v | |
when nil then result = "<#{k.to_s}/>" | |
when String then result = "<#{k}>#{v}</#{k}>" | |
when Fixnum then result = "<#{k}>#{v}</#{k}>" | |
when Array then case v.compact.size | |
when 1 then case v.compact.first | |
when Hash then result = "<#{k} #{v.first.send(:to_attr)} />" | |
else | |
result = "<#{k}>#{v.compact.first}</#{k}>" | |
end | |
when 2 then case v.last | |
when String | |
result = "<#{k} #{v.first.send(:to_attr)}>#{v.last}</#{k}>" | |
when Hash | |
result = "<#{k} #{v.first.send(:to_attr)}>#{v.last.to_xml}</#{k}>" | |
end | |
end | |
when Hash then result = "<#{k}>#{v.to_xml}</#{k}>" | |
end | |
end | |
result | |
else | |
collect{|k, v| Hash[k,v].to_xml}.join | |
end | |
end | |
def first | |
Hash[keys.first,values.first] | |
end | |
def last | |
Hash[keys.last,values.last] | |
end | |
private | |
def to_attr | |
collect{|k, v| v.nil? ? "#{k}": "#{k}='#{v}'"}.join(' ') | |
end | |
end | |
require 'minitest/autorun' | |
class TestHash < MiniTest::Unit::TestCase | |
def test_void_hash | |
assert_equal "", {}.to_xml | |
end | |
def test_empty_node | |
assert_equal "<a/>", {a:nil}.to_xml | |
end | |
def test_string_text | |
assert_equal "<a>hello</a>", {a:'hello'}.to_xml | |
end | |
def test_number_text | |
assert_equal "<a>1</a>", {a:1}.to_xml | |
end | |
def test_node_with_no_attributes | |
assert_equal "<a>hello</a>", {a:[nil,"hello"]}.to_xml | |
end | |
def test_node_with_no_attributes_compacted | |
assert_equal "<a>hello</a>", {a:["hello"]}.to_xml | |
end | |
def test_node_with_attributes_only | |
assert_equal "<a b='1' c />", {a:[{b:1,c:nil}]}.to_xml | |
end | |
def test_node_with_attributes_and_nil_text | |
assert_equal "<a b='1' c='2' />", {a:[{b:1,c:2},nil]}.to_xml | |
end | |
def test_node_with_attributes_and_text | |
assert_equal "<a b='1' c='2'>hello</a>", {a:[{b:1,c:2},"hello"]}.to_xml | |
end | |
def test_node_with_attributes_and_nesting | |
assert_equal "<a b='1' c='2'><d>3</d><e>4</e></a>", {a:[{b:1,c:2},{d:3,e:4}]}.to_xml | |
end | |
def test_nesting | |
assert_equal "<a><b>1</b><c/></a>", {a:{b:1,c:nil}}.to_xml | |
end | |
def test_nesting_with_more_elements | |
assert_equal "<a><b>1</b><c/><d>hello</d></a>", {a:{b:1,c:nil,d:"hello"}}.to_xml | |
end | |
def test_nesting_with_attributes_and_text | |
assert_equal "<html><body><a id='header'>Header</a></body></html>", {html:{body:{a:[{id:'header'},"Header"]}}}.to_xml | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment