# Copyright 2008 The Tor Project, Inc. See LICENSE for licensing information. """This module converts JSon to XML. It is allegedly for people who have libraries that can read XML, but nothing that can read JSon. Nick questions whether it's actually useful. Certainly, it's quite unlikely that you'll be able to check any keys once you've converted it. """ import re import thandy def xml_str_encoder(s): s = s.replace("&", "&") s = s.replace("<", "<") s = s.replace(">", ">") return s def isAsciiName(s): """ Return true iff s is pure-ascii, and a syntactically valid XML name. >>> isAsciiName("a") True >>> isAsciiName("ab.-dc") True >>> isAsciiName("") False >>> isAsciiName(".foo") False """ return re.match(r'^[A-Za-z\_\:][A-Za-z0-9\_\:\-\.]*$', s) != None def _encodeToXML(obj, outf): if isinstance(obj, basestring): outf(xml_str_encoder(obj)) elif obj is True: outf("true") elif obj is False: outf("false") elif obj is None: outf("null") elif isinstance(obj, (int,long)): outf(str(obj)) elif isinstance(obj, (tuple, list)): outf("\n") for item in obj: outf("") _encodeToXML(item, outf) outf(" ") outf("\n") elif isinstance(obj, dict): outf("\n") for k,v in sorted(obj.items()): isAscii = isAsciiName(k) if isAscii: outf("<%s>"%k) _encodeToXML(v, outf) outf("\n"%k) else: outf("%s"%xml_str_encoder(k)) _encodeToXML(v, outf) outf("\n") outf("\n") else: raise thandy.FormatException("I can't encode %r"%obj) def encodeToXML(obj, outf=None): """Convert a json-encodable object to a quick-and-dirty XML equivalent.""" result = None if outf == None: result = [] outf = result.append _encodeToXML(obj, outf) if result is not None: return "".join(result)