""" yaml2xml This currently takes a recursive map/list/string structure and serializes it as http://yaml.org/xml/ discusses. It is definately 'unstable'. There is also a html option, and with a really nice CSS style sheet, it can be made to look quite like real YAML (using images for lists and mappings). Note, this does not handle XML escaping.... """ import types tab = ' ' def yaml2html(data, write = None): return yaml2xml(data, write,'div','dl','dt','dd','ol','li') def encode(data): if data is None: return '' return str(data).replace('"',""").replace(\ "&","&").replace("<","<") def yaml2xml(data, write = None, root = 'root', map = '', map_key = '*', map_val = '', seq = '', seq_val = '_', rootattr = {} ): """ Very primitive dump from native map, list, scalar data structures into XML per http://yaml.org/xml/ """ ret = lambda: None if not write: lst = [] write = lst.append ret = lambda: "".join(lst) def opentag(key,val,spacer='\n',inmap=False,attrib = {},close=False): if '*' != map_key and inmap: write("<%s>%s" % (map_key, key, map_key)) write(spacer) key = map_val write("<%s" % key) keys = attrib.keys() keys.sort() indent = spacer + (' ' * (len(key)+1)) siz = len(indent) if type({}) == type(val): lst = [(k,v) for (k,v) in val.items() if k[0] == '@'] lst.sort() for (k,v) in lst: item = ' %s="%s"' % (k[1:],encode(v)) if siz + len(item) > 59: siz = len(indent) write(indent) write(item) siz += len(item) for k in keys: item = ' %s="%s"' % (k,encode(attrib[k])) if siz + len(item) > 59: siz = len(indent) write(indent) write(item) siz += len(item) if close: write("/") write(">") def apply(data, indent = tab): spacer = "\n" + indent if data is None: return typ = type(data) if typ in (type([]), type(tuple())): if seq: write(spacer) write("<%s>" % seq) for v in data: write(spacer) opentag(seq_val,v,spacer) if apply(v,indent + tab): write(spacer) write('' % seq_val ) if seq: write(spacer) write("" % seq) return 1 if type({}) == typ: lst = data.items() lst.sort() if map: write(spacer) write("<%s>" % map) for (k,v) in lst: if '@' == k[0] or '=' == k[0]: continue write(spacer) opentag(k,v,spacer,inmap=True) if apply(v,indent + tab): write(spacer) if '*' == map_key: write("" % k) else: write("" % map_val) if map: write(spacer) write("" % map) return 1 write(encode(data)) return 0 if data: opentag(root,data,attrib=rootattr) if apply(data): write("\n") write('\n' % root) else: opentag(root,data,attrib=rootattr,close=True) write("\n") return ret() if __name__ == '__main__': assert yaml2xml(None) == """\ """ assert yaml2xml(None,root='bing',rootattr={'one': '1', 'two': '2'}) == """\ """ assert yaml2xml('hello') == """\ hello """ assert yaml2xml({'k':'v'}) == """\ v """ assert yaml2xml({'@att': 'val'}, rootattr={'ick': 'value'}) == """\ """ assert yaml2xml({'key': 'value','sublist': [{'@at': 'aval', 'a': 'b' }]} ) == """\ value <_ at="aval"> b """ assert yaml2xml({'key': 'value','submap': {'@at': 'aval', 'a': 'b' }} ) == """\ value b """ assert yaml2xml(['one','two']) == """\ <_>one <_>two """ assert yaml2xml({'key': 'value', 'list': ['one',{'a':'b'}]}) == """\ value <_>one <_> b """ assert yaml2xml(None,root='bing', rootattr={'name': "Full Name", "tele": "Telephone", "addr": "This is someone's address." }) == """\ """ assert yaml2html(None) == """\
""" assert yaml2html('hello') == """\
hello
""" assert yaml2html({'k':'v'}) == """\
k
v
""" assert yaml2html(['one','two']) == """\
  1. one
  2. two
""" assert yaml2html({'key': 'value', 'list': ['one',{'a':'b'}]}) == """\
key
value
list
  1. one
  2. a
    b
""" assert yaml2html({'key': 'value','submap': {'@at': 'aval', 'a': 'b' }} ) == """\
key
value
submap
a
b
"""