YAML2XML in 33 lines or your money back
Posted by Ben Jackson Fri, 23 Sep 2005 18:44:00 GMT
After spending more than a few hours trying to find a decent YAML2XML converter, struggling with CPAN to install the required perl modules for the hack that I found and finding that the output was buggy and incomplete, I decided to have a shot at doing it myself and learn about ruby's XML libraries in the process.
Two and a half hours and 33 lines of code later and I've got a basic converter that will work with sephiroth's XML2Object library for Actionscript. The secret (courtesy of Jim Weirich) is the use of builder.method_missing() to pass an arbitrary tag name instead of the usual syntax:
# normal usage
builder.div {
builder.p("hello world!")
}
# equivalent
builder.method_missing("div") {
builder.method_missing("p", "hello world!")
}
Here's the final script:
# yaml2xml.rb
# converts a yaml document to a corresponding xml
# format for use with XML2Object class from sephiroth.it
# for more details on the class visit
# http://www.sephiroth.it/file_detail.php?pageNum_comments=10&id=129
# usage: ruby yaml2xml.rb input.yml > output.xml
require 'yaml'
require 'rubygems'
require_gem 'builder'
@builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
def yaml2xml src, tagname="root"
unless src.is_a?(Array)
@builder.method_missing(tagname) {
process_source src, tagname
}
else
process_source src, tagname
end
end
def process_source src, tagname
if src.is_a?(Hash)
src.each do |name, value|
unless value.kind_of?(Hash) or value.kind_of?(Array)
@builder.method_missing(name, value)
else
yaml2xml value, name
end
end
elsif src.is_a?(Array)
src.each do |value|
yaml2xml value, tagname
end
end
end
yaml2xml YAML::load(File.open(ARGV[0]))

! /usr/bin/python
you need syck (python2.3-syck package on debian)
usage: yaml2xml input.yml > output.xml
import sys,syck,yaml2xml print yaml2xml.yaml2xml(syck.load(file(sys.argv[1]).read()))