Skip to content

Instantly share code, notes, and snippets.

@altamic
Created October 25, 2012 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save altamic/3953435 to your computer and use it in GitHub Desktop.
Save altamic/3953435 to your computer and use it in GitHub Desktop.
Hash structure for xml conversion
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