# Copyright 2008 The Tor Project, Inc. See LICENSE for licensing information. 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)