Skip to content

Instantly share code, notes, and snippets.

@gdanko
Last active April 3, 2018 21:18
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 gdanko/78489668bbb1fad5989e05e7aeba8360 to your computer and use it in GitHub Desktop.
Save gdanko/78489668bbb1fad5989e05e7aeba8360 to your computer and use it in GitHub Desktop.
A simple hash > XML converter using REXML
class ::Hash
require "rexml/document"
def to_xml(indent: nil, rootname: nil, output: nil, encoding: nil)
indent = indent ? indent : 2
rootname = rootname ? rootname : "root"
output = output == $stdout ? $stdout : nil
encoding = encoding ? encoding : "UTF-8"
xml = REXML::Document.new
formatter = REXML::Formatters::Pretty.new(indent)
formatter.compact = true
process_block(key: rootname, block: self, xml: xml)
xml << REXML::XMLDecl.new("1.0", "utf-8")
if output == $stdout
formatter.write(xml, $stdout)
else
output = ""
formatter.write(xml, output)
return output
end
end
private
def process_block(key: nil, block: nil, xml: nil)
if block.is_a?(Hash)
attributes = find_attributes(block: block)
attributes.each { |key, value| block.delete(key) }
item = attributes.length > 0 ? xml.add_element(key, attributes) : xml.add_element(key)
block.each do |key, value|
process_block(key: key, block: value, xml: item)
end
elsif block.is_a?(Array)
block.each do |element|
process_block(key: key, block: element, xml: xml)
end
else
item = xml.add_element(key)
item.text = block.to_s
end
end
def find_attributes(block: nil)
attributes = {}
block.each do |key, value|
attributes[key] = value if (not value.is_a?(Array) and not value.is_a?(Hash))
end
return attributes
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment