def encode(self, obj, root='root'): buf = StringIO() xml = XMLGenerator(buf, encoding='utf-8') xml.startDocument() self.encode_obj(xml, root, obj) xml.endDocument() return buf.getvalue()
class xmlreport: def __init__(self, filename, xslfile): self.fp = open(filename, "wb") self.xmlgen = XMLGenerator(self.fp, "utf-8") self.xmlgen.startDocument() self.xmlgen.processingInstruction("xml-stylesheet", 'type="text/xsl" href="{}"'.format(xslfile)) attrs = AttributesNSImpl({}, {}) self.xmlgen.startElementNS((None, "report"), "report", attrs) def write(self, path, code, message): attr_vals = { (None, "code"): code, (None, "path"): path } attr_qnames = { (None, "code"): "code", (None, "path"): "path" } attrs = AttributesNSImpl(attr_vals, attr_qnames) self.xmlgen.startElementNS((None, "file"), "file", attrs) self.xmlgen.characters(message) self.xmlgen.endElementNS((None, "file"), "file") def newline(self): #self.fp.write("\n") self.xmlgen.characters("\n") def close(self): self.xmlgen.endElementNS((None, "report"), "report") self.xmlgen.endDocument() self.fp.close()
def export(self,filename,transport): vprint( "osm-xml export...",1) #remember all nodes already exported unodes = {} fp = open(filename, "w") x = XMLGenerator(fp, "UTF-8") x.startDocument() x.startElement('osm',{"version":"0.6","generator":"crazy py script"}) for w in self.ways.itervalues(): if not 'highway' in w.tags: continue if transport == "all" or transport == "pt": if not (w.tags['highway']=='bus' or w.tags['highway']=='tram'): continue if transport == "all" or transport == "hw": if (w.tags['highway']=='bus' or w.tags['highway']=='tram'): continue w.toOSM(x) for nid in w.nds: if nid in unodes:#already used continue unodes[nid]=True if w.nds.index(nid)==0 or w.nds.index(nid)==len(w.nds)-1: self.nodes[nid].toOSM(x,True) else: self.nodes[nid].toOSM(x) x.endElement('osm') x.endDocument()
def test_5027_2(self): # The xml prefix (as in xml:lang below) is reserved and bound by # definition to http://www.w3.org/XML/1998/namespace. XMLGenerator had # a bug whereby a KeyError is raised because this namespace is missing # from a dictionary. # # This test demonstrates the bug by direct manipulation of the # XMLGenerator. result = StringIO() gen = XMLGenerator(result) gen.startDocument() gen.startPrefixMapping("a", "http://example.com/ns") gen.startElementNS(("http://example.com/ns", "g1"), "g1", {}) lang_attr = {("http://www.w3.org/XML/1998/namespace", "lang"): "en"} gen.startElementNS(("http://example.com/ns", "g2"), "g2", lang_attr) gen.characters("Hello") gen.endElementNS(("http://example.com/ns", "g2"), "g2") gen.endElementNS(("http://example.com/ns", "g1"), "g1") gen.endPrefixMapping("a") gen.endDocument() self.assertEqual( result.getvalue(), start + ('<a:g1 xmlns:a="http://example.com/ns">' '<a:g2 xml:lang="en">Hello</a:g2>' "</a:g1>"), )
def generateXML(self,output): gen = XMLGenerator(output,"UTF-8") gen.startDocument() gen.startElement("xml",{}); if self.skipguid: gen.startElement("sheet",{}) else: gen.startElement("sheet",{'guid':self.sheetUID}) for cellattrs in [{'col':val[0],'row':val[1],'formula':val[2]} for val in self.cells]: if self.skipCol: del cellattrs['col'] if self.skipRow: del cellattrs['row'] if self.skipFormula: del cellattrs['formula'] gen.startElement("cell",cellattrs) gen.endElement("cell") gen.endElement("sheet") if not self.badxml: gen.endElement("xml") gen.endDocument()
class XmlLogger(object): def __init__(self, path): if os.access(path, os.F_OK): os.rename(path, path + '.bak-' + str(load_time)) self.output = open(path, 'w') self.xml_gen = XMLGenerator(self.output, 'utf-8') self.lock = RLock() def start_log(self, tag, attributes): self.doc_tag = tag with self.lock: self.xml_gen.startDocument() self.xml_gen.startElement(tag, attributes) def end_log(self): with self.lock: self.xml_gen.endElement(self.doc_tag) self.xml_gen.endDocument() @contextmanager def element(self, name, attrs={}): with self.lock: attrs = dict((key, str(value)) for key, value in attrs.items()) self.text('\n') self.xml_gen.startElement(name, attrs) yield self.xml_gen.endElement(name) def text(self, text): with self.lock: self.xml_gen.characters(str(text))
def manifest_xml(f, files): from xml.sax.saxutils import XMLGenerator xml = XMLGenerator(f, "utf-8") xml.startDocument() uri = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" prefix = "manifest" xml.startPrefixMapping(prefix, uri) def startElement(name, attrs): attrs = dict(((uri, n), v) for n, v in attrs.iteritems()) xml.startElementNS((uri, name), prefix + ":" + name, attrs) def endElement(name): xml.endElementNS((uri, name), prefix + ":" + name) def file_entry(full_path, media_type, **kwargs): attrs = {"media-type": media_type, "full-path": full_path} attrs.update(dict((n.replace("_", "-"), v) for n, v in kwargs.iteritems())) startElement("file-entry", attrs) endElement("file-entry") startElement("manifest", dict(version="1.2")) file_entry("/", "application/vnd.oasis.opendocument.text", version="1.2") for e in files: e = dict(e) full_path = e.pop("full_path") media_type = e.pop("media_type", "application/octet-stream") file_entry(full_path, media_type) endElement("manifest") xml.endPrefixMapping(prefix) xml.endDocument()
def saveProfiles(self, filename = None): '''saves the profiles to filename (default asstes/profiles.xml)''' if not filename: filename = os.path.join('assets', 'profiles.xml') xml_file = open(filename, "w") xmlgen = XMLGenerator(xml_file, 'UTF-8') xmlgen.startDocument() xmlgen.startElement('profilelist', {'default': str(self.currentProfile['id'])}) xml_file.write('\n') for profile in self.profiles: keys = {} for key in profile: if not key == 'active': keys[key] = str(profile[key]) xml_file.write('\t') xmlgen.startElement('profile', keys) for s in profile.shiplist: keys = {} for key in profile.shiplist[s]: keys[key] = str(profile.shiplist[s][key]) xml_file.write('\n\t\t') xmlgen.startElement('ship', keys) xmlgen.endElement('ship') xml_file.write('\t') xmlgen.endElement('profile') xml_file.write('\n') xmlgen.endElement('profilelist') xml_file.write('\n') xmlgen.endDocument() xml_file.close() self.createDisplay()
class XmlWriter(AbstractXmlWriter): def __init__(self, path): self.path = path self._output = open(path, 'wb') self._writer = XMLGenerator(self._output, 'UTF-8') self._writer.startDocument() self.closed = False def start(self, name, attributes={}, newline=True): attrs = AttributesImpl(attributes) self._writer.startElement(name, attrs) if newline: self.content('\n') def content(self, content): if content is not None: self._writer.characters(self._encode(content)) def end(self, name, newline=True): self._writer.endElement(name) if newline: self.content('\n') def close(self): self._writer.endDocument() self._output.close() self.closed = True
class XmlWriter(AbstractXmlWriter): def __init__(self, output): self._output = self._create_output(output) self._writer = XMLGenerator(self._output, encoding='UTF-8') self._writer.startDocument() self.closed = False def _create_output(self, output): return open(output, 'w') \ if isinstance(output, basestring) else output def _start(self, name, attrs): self._writer.startElement(name, AttributesImpl(attrs)) def _content(self, content): self._writer.characters(content) def _end(self, name): self._writer.endElement(name) def _newline(self): self._output.write('\n') # Workaround for http://ironpython.codeplex.com/workitem/29474 if sys.platform == 'cli': def _escape(self, content): return AbstractXmlWriter._escape(self, content).encode('UTF-8')
def main(): optparser = optparse.OptionParser(usage="Usage: %prog [options] POFILE ...") optparser.add_option("-r", "--roundtrip", help="generate round-tripable output", action="store_true", dest="roundtrip", default=False) optparser.add_option("-o", "--output", help="write output to XMLFILE", metavar="XMLFILE", action="store", dest="output", default="-") (options, args) = optparser.parse_args() if options.output == "-": output = sys.stdout else: output = open(options.output, "w") writer = XMLGenerator(output or sys.stdout, "utf-8") writer.startDocument() writer.processingInstruction("xml-stylesheet", 'type="text/xsl" href="format-html.xsl"') writer.ignorableWhitespace("\n") writer.startElement("messages", {}) writer.ignorableWhitespace("\n") msg = Message(writer, options.roundtrip) for l in fileinput.input(args): # Continuation string? m = re.match(r'\s*"(.*)"', l) if m: assert(msg.current) msg.current.append(unescape_c(m.group(1))) continue else: msg.flush() m = re.match(r'(?s)msgid "(.*)"', l) if m: msg.msgid = [unescape_c(m.group(1))] msg.current = msg.msgid m = re.match(r'(?s)msgstr "(.*)"', l) if m: msg.msgstr = [unescape_c(m.group(1))] msg.current = msg.msgstr m = re.match(r'# \s*(.*)', l) if m: msg.usrcomment.append(m.group(1)) m = re.match(r'#\.\s*(.*)', l) if m: msg.dotcomment.append(m.group(1)) m = re.match(r'#:\s*(.*)', l) if m: msg.reference.append(m.group(1)) m = re.match(r'#,\s*(.*)', l) if m: msg.flags.append(m.group(1)) msg.flush() writer.endElement("messages") writer.ignorableWhitespace("\n") writer.endDocument()
def unparse(input_dict, output=None, encoding='utf-8', full_document=True, **kwargs): """ dict(json)转xml格式 :param input_dict: :param output: :param encoding: :param full_document: :param kwargs: :return: """ if full_document and len(input_dict) != 1: raise ValueError('Document must have exactly one root.') must_return = False if output is None: output = StringIO() must_return = True content_handler = XMLGenerator(output, encoding) if full_document: content_handler.startDocument() for k, v in input_dict.items(): _emit(k, v, content_handler, full_document=full_document, **kwargs) if full_document: content_handler.endDocument() if must_return: rep_value = output.getvalue() try: rep_value = rep_value.decode(encoding) except AttributeError: pass return rep_value
def execute(self, transform_manager, input): with open(transform_manager('xml'), 'w') as output: transform_manager.start(self, [input]) generator = XMLGenerator(output, encoding='utf-8') generator.startDocument() generator.startElement('TEI', {'xmlns':'http://www.tei-c.org/ns/1.0'}) generator.startElement('text', {}) generator.startElement('body', {}) for sheet in self.sheets(input): generator.startElement('table', {}) generator.startElement('head', {}) generator.characters(sheet.name) generator.endElement('head') for i, row in enumerate(sheet.rows): generator.startElement('row', {'n': unicode(int(i) + 1)}) for j, cell in enumerate(row.cells): generator.startElement('cell', {'n': unicode(j + 1)}) generator.characters(unicode(cell)) generator.endElement('cell') generator.endElement('row') generator.endElement('table') generator.endElement('body') generator.endElement('text') generator.endElement('TEI') transform_manager.end([output.name]) return output.name
class XmlItemExporter(BaseItemExporter): def __init__(self, file, **kwargs): self.item_element = kwargs.pop('item_element', 'item') self.root_element = kwargs.pop('root_element', 'items') self._configure(kwargs) self.xg = XMLGenerator(file, encoding=self.encoding) def start_exporting(self): self.xg.startDocument() self.xg.startElement(self.root_element, {}) def export_item(self, item): self.xg.startElement(self.item_element, {}) for name, value in self._get_serialized_fields(item, default_value=''): self._export_xml_field(name, value) self.xg.endElement(self.item_element) def finish_exporting(self): self.xg.endElement(self.root_element) self.xg.endDocument() def _export_xml_field(self, name, serialized_value): self.xg.startElement(name, {}) if hasattr(serialized_value, '__iter__'): for value in serialized_value: self._export_xml_field('value', value) else: self.xg.characters(serialized_value) self.xg.endElement(name)
class KanjiListToXmlFile: def __init__(self, filepath): self.file = open(filepath, "w+") self.handler = XMLGenerator(self.file, 'utf-8') self.handler.startDocument() self.handler.startElement('list', {}) def __del__(self): self.handler.endElement('list') self.handler.endDocument() def kanjiToXml(self, kanji): self.handler.startElement('character', {}) for el in kanji.element: if isinstance(kanji.element[el], unicode): self.handler.startElement(el, {}) self.handler.characters(kanji.element[el]) self.handler.endElement(el) elif isinstance(kanji.element[el], int): self.handler.startElement(el, {}) self.handler.characters(str(kanji.element[el])) self.handler.endElement(el) elif isinstance(kanji.element[el], list): for m in kanji.element[el]: self.handler.startElement(el, {}) self.handler.characters(m) self.handler.endElement(el) self.handler.endElement('character') self.file.write('\n') def kanjiListToXml(self, kanjiList): for kanji in kanjiList: self.kanjiToXml(kanji)
class ExportExtractor(XMLFilterBase): def __init__(self, file): XMLFilterBase.__init__(self) self.generator = XMLGenerator(file, 'UTF-8') self.generator.startPrefixMapping(u'', u'http://www.eucalyptus.com/ns/reporting/export/2012-08-24/') self.replyData = StringIO() self.replyGenerator = XMLGenerator( self.replyData, 'UTF-8' ) self.switchTarget( self.replyGenerator ) def startDocument(self): self.generator.startDocument() XMLFilterBase.startDocument(self) def endElementNS(self, name, qname): XMLFilterBase.endElementNS(self, name, qname) namespace, element = name if namespace == u'http://www.eucalyptus.com/ns/reporting/export/2012-08-24/' and element == u'Export': self.switchTarget( self.replyGenerator ) def startElementNS(self, name, qname, attrs): namespace, element = name if namespace == u'http://www.eucalyptus.com/ns/reporting/export/2012-08-24/' and element == u'Export': self.switchTarget( self.generator ) XMLFilterBase.startElementNS(self, name, qname, attrs) def switchTarget(self, target): self._cont_handler = target self._dtd_handler = target self._ent_handler = target self._err_handler = target def getReply(self): return self.replyData.getvalue()
def test_5027_2(self): # The xml prefix (as in xml:lang below) is reserved and bound by # definition to http://www.w3.org/XML/1998/namespace. XMLGenerator had # a bug whereby a KeyError is thrown because this namespace is missing # from a dictionary. # # This test demonstrates the bug by direct manipulation of the # XMLGenerator. result = StringIO() gen = XMLGenerator(result) gen.startDocument() gen.startPrefixMapping('a', 'http://example.com/ns') gen.startElementNS(('http://example.com/ns', 'g1'), 'g1', {}) lang_attr = {('http://www.w3.org/XML/1998/namespace', 'lang'): 'en'} gen.startElementNS(('http://example.com/ns', 'g2'), 'g2', lang_attr) gen.characters('Hello') gen.endElementNS(('http://example.com/ns', 'g2'), 'g2') gen.endElementNS(('http://example.com/ns', 'g1'), 'g1') gen.endPrefixMapping('a') gen.endDocument() self.assertEqual(result.getvalue(), start + ( '<a:g1 xmlns:a="http://example.com/ns">' '<a:g2 xml:lang="en">Hello</a:g2>' '</a:g1>'))
def save(self, filename=None): if self.filename and filename is None: filename = self.filename if len(self.__dict__) == 0 or filename == None: return try: fileobj = open(filename, 'w') except: print 'ERROR>>> cannot write preferences into %s' % filename return writer = XMLGenerator(out=fileobj, encoding=self.system_encoding) writer.startDocument() defaults = XmlConfigParser.__dict__ items = self.__dict__.items() items.sort() writer.startElement('preferences', {}) writer.characters('\n') for key, value in items: if defaults.has_key(key) and defaults[key] == value: continue if key in ['filename', 'app']: continue writer.characters('\t') writer.startElement('%s' % key, {}) str_value = path_unicode(value.__str__()) if isinstance(value, str): str_value = "'%s'" % (escape_quote(str_value)) writer.characters(str_value) writer.endElement('%s' % key) writer.characters('\n') writer.endElement('preferences') writer.endDocument() fileobj.close
def unparse(input_dict, output=None, encoding='utf-8', full_document=True, **kwargs): """Emit an XML document for the given `input_dict` (reverse of `parse`). The resulting XML document is returned as a string, but if `output` (a file-like object) is specified, it is written there instead. Dictionary keys prefixed with `attr_prefix` (default=`'@'`) are interpreted as XML node attributes, whereas keys equal to `cdata_key` (default=`'#text'`) are treated as character data. The `pretty` parameter (default=`False`) enables pretty-printing. In this mode, lines are terminated with `'\n'` and indented with `'\t'`, but this can be customized with the `newl` and `indent` parameters. """ if full_document and len(input_dict) != 1: raise ValueError('Document must have exactly one root.') must_return = False if output is None: output = StringIO() must_return = True content_handler = XMLGenerator(output, encoding) if full_document: content_handler.startDocument() for key, value in input_dict.items(): _emit(key, value, content_handler, full_document=full_document, **kwargs) if full_document: content_handler.endDocument() if must_return: value = output.getvalue() try: # pragma no cover value = value.decode(encoding) except AttributeError: # pragma no cover pass return value
def manifest_xml(f, files): from xml.sax.saxutils import XMLGenerator xml = XMLGenerator(f, 'utf-8') xml.startDocument() uri = 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0' prefix = 'manifest' xml.startPrefixMapping(prefix, uri) def startElement(name, attrs): attrs = dict( ((uri, n), v) for n, v in attrs.iteritems() ) xml.startElementNS( (uri, name), prefix+':'+name, attrs) def endElement(name): xml.endElementNS( (uri, name), prefix+':'+name) def file_entry(full_path, media_type, **kwargs): attrs = {'media-type': media_type, 'full-path': full_path} attrs.update(dict((n.replace('_', '-'), v) for n, v in kwargs.iteritems())) startElement('file-entry', attrs) endElement('file-entry') startElement( 'manifest', dict(version='1.2') ) file_entry('/', 'application/vnd.oasis.opendocument.text', version='1.2') for e in files: e = dict(e) full_path = e.pop('full_path') media_type = e.pop('media_type', 'application/octet-stream') file_entry(full_path, media_type) endElement( 'manifest' ) xml.endPrefixMapping(prefix) xml.endDocument()
class XmlFormat(ModelEventHandler): def __init__(self, out): self.xmlgen = XMLGenerator(out, 'utf-8') def startDocument(self): self.xmlgen.startDocument() def startModel(self, model, attributes, **context): logger.debug('xmlmodel.XmlFormat: model: %s, %s', model.__name__, attributes) logger.debug('xmlmodel.XmlFormat: context: %s', context) recordid = context.get('recordid', ('UNKNOWN', 'UNKNOWN', -1)) hwptag = context.get('hwptag', '') logger.info('xmlmodel.XmlFormat: rec:%d %s', recordid[2], hwptag) if model is Text: text = attributes.pop('text') else: text = None for x in startelement(context, self.xmlgen, (model, attributes)): x[0](*x[1:]) if model is Text and text is not None: self.xmlgen.characters(text) unparsed = context.get('unparsed', '') if len(unparsed) > 0: logger.debug('UNPARSED: %s', hexdump(unparsed, True)) def endModel(self, model): self.xmlgen.endElement(model.__name__) def endDocument(self): self.xmlgen.endDocument()
class XMLTweets(): ns = "http://www.milowski.com/twitter" out = None xml = None def open(self,filename): self.out = open(filename,"w") self.xml = XMLGenerator(self.out,"utf-8") self.xml.startDocument() self.xml.startPrefixMapping("",self.ns) self.xml.startElementNS((self.ns,"tweets"),"tweets",{}) self.xml.characters("\n") def tweet(self,tweet): self.xml.startElementNS((self.ns,"tweet"),"tweet",{(None,"alias"):tweet.user.screen_name, (None,"created"): tweet.created_at.strftime("%Y-%m-%dT%H-%M-%SZ")}) self.xml.characters(tweet.text) self.xml.endElementNS((self.ns,"tweet"),"tweet") self.xml.characters("\n") def close(self): if self.out != None: self.xml.endElementNS((self.ns,"tweets"),"tweets") self.xml.endDocument() self.out.close() self.xml = None self.out = None
def toOSM(self,x): # Generate SAX events frame = False if x == None : frame=True # Start Document x = XMLGenerator(sys.stdout, "UTF-8") x.startDocument() x.startElement('osm',{"version":"0.6"}) x.startElement('relation',{"id":"-"+self.id.split("-",2)[1]}) #bad but for rendering ok #x.startElement('way',{"id":self.id.replace("special","").split("-",2)[0]}) for nid,role in map(lambda t: (t.items()[0]), self.mnode): x.startElement('member',{"type":"node", "ref":nid, "role":role}) x.endElement('member') for wid,role in map(lambda t: (t.items()[0]), self.mway): x.startElement('member',{"type":"way", "ref":wid, "role":role}) x.endElement('member') for rid,role in map(lambda t: (t.items()[0]), self.mrelation): x.startElement('member',{"type":"relation", "ref":rid, "role":role}) x.endElement('member') for k, v in self.tags.iteritems(): x.startElement('tag',{"k":k, "v":v}) x.endElement('tag') x.endElement('way') if frame: x.endElement('osm') x.endDocument()
def get_update_result_as_xml(status, txn_id, prv_txn, sum, comment=None): out = StringIO.StringIO("") g = XMLGenerator(out, encoding='UTF-8') g.startDocument() g.startElement("response", {}) g.startElement("mgpe_txn_id", {}) g.characters(txn_id) g.endElement("mgpe_txn_id") g.startElement("txn_id", {}) g.characters(txn_id) g.endElement("txn_id") g.startElement("prv_txn", {}) g.characters(prv_txn) g.endElement("prv_txn") g.startElement("sum", {}) g.characters(sum) g.endElement("sum") g.startElement("result", {}) g.characters(status) g.endElement("result") if comment: g.startElement("comment", {}) g.characters(comment) g.endElement("comment") g.endElement("response") g.endDocument() return out.getvalue()
class RspecFreezer(): #repositories is a dict of names and CTXRepo objects def __init__ (self, repositories, output = sys.stdout): self.default_version = "1" self.repos = repositories self.msgSender = "rspecRecursiveFreezer" self.xmlgenerator = XMLGenerator(output,'utf-8'); self.rcsclient = dict() self.rcsclient['svn']= ctx_svn_client.CTXSubversionClient() self.rcsclient['git']= ctx_git_client.CTXGitClient() #-------------------------------------------------------------------------- def generateFrozen(self, repo_names_to_freeze = None): self.xmlgenerator.startDocument() self.xmlgenerator.characters("\n") self.xmlgenerator.startElement('ctx-rspec', attrs = {}) self.xmlgenerator.characters("\n") for repo in self.repos: if repo_names_to_freeze == None: self.freezeRepo(repo) else: if repo.getID() in repo_names_to_freeze: self.freezeRepo(repo) self.xmlgenerator.endElement('ctx-rspec') self.xmlgenerator.characters("\n") self.xmlgenerator.endDocument() #self.rspec. def freezeRepo(self, repo): id = repo.getID() href = repo.getHref() rcs = repo.getRcs() path = repo.getPath() rev = repo.getRSpecRevision() repo_path = repo.getAbsLocalPath() #TODO: make it possible to base the freeze on an existing rspec (only freeze repos included in there) if (rcs == 'svn' or rcs == 'git'): if rev == 'HEAD' or rev == None or rev == 'master': curr_rev = self.rcsclient[rcs].getRevisionFromWorkingCopy(repo_path) else: curr_rev = self.rcsclient[rcs].getRevisionFromWorkingCopy(repo_path) if str(curr_rev) != rev: warningMessage('%s: Overwriting strict revision nr %s with %s'%(id, str(rev), str(curr_rev))) self.xmlgenerator.characters("\t") self.xmlgenerator.startElement('ctx-repo', attrs = {'id':id,'rcs':rcs, 'href': href, 'rev': str(curr_rev), 'path':path }) self.xmlgenerator.characters("\n") else: warningMessage("Currently only supporting freeze for svn-repos, skipping '%s'"%repo_path) return paths = repo.getAllRelativePaths() for path_type in paths: for path_spec in paths[path_type]: self.xmlgenerator.characters("\t\t") self.xmlgenerator.startElement('ctx-path', attrs = {'type':path_type, 'spec':path_spec}) self.xmlgenerator.endElement('ctx-path') self.xmlgenerator.characters("\n") self.xmlgenerator.characters("\t") self.xmlgenerator.endElement('ctx-repo') self.xmlgenerator.characters("\n\n")
def dump_xml(self, output_dir): """ Dumps test result to xml """ self.buffer = False with open(os.path.join(output_dir, 'junit.xml'), 'w') as output: document = XMLGenerator(output, 'utf-8') document.startDocument() document.startElement('testsuites', AttributesImpl({})) suites = groupby(self.testInfos, key=lambda test_info: self.test_case_name(test_info.test_method)) for suite_name, suite in suites: document.startElement('testsuite', AttributesImpl({'name' : suite_name})) for test_info in suite: document.startElement('testcase', AttributesImpl({ 'classname' : suite_name, 'name' : self.test_method_name(test_info.test_method), 'time' : '%3f' % total_seconds(test_info.end_time - test_info.start_time) })) if test_info.result == TestInfo.RESULT.ERROR: document.startElement('error', AttributesImpl({ 'message' : smart_text(test_info.err[1]) })) document.characters(self._exc_info_to_string(test_info.err, test_info.test_method)) document.endElement('error') elif test_info.result == TestInfo.RESULT.FAILURE: document.startElement('failure', AttributesImpl({ 'message' : smart_text(test_info.err[1]) })) document.characters(self._exc_info_to_string(test_info.err, test_info.test_method)) document.endElement('failure') elif test_info.result == TestInfo.RESULT.UNEXPECTED_SUCCESS: document.startElement('error', AttributesImpl({ 'message' : 'Unexpected success' })) document.endElement('error') elif test_info.result == TestInfo.RESULT.SKIPPED: document.startElement('skipped', AttributesImpl({})) document.characters(test_info.reason) document.endElement('skipped') if test_info.stdout: document.startElement('system-out', AttributesImpl({})) document.characters(test_info.stdout) document.endElement('system-out') if test_info.stderr: document.startElement('system-err', AttributesImpl({})) document.characters(test_info.stderr) document.endElement('system-err') document.endElement('testcase') document.endElement('testsuite') document.endElement('testsuites') document.endDocument()
def __init__(self, output, encoding, top_level_tag, attrs): xml_writer = XMLGenerator(output, encoding, True) xml_writer.startDocument() xml_writer.startElement(top_level_tag, attrs) self._xml_writer = xml_writer self.top_level_tag = top_level_tag self.ident=4 self._xml_writer.characters('\n')
def test_xmlgen_basic_empty(self): result = StringIO() gen = XMLGenerator(result, short_empty_elements=True) gen.startDocument() gen.startElement("doc", {}) gen.endElement("doc") gen.endDocument() self.assertEqual(result.getvalue(), start + "<doc/>")
def test_xmlgen_basic(self): result = StringIO() gen = XMLGenerator(result) gen.startDocument() gen.startElement("doc", {}) gen.endElement("doc") gen.endDocument() self.assertEqual(result.getvalue(), start + "<doc></doc>")
def test_xmlgen_basic(): result = StringIO() gen = XMLGenerator(result) gen.startDocument() gen.startElement("doc", {}) gen.endElement("doc") gen.endDocument() return result.getvalue() == start + "<doc></doc>"
def create_testdoc(_title, _content, _data_count, _data_text): xml_doc = BytesIO() try: xml_generator = XMLGenerator(xml_doc, 'UTF-8') start_element = lambda name, attrs: xml_generator.startElement( name, attrs) end_element = lambda name: xml_generator.endElement(name) text = lambda value: xml_generator.characters(value) attrs = lambda values: AttributesImpl(values) empty_attrs = attrs({}) xml_generator.startDocument() start_element('html', attrs({'xmlns': XHTML_NAMESPACE})) start_element('head', empty_attrs) start_element('title', empty_attrs) text(_title) end_element('title') end_element('head') start_element('body', empty_attrs) start_element('h1', empty_attrs) text(_title) end_element('h1') start_element('p', empty_attrs) text(_content) end_element('p') for i in range(_data_count): start_element('div', attrs({'data-i': str(i)})) for j in range(_data_count): start_element('p', attrs({'data-j': str(j)})) text(_data_text) end_element('p') end_element('div') end_element('body') end_element('html') xml_generator.endDocument() return xml_doc.getvalue() finally: xml_doc.close()
def unparse(input_dict, output=None, encoding='utf-8', full_document=True, **kwargs): """Emit an XML document for the given `input_dict` (reverse of `parse`). The resulting XML document is returned as a string, but if `output` (a file-like object) is specified, it is written there instead. Dictionary keys prefixed with `attr_prefix` (default=`'@'`) are interpreted as XML node attributes, whereas keys equal to `cdata_key` (default=`'#text'`) are treated as character data. The `pretty` parameter (default=`False`) enables pretty-printing. In this mode, lines are terminated with `'\n'` and indented with `'\t'`, but this can be customized with the `newl` and `indent` parameters. """ ((key, value), ) = input_dict.items() must_return = False if output is None: output = StringIO() must_return = True content_handler = XMLGenerator(output, encoding) if full_document: content_handler.startDocument() _emit(key, value, content_handler, **kwargs) if full_document: content_handler.endDocument() if must_return: value = output.getvalue() try: # pragma no cover value = value.decode(encoding) except AttributeError: # pragma no cover pass return value
class XmlItemExporter(BaseItemExporter): def __init__(self, file, **kwargs): self.item_element = kwargs.pop('item_element', 'item') self.root_element = kwargs.pop('root_element', 'items') self._configure(kwargs) self.xg = XMLGenerator(file, encoding=self.encoding) def start_exporting(self): self.xg.startDocument() self.xg.startElement(self.root_element, {}) def export_item(self, item): self.xg.startElement(self.item_element, {}) for value in item: self._export_xml_field(value, item[value]) self.xg.endElement(self.item_element) def finish_exporting(self): self.xg.endElement(self.root_element) self.xg.endDocument() def _export_xml_field(self, name, serialized_value): self.xg.startElement(name, {}) if hasattr(serialized_value, '__iter__'): if type(serialized_value).__name__ != 'dict': for value in serialized_value: if type(value).__name__ == 'str' or type( value).__name__ == 'unicode': self._export_xml_field('value', value) else: self.export_item(value) else: self.export_item(serialized_value) else: self.xg.characters(serialized_value) self.xg.endElement(name)
def run(self): xml = XMLGenerator(self.out, 'UTF-8', True) xml.startDocument() xml.startPrefixMapping('', self.SVG_NAMESPACE) xml.startPrefixMapping(self.XLINK_PREFIX, self.XLINK_NAMESPACE) canvasWidth = int(self.marginWidth + (self.count - 1) * self.offset) attrs = self._defaultNSAttrs({ self._svgName('version'): self.SVG_VERSION, self._svgName('width'): str(canvasWidth), self._svgName('height'): str(self.canvasHeight), self._svgName('viewBox'): ('%d %d %d %g' % (0, 0, canvasWidth, self.canvasHeight)) }) xml.startElementNS(self.SVG_ELEMENT, None, attrs) self._defs(xml) self._contentGroup(xml) xml.ignorableWhitespace('\n') xml.endElementNS(self.SVG_ELEMENT, None) xml.endPrefixMapping('') xml.endPrefixMapping(self.XLINK_PREFIX) xml.endDocument()
def dump_xml(replay): from xml.sax.saxutils import XMLGenerator d = replay_to_dict(replay) players = d.pop('player_slots') gen = XMLGenerator() gen.startDocument() gen.startElement('replay', {}) for key, value in d.iteritems(): gen.startElement(key, {}) gen.characters(str(value)) gen.endElement(key) gen.startElement('players', {}) for player in players: actions = player.pop('actions') gen.startElement('player', {}) for key, value in player.iteritems(): gen.startElement(key, {}) gen.characters(str(value)) gen.endElement(key) gen.startElement('actions', {}) for action in actions: gen.startElement('action', {}) for key, value in action.iteritems(): gen.startElement(key, {}) gen.characters(str(value)) gen.endElement(key) gen.endElement('action') gen.endElement('actions') gen.endElement('player') gen.endElement('players') gen.endElement('replay') gen.endDocument()
def startDocument(self, output, html_title, encoding='UTF-8'): gen = XMLGenerator(output, encoding) gen.startDocument() try: static_location = '/static/content' static_object = self.globals['static'] static_location = static_object.metadata.get('base_url', '/static') static_location += '/content' except: pass output.write('<?xml-stylesheet type="text/xsl" href="%s/%s"?>\n' % \ (static_location, self.XSLT_NAME) ) output.write('<!DOCTYPE graphtool-data>\n') gen.startElement('graphtool', {}) gen.characters("\n\t") gen.startElement('attr', {'name': 'static_base_url'}) gen.characters(static_location) gen.endElement('attr') gen.characters("\n\t") gen.startElement('html_title', {}) gen.characters(html_title) gen.endElement('html_title') gen.characters("\n\t") return gen
def render(self, data, namespaces=None): namespaces = namespaces or [] stream = BytesIO() xml = XMLGenerator(stream, encoding='utf-8') xml.startDocument() if isinstance(data, (list, tuple)): raise RenderError('Renderer of iterables is not supported') keys = list(data.keys()) if len(keys) != 1: raise RenderError('`data` should have only one key, the root') root_element = keys[0] attrs = {'xmlns:' + ns: url for ns, url in namespaces} xml.startElement(root_element, attrs) self._to_xml(xml, data[root_element]) xml.endElement(root_element) xml.endDocument() return stream.getvalue()
class SeqXmlWriter(SequentialSequenceWriter): """Writes SeqRecords into seqXML file. SeqXML requires the sequence alphabet be explicitly RNA, DNA or protein, i.e. an instance or subclass of Bio.Alphapet.RNAAlphabet, Bio.Alphapet.DNAAlphabet or Bio.Alphapet.ProteinAlphabet. """ def __init__(self, handle, source=None, source_version=None, species=None, ncbiTaxId=None): """Create Object and start the xml generator.""" SequentialSequenceWriter.__init__(self, handle) self.xml_generator = XMLGenerator(handle, "utf-8") self.xml_generator.startDocument() self.source = source self.source_version = source_version self.species = species self.ncbiTaxId = ncbiTaxId def write_header(self): """Write root node with document metadata.""" SequentialSequenceWriter.write_header(self) attrs = { "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "xsi:noNamespaceSchemaLocation": "http://www.seqxml.org/0.4/seqxml.xsd", "seqXMLversion": "0.4" } if self.source is not None: attrs["source"] = self.source if self.source_version is not None: attrs["sourceVersion"] = self.source_version if self.species is not None: if not isinstance(self.species, basestring): raise TypeError("species should be of type string") attrs["speciesName"] = self.species if self.ncbiTaxId is not None: if not isinstance(self.ncbiTaxId, (basestring, int)): raise TypeError("ncbiTaxID should be of type string or int") attrs["ncbiTaxID"] = self.ncbiTaxId self.xml_generator.startElement("seqXML", AttributesImpl(attrs)) def write_record(self, record): """Write one record.""" if not record.id or record.id == "<unknown id>": raise ValueError("SeqXML requires identifier") if not isinstance(record.id, basestring): raise TypeError("Identifier should be of type string") attrb = {"id": record.id} if "source" in record.annotations and self.source != record.annotations[ "source"]: if not isinstance(record.annotations["source"], basestring): raise TypeError("source should be of type string") attrb["source"] = record.annotations["source"] self.xml_generator.startElement("entry", AttributesImpl(attrb)) self._write_species(record) self._write_description(record) self._write_seq(record) self._write_dbxrefs(record) self._write_properties(record) self.xml_generator.endElement("entry") def write_footer(self): """Close the root node and finish the XML document.""" SequentialSequenceWriter.write_footer(self) self.xml_generator.endElement("seqXML") self.xml_generator.endDocument() def _write_species(self, record): """Write the species if given.""" local_ncbi_taxid = None if "ncbi_taxid" in record.annotations: local_ncbi_taxid = record.annotations["ncbi_taxid"] if isinstance(local_ncbi_taxid, list): # SwissProt parser uses a list (which could cope with chimeras) if len(local_ncbi_taxid) == 1: local_ncbi_taxid = local_ncbi_taxid[0] elif len(local_ncbi_taxid) == 0: local_ncbi_taxid = None else: ValueError( 'Multiple entries for record.annotations["ncbi_taxid"], %r' % local_ncbi_taxid) if "organism" in record.annotations and local_ncbi_taxid: local_org = record.annotations["organism"] if not isinstance(local_org, basestring): raise TypeError("organism should be of type string") if not isinstance(local_ncbi_taxid, (basestring, int)): raise TypeError("ncbiTaxID should be of type string or int") # The local species definition is only written if it differs from the global species definition if local_org != self.species or local_ncbi_taxid != self.ncbiTaxId: attr = {"name": local_org, "ncbiTaxID": local_ncbi_taxid} self.xml_generator.startElement("species", AttributesImpl(attr)) self.xml_generator.endElement("species") def _write_description(self, record): """Write the description if given.""" if record.description: if not isinstance(record.description, basestring): raise TypeError("Description should be of type string") description = record.description if description == "<unknown description>": description = "" if len(record.description) > 0: self.xml_generator.startElement("description", AttributesImpl({})) self.xml_generator.characters(description) self.xml_generator.endElement("description") def _write_seq(self, record): """Write the sequence. Note that SeqXML requires a DNA, RNA or protein alphabet. """ if isinstance(record.seq, UnknownSeq): raise TypeError( "Sequence type is UnknownSeq but SeqXML requires sequence") seq = str(record.seq) if not len(seq) > 0: raise ValueError("The sequence length should be greater than 0") # Get the base alphabet (underneath any Gapped or StopCodon encoding) alpha = Alphabet._get_base_alphabet(record.seq.alphabet) if isinstance(alpha, Alphabet.RNAAlphabet): seqElem = "RNAseq" elif isinstance(alpha, Alphabet.DNAAlphabet): seqElem = "DNAseq" elif isinstance(alpha, Alphabet.ProteinAlphabet): seqElem = "AAseq" else: raise ValueError("Need a DNA, RNA or Protein alphabet") self.xml_generator.startElement(seqElem, AttributesImpl({})) self.xml_generator.characters(seq) self.xml_generator.endElement(seqElem) def _write_dbxrefs(self, record): """Write all database cross references.""" if record.dbxrefs is not None: for dbxref in record.dbxrefs: if not isinstance(dbxref, basestring): raise TypeError("dbxrefs should be of type list of string") if dbxref.find(':') < 1: raise ValueError( "dbxrefs should be in the form ['source:id', 'source:id' ]" ) dbsource, dbid = dbxref.split(':', 1) attr = {"source": dbsource, "id": dbid} self.xml_generator.startElement("DBRef", AttributesImpl(attr)) self.xml_generator.endElement("DBRef") def _write_properties(self, record): """Write all annotations that are key value pairs with values of a primitive type or list of primitive types.""" for key, value in record.annotations.items(): if key not in ("organism", "ncbi_taxid", "source"): if value is None: attr = {"name": key} self.xml_generator.startElement("property", AttributesImpl(attr)) self.xml_generator.endElement("property") elif isinstance(value, list): for v in value: if isinstance(value, (int, float, basestring)): attr = {"name": key, "value": v} self.xml_generator.startElement( "property", AttributesImpl(attr)) self.xml_generator.endElement("property") elif isinstance(value, (int, float, basestring)): attr = {"name": key, "value": str(value)} self.xml_generator.startElement("property", AttributesImpl(attr)) self.xml_generator.endElement("property")
class GrafRenderer(object): """ Renders a GrAF XML representation that can be read back by an instance of L{GraphParser}. Version: 1.0. """ def __init__(self, out, constants=Constants): """Create an instance of a GrafRenderer. """ out = out if hasattr(out, 'write') else open(out, "w") # TODO: use a generator with indents try: # For Python >= 3.2 self._gen = XMLGenerator(out, 'utf-8', short_empty_elements=True) except TypeError: self._gen = XMLGenerator(out, 'utf-8') self._g = Constants def _tag(self, tag, attribs=None): return TagWriter(self._gen, self._g.NAMESPACE, tag, attribs) def render_node(self, n): """ Used to render the node elements of the Graph. """ tag = self._tag(self._g.NODE, { self._g.ID: n.id, self._g.ROOT: 'true' if n.is_root else None, }) with tag: for link in n.links: self.render_link(link) for a in n.annotations: self.render_ann(a) def render_link(self, link): """ Used to render the link elements of the Graph. """ self._tag(self._g.LINK, { 'targets': ' '.join(str(region.id) for region in link) }).write() def render_region(self, region): """ Used to render the region elements of the Graph. """ self._tag( self._g.REGION, { self._g.ID: region.id, self._g.ANCHORS: ' '.join(str(a) for a in region.anchors) }).write() def render_edge(self, e): """ Used to render the edge elements of the Graph. """ with self._tag(self._g.EDGE, { self._g.FROM: e.from_node.id, self._g.TO: e.to_node.id }): for a in e.annotations: self.render_ann(a) def render_as(self, aSet): """ Used to render the annotation set elements of the Graph. """ with self._tag(self._g.ASET, {self._g.NAME: aSet.name}): for a in aSet: self.render_ann(a) def render_ann(self, a): """ Used to render the annotation elements of the Graph. """ tag = self._tag( self._g.ANNOTATION, { 'label': a.label, 'ref': a.element.id, self._g.ASET: None if a.aspace is None else a.aspace.name }) with tag: self.render_fs(a.features) def render_fs(self, fs): """ Used to render the feature structure elements of the Graph. """ if not fs: return with self._tag(self._g.FS, {self._g.TYPE: fs.type}): for name, value in fs.items(): self.render_feature(name, value) def render_feature(self, name, value): """ Used to render the features elements of the Graph. """ if hasattr(value, 'items'): with self._tag(self._g.FEATURE, {self._g.NAME: name}): self.render_fs(value) else: self._tag(self._g.FEATURE, { self._g.NAME: name, self._g.VALUE: value }).write() def write_header(self, g): """ Writes the header tag at the beginning of the XML file. """ header = g.header with self._tag(self._g.HEADER): self.render_tag_usage(g) self.write_header_elements(graph, header) def write_header_elements(self, graph, header): """ Helper method for write_header. """ roots = header.roots if roots: with self._tag(self._g.ROOTS): for root in roots: self._tag(self._g.ROOT).write() depends_on = header.depends_on if depends_on: with self._tag(self._g.ROOTS): for dependency in depends_on: self._tag(self._g.DEPENDSON, { self._g.TYPE: dependency }).write() aspaces = graph.annotation_spaces if aspaces: with self._tag(self._g.ANNOTATION_SPACES): for aspace in aspaces: self._tag(self._g.ANNOTATION_SPACE, { self._g.NAME: aspace.name, self._g.TYPE: aspace.type }).write() def count_tag_usage(self, g): annotations = {} for node in g.nodes: for a in node.annotations: count = annotations.setdefault(a.label, 0) annotations[a.label] = count + 1 return annotations def render_tag_usage(self, g): annotations = self.count_tag_usage(g) with self._tag(self._g.TAGSDECL): for k, v in annotations.items(): self._tag(self._g.TAGUSAGE, { self._g.GI: str(k), self._g.OCCURS: str(v) }).write() def render(self, g): self._gen.startDocument() self._gen.startPrefixMapping(None, self._g.NAMESPACE) with self._tag(self._g.GRAPH): self.write_header(g) # Add any features of the graph if g.features is not None: self.render_fs(g.features) # Render the regions for region in sorted(g.regions): self.render_region(region) # Render the nodes nodes = sorted(g.nodes) for node in nodes: self.render_node(node) # Render the edges for edge in g.edges: self.render_edge(edge)
class Renderer(base.Renderer): def __init__( self, size, units, unitmult=1, *, margin=0, down=+1, # -1 if y axis points upwards line=None, textsize=10, textbottom=False, colour=None): self.textsize = textsize width = size[0] + 2 * margin height = size[1] + 2 * margin if down < 0: top = -size[1] self.flip = (+1, -1) else: top = 0 self.flip = (+1, +1) viewbox = "{},{} {},{}".format(-margin, top - margin, width, height) self.xml = XMLGenerator(encoding=stdout.encoding, short_empty_elements=True) self.xml.startDocument() attrs = { "xmlns": "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", "width": "{}{}".format(width * unitmult, units), "height": "{}{}".format(height * unitmult, units), "viewBox": viewbox, } if line is None: self.linewidth = 1 else: attrs["stroke-width"] = format(line) self.linewidth = line attrs.update(self._colour(colour)) self.xml.startElement("svg", attrs) text = list() if textbottom: text.append("dominant-baseline: text-after-edge") text.append("fill: currentColor") self.rulesets = [ (".outline, path, line, polyline", ("stroke: currentColor", "fill: none")), (".solid", ("fill: currentColor", "stroke: none")), ("text", text), ] self.fonts = dict() def addfont(self, id, size, family, *, italic=False, bold=False, underline=False): props = [ "font-size: {}px".format(size), "font-family: {}".format(family), ] if italic: props.append("font-style: italic") if bold: props.append("font-weight: bold") if underline: props.append("text-decoration: underline") self.fonts["." + id] = props def setdefaultfont(self, id): id = "." + id self.fonts["text, " + id] = self.fonts.pop(id) def start(self): self.rulesets.extend(self.fonts.items()) css = list() for (selector, rules) in self.rulesets: rules = "".join(map(" {};\n".format, rules)) css.append("{} {{\n{}}}\n".format(selector, rules)) self.tree(("style", dict(type="text/css"), css)) def finish(self): self.xml.endElement("svg") self.xml.endDocument() def line(self, a, b=None, *pos, **kw): attrs = dict() if b: points = (a, b) else: points = (a, ) for (n, p) in enumerate(points, 1 + 2 - len(points)): (x, y) = p attrs["x{}".format(n)] = format(x) attrs["y{}".format(n)] = format(y * self.flip[1]) self._line(attrs, *pos, **kw) def hline(self, a, b=None, *, width=None, offset=None, colour=None): a = format(a) if b is None: attrs = {"x2": a} else: attrs = {"x1": a, "x2": format(b)} self._line(attrs, width=width, offset=offset, colour=colour) def vline(self, a, b=None, *pos, **kw): a = format(a * self.flip[1]) if b is None: attrs = {"y2": a} else: attrs = {"y1": a, "y2": format(b * self.flip[1])} self._line(attrs, *pos, **kw) def _line(self, attrs, *, offset=None, width=None, colour=None): self._width(attrs, width) attrs.update(self._colour(colour)) transform = self._offset(offset) self.emptyelement("line", attrs, transform=transform) def polyline(self, points, *, width=None, colour=None): s = list() for (x, y) in points: s.append("{},{}".format(x, y * self.flip[1])) attrs = {"points": " ".join(s)} self._width(attrs, width) attrs.update(self._colour(colour)) self.emptyelement("polyline", attrs) def cubicbezier(self, a, b, c, d, *, offset=None, colour=None, width=None): attrs = dict(self._colour(colour)) s = list() for p in (a, b, c, d): s.append("{},{}".format(*map(operator.mul, p, self.flip))) attrs["d"] = "M{} C {} {} {}".format(*s) self._width(attrs, width) self.emptyelement("path", attrs, transform=self._offset(offset)) def ellipse(self, r, offset=None, *, outline=None, fill=None, width=None): [rx, ry] = r attrs = {"rx": format(rx), "ry": format(ry)} style = list() self._closed(attrs, style, outline, fill, width) if offset: (x, y) = offset attrs["cx"] = format(x) attrs["cy"] = format(y * self.flip[1]) self.emptyelement("ellipse", attrs, style=style) def polygon(self, points, *, offset=None, rotate=None, outline=None, fill=None, width=None): s = list() for (x, y) in points: s.append("{},{}".format(x, y * self.flip[1])) attrs = {"points": " ".join(s)} style = list() transform = self._offset(offset) if rotate is not None: transform.append("rotate({})".format(rotate)) self._closed(attrs, style, outline, fill, width) self.emptyelement("polygon", attrs, style=style, transform=transform) def rectangle(self, a, b=None, *, offset=None, rotate=None, outline=None, fill=None, width=None, _attrs=()): """ rectangle(a) -> <rect width=a /> rectangle(a, b) -> <rect x=a width=(b - a) /> Offset implemented independently using transform="translate(offset)" """ attrs = dict(_attrs) style = list() transform = self._offset(offset) if rotate is not None: transform.append("rotate({})".format(rotate)) if b: (x, y) = a attrs["x"] = format(x) attrs["y"] = format(y * self.flip[1]) (bx, by) = b w = bx - x h = by - y else: (w, h) = a h *= self.flip[1] # Compensate for SVG not allowing negative dimensions translate = dict() if w < 0: translate["x"] = format(w) w = -w if h < 0: translate["y"] = format(h) h = -h if translate: if b: # x and y attributes already used for a, so use a transform x = translate.get("x", 0) y = translate.get("y", 0) transform.append("translate({}, {})".format(x, y)) else: attrs.update(translate) attrs["width"] = format(w) attrs["height"] = format(h) self._closed(attrs, style, outline, fill, width) self.emptyelement("rect", attrs, style=style, transform=transform) def roundrect(self, r, *pos, **kw): (x, y) = r attrs = {"rx": format(x), "ry": format(y)} return self.rectangle(*pos, _attrs=attrs, **kw) def _closed(self, attrs, style, outline=None, fill=None, width=None): if fill and (not outline or isinstance(outline, Iterable) or \ not isinstance(fill, Iterable)): attrs["class"] = "solid" else: attrs["class"] = "outline" if isinstance(fill, Iterable): style.extend(self._colour(fill, "fill")) if isinstance(outline, Iterable): style.extend(self._colour(outline, "stroke")) self._width(attrs, width) def _width(self, attrs, width=None): if width is not None: attrs["stroke-width"] = format(width) def arc(self, r, start, end, offset=None, *, colour=None, width=None): if abs(end - start) >= 360: return self.ellipse(r, offset, outline=colour, width=width) a = list() d = list() for x in range(2): sincos = (cos, sin)[x] da = sincos(radians(start)) db = sincos(radians(end)) a.append(format(da * r[x] * self.flip[x])) d.append(format((db - da) * r[x] * self.flip[x])) large = (end - start) % 360 > 180 at = dict(self._colour(colour)) at["d"] = "M{a} a{r} 0 {large:d},0 {d}".format( a=",".join(a), r=",".join(map(format, r)), large=large, d=",".join(d), ) self._width(at, width) self.emptyelement("path", at, transform=self._offset(offset)) def text(self, text, offset=None, horiz=None, vert=None, *, angle=None, font=None, colour=None, width=None): attrs = dict() style = list() transform = list() if vert is not None: baselines = { self.CENTRE: "central", self.TOP: "text-before-edge", self.BOTTOM: "text-after-edge", } style.append(("dominant-baseline", baselines[vert])) if horiz is not None: anchors = { self.CENTRE: "middle", self.LEFT: "start", self.RIGHT: "end", } style.append(("text-anchor", anchors[horiz])) transform.extend(self._offset(offset)) if angle is not None: transform.append("rotate({})".format(angle * self.flip[1])) if font is not None: attrs["class"] = font attrs.update(self._colour(colour)) with self.element("text", attrs, style=style, transform=transform): if width is None: if isinstance(text, str): self.xml.characters(text) else: for seg in text: attrs = dict() if seg.get("overline"): attrs["text-decoration"] = "overline" self.tree(("tspan", attrs, (seg["text"], ))) return # Very hacky approximation of the size of each character # as one en wide width /= self.textsize / 2 wrapper = TextWrapper(width=width, replace_whitespace=False) hardlines = text.splitlines(keepends=True) if not hardlines: hardlines.append("") line = 0 for hardline in hardlines: wrapped = wrapper.wrap(hardline) if not wrapped: # Caused by empty string wrapped.append("") for softline in wrapped: lineattrs = { "x": "0", "y": "{}em".format(line / 0.875), "xml:space": "preserve", } self.tree(("tspan", lineattrs, (softline, ))) line += 1 def image(self, a, b=None, *, file=None, data=None, offset=None): """ image(a) -> <image width=a /> image(a, b) -> <rect x=a width=(b - a) /> Offset implemented independently using transform="translate(offset)" """ if data is None: with open(file, "rb") as file: data = file.read() data = "data:image/bmp;base64," + b64encode(data).decode("ascii") attrs = {"xlink:href": data} if b: (x, y) = a attrs["x"] = format(x) (bx, by) = b w = bx - x h = by - y if self.flip[1] < 0: y = -by attrs["y"] = format(y) else: (w, h) = a attrs["width"] = format(w) attrs["height"] = format(h) self.emptyelement("image", attrs, transform=self._offset(offset)) def addobjects(self, objects): with self.element("defs"): for d in objects: with self.element("g", dict(id=d.__name__)): d(self) def draw(self, object, offset=None, *, rotate=None, colour=None): attrs = {"xlink:href": _buildurl(fragment=object.__name__)} transform = None if rotate is not None: transform = self._offset(offset) transform.append("rotate({})".format(rotate * 90 * self.flip[1])) elif offset: (x, y) = offset attrs["x"] = format(x) attrs["y"] = format(y * self.flip[1]) attrs.update(self._colour(colour)) self.emptyelement("use", attrs, transform=transform) @contextmanager def view(self, *, offset=None, rotate=None, colour=None): transform = self._offset(offset) if rotate is not None: transform.append("rotate({})".format(rotate * self.flip[1] * 90)) attrs = dict(self._colour(colour)) with self.element("g", attrs, transform=transform): yield self def _offset(self, offset=None): if offset: (x, y) = offset y *= self.flip[1] return [("translate({}, {})".format(x, y))] else: return [] def _colour(self, colour=None, attr="color"): if colour: colour = (min(int(x * 0x100), 0xFF) for x in colour) return ((attr, "#" + "".join(map("{:02X}".format, colour))), ) else: return () @contextmanager def element(self, name, attrs=(), style=None, transform=None): attrs = dict(attrs) if style: attrs["style"] = "; ".join("{}: {}".format(*s) for s in style) if transform: attrs["transform"] = " ".join(transform) self.xml.startElement(name, attrs) yield self.xml.endElement(name) def emptyelement(self, *pos, **kw): with self.element(*pos, **kw): pass def tree(self, *elements): for e in elements: if isinstance(e, str): self.xml.characters(e) else: (name, attrs, children) = e with self.element(name, attrs): self.tree(*children)
class XmlItemExporter(BaseItemExporter): def __init__(self, file, **kwargs): self.item_element = kwargs.pop('item_element', 'item') self.root_element = kwargs.pop('root_element', 'items') self._configure(kwargs) if not self.encoding: self.encoding = 'utf-8' self.xg = XMLGenerator(file, encoding=self.encoding) def _beautify_newline(self, new_item=False): if self.indent is not None and (self.indent > 0 or new_item): self._xg_characters('\n') def _beautify_indent(self, depth=1): if self.indent: self._xg_characters(' ' * self.indent * depth) def start_exporting(self): self.xg.startDocument() self.xg.startElement(self.root_element, {}) self._beautify_newline(new_item=True) def export_item(self, item): self._beautify_indent(depth=1) self.xg.startElement(self.item_element, {}) self._beautify_newline() for name, value in self._get_serialized_fields(item, default_value=''): self._export_xml_field(name, value, depth=2) self._beautify_indent(depth=1) self.xg.endElement(self.item_element) self._beautify_newline(new_item=True) def finish_exporting(self): self.xg.endElement(self.root_element) self.xg.endDocument() def _export_xml_field(self, name, serialized_value, depth): self._beautify_indent(depth=depth) self.xg.startElement(name, {}) if hasattr(serialized_value, 'items'): self._beautify_newline() for subname, value in serialized_value.items(): self._export_xml_field(subname, value, depth=depth + 1) self._beautify_indent(depth=depth) elif is_listlike(serialized_value): self._beautify_newline() for value in serialized_value: self._export_xml_field('value', value, depth=depth + 1) self._beautify_indent(depth=depth) elif isinstance(serialized_value, six.text_type): self._xg_characters(serialized_value) else: self._xg_characters(str(serialized_value)) self.xg.endElement(name) self._beautify_newline() # Workaround for https://bugs.python.org/issue17606 # Before Python 2.7.4 xml.sax.saxutils required bytes; # since 2.7.4 it requires unicode. The bug is likely to be # fixed in 2.7.6, but 2.7.6 will still support unicode, # and Python 3.x will require unicode, so ">= 2.7.4" should be fine. if sys.version_info[:3] >= (2, 7, 4): def _xg_characters(self, serialized_value): if not isinstance(serialized_value, six.text_type): serialized_value = serialized_value.decode(self.encoding) return self.xg.characters(serialized_value) else: # pragma: no cover def _xg_characters(self, serialized_value): return self.xg.characters(serialized_value)
elif result.eofs == 'E': errors = 1 else: errors = 1 filename = os.path.join(self.outdir, '%s.xml' % (result.case.uid,)) dirname = os.path.dirname(filename) try: os.makedirs(dirname) except OSError, ex: if ex.errno != errno.EEXIST: raise f_report = open(filename, 'w') try: xml = XMLGenerator(f_report, encoding='utf-8') xml.startDocument() xml.startElement('testsuite', { 'name': encode(result.case.description or result.case.uid), 'tests': '%d' % (1,), 'failures': '%d' % (failures,), 'errors': '%d' % (errors,), 'time': '%0.3f' % (result.duration / 1000.0,), 'disabled': '%d' % (disabled,), 'skipped': '%d' % (skipped,), 'timestamp': self.now.isoformat(), 'hostname': os.uname()[1], 'id': result.case.uid, 'package': self.section, }) xml.startElement('properties', {})
class Logger: def __init__(self) -> None: self.logfile = os.environ.get("LOGFILE", "/dev/null") self.logfile_handle = open(self.logfile, "wb") self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8") self.queue: "Queue[Dict[str, str]]" = Queue(1000) self.xml.startDocument() self.xml.startElement("logfile", attrs={}) def close(self) -> None: self.xml.endElement("logfile") self.xml.endDocument() self.logfile_handle.close() def sanitise(self, message: str) -> str: return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C") def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str: if "machine" in attributes: return "{}: {}".format(attributes["machine"], message) return message def log_line(self, message: str, attributes: Dict[str, str]) -> None: self.xml.startElement("line", attributes) self.xml.characters(message) self.xml.endElement("line") def log(self, message: str, attributes: Dict[str, str] = {}) -> None: eprint(self.maybe_prefix(message, attributes)) self.drain_log_queue() self.log_line(message, attributes) def enqueue(self, message: Dict[str, str]) -> None: self.queue.put(message) def drain_log_queue(self) -> None: try: while True: item = self.queue.get_nowait() attributes = {"machine": item["machine"], "type": "serial"} self.log_line(self.sanitise(item["msg"]), attributes) except Empty: pass @contextmanager def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]: eprint(self.maybe_prefix(message, attributes)) self.xml.startElement("nest", attrs={}) self.xml.startElement("head", attributes) self.xml.characters(message) self.xml.endElement("head") tic = time.time() self.drain_log_queue() yield self.drain_log_queue() toc = time.time() self.log("({:.2f} seconds)".format(toc - tic)) self.xml.endElement("nest")
class XmlAnnotationWriter: def __init__(self, file): self.version = "1.1" self.file = file self.xmlgen = XMLGenerator(self.file, 'utf-8') self._level = 0 def _indent(self, newline=True): if newline: self.xmlgen.ignorableWhitespace("\n") self.xmlgen.ignorableWhitespace(" " * self._level) def _add_version(self): self._indent() self.xmlgen.startElement("version", {}) self.xmlgen.characters(self.version) self.xmlgen.endElement("version") def open_root(self): self.xmlgen.startDocument() self.xmlgen.startElement("annotations", {}) self._level += 1 self._add_version() def _add_meta(self, meta): self._level += 1 for k, v in meta.items(): if isinstance(v, OrderedDict): self._indent() self.xmlgen.startElement(k, {}) self._add_meta(v) self._indent() self.xmlgen.endElement(k) elif isinstance(v, list): self._indent() self.xmlgen.startElement(k, {}) for tup in v: self._add_meta(OrderedDict([tup])) self._indent() self.xmlgen.endElement(k) else: self._indent() self.xmlgen.startElement(k, {}) self.xmlgen.characters(v) self.xmlgen.endElement(k) self._level -= 1 def add_meta(self, meta): self._indent() self.xmlgen.startElement("meta", {}) self._add_meta(meta) self._indent() self.xmlgen.endElement("meta") def open_track(self, track): self._indent() self.xmlgen.startElement("track", track) self._level += 1 def open_image(self, image): self._indent() self.xmlgen.startElement("image", image) self._level += 1 def open_box(self, box): self._indent() self.xmlgen.startElement("box", box) self._level += 1 def open_polygon(self, polygon): self._indent() self.xmlgen.startElement("polygon", polygon) self._level += 1 def open_polyline(self, polyline): self._indent() self.xmlgen.startElement("polyline", polyline) self._level += 1 def open_points(self, points): self._indent() self.xmlgen.startElement("points", points) self._level += 1 def open_cuboid(self, cuboid): self._indent() self.xmlgen.startElement("cuboid", cuboid) self._level += 1 def open_tag(self, tag): self._indent() self.xmlgen.startElement("tag", tag) self._level += 1 def add_attribute(self, attribute): self._indent() self.xmlgen.startElement("attribute", {"name": attribute["name"]}) self.xmlgen.characters(attribute["value"]) self.xmlgen.endElement("attribute") def close_box(self): self._level -= 1 self._indent() self.xmlgen.endElement("box") def close_polygon(self): self._level -= 1 self._indent() self.xmlgen.endElement("polygon") def close_polyline(self): self._level -= 1 self._indent() self.xmlgen.endElement("polyline") def close_points(self): self._level -= 1 self._indent() self.xmlgen.endElement("points") def close_cuboid(self): self._level -= 1 self._indent() self.xmlgen.endElement("cuboid") def close_tag(self): self._level -= 1 self._indent() self.xmlgen.endElement("tag") def close_image(self): self._level -= 1 self._indent() self.xmlgen.endElement("image") def close_track(self): self._level -= 1 self._indent() self.xmlgen.endElement("track") def close_root(self): self._level -= 1 self._indent() self.xmlgen.endElement("annotations") self.xmlgen.endDocument()
class ClipExtractor(ContentHandler): def __init__(self, output, clipId): self._sink = XMLGenerator(output, 'UTF-8', True) self._locator = None self._id = clipId def setDocumentLocator(self, locator): self._locator = locator self._skip = None self._stopAt = None return self._sink.setDocumentLocator(locator) def startDocument(self): # self._prefixes = {} self.scale = self.units = None self._context = [] self._outerSvgRendered = False return self._sink.startDocument() def endDocument(self): # self._prefixes.clear() return self._sink.endDocument() def startPrefixMapping(self, prefix, uri): self._context.append(('xmlns', None, prefix, uri)) # mappings = self._prefixes.get(prefix) # if mappings is None: # self._prefixes[prefix] = mappings = [] # mappings.append(uri) return self._sink.startPrefixMapping(prefix, uri) def endPrefixMapping(self, prefix): context = self._context.pop() assert ('xmlns', None, prefix) == context[:-1] # mappings = self._prefixes.get(prefix) # assert mappings is not None # mappings.pop() return self._sink.endPrefixMapping(prefix) def startElement(self, qname, attrs): raise xml.sax.SAXNotSupportedException( 'This handler must be used with feature "%s"' ' turned on' % xml.sax.handler.feature_namespaces) # if 'xmlns' in attrs: # if self._context: # raise xml.sax.SAXNotSupportedException( # 'This document must be parsed with feature "%s"' # ' turned on' # % xml.sax.handler.feature_namespaces # ) # else: # self.startPrefixMapping('', attrs.get('xmlns')) # ns, name = self._splitNS(qname) # handler = self.ELEMENTS.get((ns, name)) # if handler and handler[0]: # update = handler[0](self, attrs, ns, name) # if not update: # if self._skip is None: # self._skip = len(self._context) + 1 # elif isinstance(update, collections.Sequence): # attrs = update[0] # if len(update) > 1: # ns, name, qname = update[1:] # self._context.append((ns, name, qname, attrs.copy())) # if self._skip is None: # return self._sink.startElement(qname, attrs) def endElement(self, qname): raise xml.sax.SAXNotSupportedException( 'This handler must be used with feature "%s"' ' turned on' % xml.sax.handler.feature_namespaces) # ns, name = self._splitNS(qname) # handler = self.ELEMENTS.get((ns, name)) # if handler and handler[1]: # handler[1](self, ns, name) # context = self._context.pop() # assert (ns, name) == context[:2] # if self._skip is None: # self._sink.endElement(qname) # elif len(self._context) < self._skip: # self._skip = None # if len(self._context) == self._stopAt: # raise self.Done('extraction complete', # self._locator.getLineNumber(), # self._locator.getColumnNumber() # ) def startElementNS(self, name, qname, attrs): if (None, 'xmlns') in attrs: self.startPrefixMapping(None, attrs.get('xmlns')) handler = self.ELEMENTS.get(name) if handler and handler[0]: update = handler[0](self, attrs, *name, qname) if not update: if self._skip is None: self._skip = len(self._context) + 1 elif isinstance(update, collections.Sequence): attrs = update[0] if len(update) > 1: name = tuple(update[1:3]) if len(update) > 3: qname = update[3] self._context.append(name + (qname, attrs.copy())) if self._skip is None: return self._sink.startElementNS(name, qname, attrs) def endElementNS(self, name, qname): handler = self.ELEMENTS.get(name) if handler and handler[1]: handler[1](self, *name, qname) context = self._context.pop() assert name == context[:2] if self._skip is None: self._sink.endElementNS(name, qname) elif len(self._context) < self._skip: self._skip = None if len(self._context) == self._stopAt: while self._context: toClose = self._context.pop() if 'xmlns' == toClose[0]: self._sink.endPrefixMapping(toClose[2]) else: self._sink.ignorableWhitespace('\n') self._sink.endElementNS(toClose[:2], toClose[2]) self._sink.endDocument() raise self.Done('extraction complete', (self._locator.getLineNumber(), self._locator.getColumnNumber())) def elementSvgEnd(self, *args): attrs = self._context[-1][3] if self.ATTR_ID in attrs and \ self._id == attrs.get(self.ATTR_ID): self._stopAt = len(self._context) - 1 def elementSvgStart(self, attrs, *args): if any((CardBackView.SVG_NAMESPACE, 'svg') == e[:2] for e in self._context): return self.ATTR_ID in attrs and \ self._id == attrs.get(self.ATTR_ID) elif not 'viewBox' in attrs and not (None, 'viewBox') in attrs: self._error(None, 'Main <svg> element has no viewBox attribute') else: try: internalSize = attrs.get((None, 'viewBox')) if internalSize is None: internalSize = attrs.get('viewBox') internalSize = self.parseBox(internalSize)[2:] externalSize = list(internalSize) units = [''] * 2 i = -1 for attr in CardBackView.ATTRS_SVG_DIMENSION: i += 1 value, unit = self._distanceAttr(attrs, attr) if unit.strip() == '%': value = None if value is not None: externalSize[i] = value units[i] = unit self.units = tuple(units) try: self.scale = tuple( e / i for e, i in zip(externalSize, internalSize)) except ZeroDivisionError as error: self._error( None, 'Found <svg> with zero dimension(s), viewBox="%s"' % attrs.get((None, 'viewBox'))) return False except: self._error() def elementUseStart(self, attrs, ns, name, qname): target = attrs.get(CardBackView.XLINK_HREF_ATTR) if not target: return False target = target.strip() if '#' == target[0] and self._id == target[1:] \ and not self._outerSvgRendered: try: outerSvg = next(e for e in self._context if (CardBackView.SVG_NAMESPACE, 'svg') == e[:2]) except StopIteration: self._error(None, 'Found <use> element outside of an <svg>') size = [] for attr in CardBackView.ATTRS_SVG_DIMENSION: value, unit = self._distanceAttr(attrs, attr) if unit.strip(): self._error( None, 'Attribute <use %s="%s" ...> is not valid' ' in this context, expected a unit-free number.' % (attr, attrs.get(None, attr))) if value is None: self._error( None, 'Attribute `%s` is missing from <use> element,' ' but is expected in this context.' % attr) size.append(value) sattrs = ('%.6f%s' % (s * v, u) for s, v, u in zip(self.scale, size, self.units)) qnames = { name: outerSvg[3].getQNameByName(name) for name in outerSvg[3].getNames() } attrMap = dict(outerSvg[3].items()) attrMap[(None, 'viewBox')] = self.boxValue((0, 0) + tuple(size)) for attr in zip(CardBackView.ATTRS_SVG_DIMENSION, sattrs): attrMap[(None, attr[0])] = attr[1] self._sink.startElementNS(outerSvg[:2], outerSvg[2], AttributesNSImpl(attrMap, qnames)) self._sink.ignorableWhitespace('\n') self._outerSvgRendered = True qnames = { name: attrs.getQNameByName(name) for name in attrs.getNames() } attrMap = dict(attrs.items()) for attr in ('x', 'y') + CardBackView.ATTRS_SVG_DIMENSION: qnames.pop((None, attr), None) attrMap.pop((None, attr), None) self._sink.startElementNS((ns, name), qname, AttributesNSImpl(attrMap, qnames)) self._sink.endElementNS((ns, name), qname) self._sink.ignorableWhitespace('\n') return False def elementDefsStart(self, attrs, *args): if not self._outerSvgRendered: self._error( None, 'Element <use xlink:href="#%s" ...> must precede' ' the <defs> element in this context.' % self._id) self._skip = None return True ATTR_ID = (None, 'id') ELEMENTS = { (CardBackView.SVG_NAMESPACE, 'svg'): (elementSvgStart, elementSvgEnd), (CardBackView.SVG_NAMESPACE, 'use'): (elementUseStart, None), (CardBackView.SVG_NAMESPACE, 'defs'): (elementDefsStart, None), } def characters(self, content): if self._skip is None: return self._sink.characters(content) def ignorableWhitespace(self, whitespace): if self._skip is None: return self._sink.ignorableWhitespace(whitespace) def processingInstruction(self, target, data): if self._skip is None: return self._sink.processingInstruction(target, data) def skippedEntity(self, name): if self._skip is None: return self._sink.skippedEntity(name) def _error(self, error=True, message=''): if error == True: error = sys.exc_info()[1] if error is None: assert message error = SAXParseException(message, None, self._locator) elif not isinstance(error, SAXParseException): msg = error.args[0] if error.args else '' if msg: msg += ' ' if message: msg += message + ' ' error.args = (msg + 'at line %d, column %d.' % (self._locator.getLineNumber(), self._locator.getColumnNumber()), ) + error.args[1:] raise error class Done(xml.sax.SAXException): pass
def dump(obj, fp): xg = XMLGenerator(fp, 'utf-8') xg.startDocument() _write_item(xg, obj, root=True) xg.endDocument()
class Logger: def __init__(self) -> None: self.logfile = os.environ.get("LOGFILE", "/dev/null") self.logfile_handle = codecs.open(self.logfile, "wb") self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8") self.queue: "Queue[Dict[str, str]]" = Queue() self.xml.startDocument() self.xml.startElement("logfile", attrs={}) self._print_serial_logs = True @staticmethod def _eprint(*args: object, **kwargs: Any) -> None: print(*args, file=sys.stderr, **kwargs) def close(self) -> None: self.xml.endElement("logfile") self.xml.endDocument() self.logfile_handle.close() def sanitise(self, message: str) -> str: return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C") def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str: if "machine" in attributes: return "{}: {}".format(attributes["machine"], message) return message def log_line(self, message: str, attributes: Dict[str, str]) -> None: self.xml.startElement("line", attributes) self.xml.characters(message) self.xml.endElement("line") def info(self, *args, **kwargs) -> None: # type: ignore self.log(*args, **kwargs) def warning(self, *args, **kwargs) -> None: # type: ignore self.log(*args, **kwargs) def error(self, *args, **kwargs) -> None: # type: ignore self.log(*args, **kwargs) sys.exit(1) def log(self, message: str, attributes: Dict[str, str] = {}) -> None: self._eprint(self.maybe_prefix(message, attributes)) self.drain_log_queue() self.log_line(message, attributes) def log_serial(self, message: str, machine: str) -> None: self.enqueue({"msg": message, "machine": machine, "type": "serial"}) if self._print_serial_logs: self._eprint(Style.DIM + "{} # {}".format(machine, message) + Style.RESET_ALL) def enqueue(self, item: Dict[str, str]) -> None: self.queue.put(item) def drain_log_queue(self) -> None: try: while True: item = self.queue.get_nowait() msg = self.sanitise(item["msg"]) del item["msg"] self.log_line(msg, item) except Empty: pass @contextmanager def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]: self._eprint(self.maybe_prefix(message, attributes)) self.xml.startElement("nest", attrs={}) self.xml.startElement("head", attributes) self.xml.characters(message) self.xml.endElement("head") tic = time.time() self.drain_log_queue() yield self.drain_log_queue() toc = time.time() self.log("({:.2f} seconds)".format(toc - tic)) self.xml.endElement("nest")
def dump_xml(self, output_dir): """ Dumps test result to xml """ self.buffer = False if not os.path.exists(output_dir): os.makedirs(output_dir) with open(os.path.join(output_dir, 'junit.xml'), 'w') as output: document = XMLGenerator(output, 'utf-8') document.startDocument() document.startElement('testsuites', AttributesImpl({})) suites = groupby(self.testInfos, key=lambda test_info: test_info.case_name) for suite_name, suite in suites: document.startElement('testsuite', AttributesImpl({'name': suite_name})) for test_info in suite: document.startElement( 'testcase', AttributesImpl({ 'classname': suite_name, 'name': test_info.method_name, 'time': '%3f' % total_seconds(test_info.end_time - test_info.start_time) })) if test_info.result == TestInfo.RESULT.ERROR: document.startElement( 'error', AttributesImpl( {'message': smart_text(test_info.err[1])})) document.characters( self._exc_info_to_string(test_info.err, test_info)) document.endElement('error') elif test_info.result == TestInfo.RESULT.FAILURE: document.startElement( 'failure', AttributesImpl( {'message': smart_text(test_info.err[1])})) document.characters( self._exc_info_to_string(test_info.err, test_info)) document.endElement('failure') elif test_info.result == \ TestInfo.RESULT.UNEXPECTED_SUCCESS: document.startElement( 'error', AttributesImpl({'message': 'Unexpected success'})) document.endElement('error') elif test_info.result == TestInfo.RESULT.SKIPPED: document.startElement('skipped', AttributesImpl({})) document.characters(test_info.reason) document.endElement('skipped') if test_info.stdout: document.startElement('system-out', AttributesImpl({})) document.characters(test_info.stdout) document.endElement('system-out') if test_info.stderr: document.startElement('system-err', AttributesImpl({})) document.characters(test_info.stderr) document.endElement('system-err') document.endElement('testcase') document.endElement('testsuite') document.endElement('testsuites') document.endDocument()
class NmapParserSAX(ParserBasics, ContentHandler): def __init__(self): ParserBasics.__init__(self) self.id_sequence = 0 self.in_run_stats = False self.in_host = False self.in_ports = False self.in_port = False self.in_os = False self.in_trace = False # _tmp_port is used while parsing a port entity self._tmp_port = {} self.nmap_xml_file = None self.unsaved = False self.valid_xml = False def set_parser(self, parser): self.parser = parser def set_xml_file(self, nmap_xml_file): self.nmap_xml_file = nmap_xml_file def parse(self): if self.nmap_xml_file: if isinstance(self.nmap_xml_file, basestring): self.parser.parse(self.nmap_xml_file) else: self.nmap_xml_file.seek(0) self.parser.parse(self.nmap_xml_file) else: raise Exception("There's no file to be parsed!") if not self.valid_xml: raise Exception("Invalid XML file!") def generate_id(self): self.id_sequence += 1 return self.id_sequence def _parse_nmaprun(self, attrs): self.valid_xml = True d = self.nmap['nmaprun'] self.scanner = attrs.get('scanner', '') self.scanner_version = attrs.get('version', '') self.start = attrs.get('start', '') self.nmap_command = attrs.get('args', '') d['xmloutputversion'] = attrs.get('xmloutputversion', '') # Umit extension self.nmap_output = attrs.get('nmap_output', '') self.profile = attrs.get('profile', '') self.profile_name = attrs.get('profile_name', '') self.profile_hint = attrs.get('hint', '') self.profile_description = attrs.get('description', '') self.profile_annotation = attrs.get('annotation', '') self.profile_options = attrs.get('options', '') self.target = attrs.get('target', '') self.scan_name = attrs.get('scan_name', '') def _parse_runstats_finished(self, attrs): self.finish_time = attrs.get('timestr', '') self.finish_epoch_time = attrs.get('time', 0) def _parse_runstats_hosts(self, attrs): self.hosts_up = attrs.get('up', 0) self.hosts_down = attrs.get('down', 0) self.hosts_total = attrs.get('total', 0) def _parse_host(self, attrs): self.host_info = HostInfo(self.generate_id()) # Umit extension self.host_info.comment = attrs.get('comment', '') def startElement(self, name, attrs): # AttributesImplDict is used here so utils/xmldisplay.py can display # instances of AttributesImpl without any effort. attrs = AttributesImplDict(attrs) if name == 'nmaprun': self._parse_nmaprun(attrs) elif name in ('verbose', 'debugging'): getattr(self, 'set_%s' % name)(attrs.copy()) elif name in ('scaninfo', 'taskbegin', 'taskprogress', 'taskend'): self.nmap[name].append(attrs.copy()) # Parse runstats elif name == 'runstats': self.in_run_stats = True elif self.in_run_stats and name == 'finished': self._parse_runstats_finished(attrs) elif self.in_run_stats and name == 'hosts': self._parse_runstats_hosts(attrs) # Parse hosts elif name == 'host': self.in_host = True self._parse_host(attrs) elif self.in_host and name in ('status', 'times', 'smurf', 'distance', 'uptime', 'tcpsequence', 'tcptssequence', 'ipidsequence'): setattr(self.host_info, name, attrs.copy()) elif self.in_host and name in ('address', 'hostscript'): getattr(self.host_info, name).append(attrs.copy()) elif self.in_host and name == 'hostnames': self.in_hostnames = True elif self.in_host and self.in_hostnames and name == 'hostname': self.host_info.hostnames.append(attrs.copy()) # port elif self.in_host and name == 'ports': self.in_ports = True elif self.in_host and self.in_ports and name == 'extraports': # XXX extrareasons not supported yet self.host_info.extraports.append(attrs.copy()) elif self.in_host and self.in_ports and name == 'port': self.in_port = True self._tmp_port.update(attrs) elif self.in_host and self.in_ports and \ self.in_port and name in ('state', 'service'): self._tmp_port.update(attrs) # os elif self.in_host and name == 'os': self.in_os = True elif self.in_host and self.in_os and name in ('osmatch', 'osclass', 'portused', 'osfingerprint'): getattr(self.host_info, name).append(attrs.copy()) # trace elif self.in_host and name == 'trace': self.in_trace = True self.host_info.trace.update(attrs.copy()) elif self.in_trace and name == 'hop': self.host_info.trace['hop'].append(attrs.copy()) def endElement(self, name): if name == 'runstats': self.in_run_stats = False elif name == 'host': self.in_host = False self.nmap['hosts'].append(self.host_info) del self.host_info elif self.in_host and name == 'hostnames': self.in_hostnames = False elif self.in_host and name == 'ports': self.in_ports = False elif self.in_host and self.in_ports and name == 'port': self.in_port = False self.host_info.ports.append(self._tmp_port.copy()) self._tmp_port.clear() elif self.in_host and self.in_os and name == 'os': self.in_os = False elif self.in_host and name == 'trace': self.in_trace = False def write_xml(self, xml_file): xml_file = self._verify_file(xml_file) self.write_parser = XMLGenerator(xml_file) # First, start the document: self.write_parser.startDocument() # Nmaprun element: self._write_nmaprun() # Scaninfo element: self._write_scaninfo() # Verbose element: self._write_verbose() # Debugging element: self._write_debugging() # Hosts elements: self._write_hosts() # Runstats element: self._write_runstats() # End of the xml file: self.write_parser.endElement('nmaprun') self.write_parser.endDocument() def _write_runstats(self): ################## # Runstats element self.write_parser.startElement('runstats', AttributesImpl(dict())) ## Finished element self.write_parser.startElement('finished', AttributesImpl({ 'time': str(time.mktime(self.finish_epoch_time)), 'timestr': self.finish_time}) ) self.write_parser.endElement('finished') ## Hosts element self.write_parser.startElement('hosts', AttributesImpl({ 'up': str(self.hosts_up), 'down': str(self.hosts_down), 'total': str(self.hosts_total)}) ) self.write_parser.endElement('hosts') self.write_parser.endElement('runstats') # End of Runstats element ######################### def _write_hosts(self): for host in self.hosts: # Start host element self.write_parser.startElement('host', AttributesImpl({ 'comment': host.comment}) ) # Status element self.write_parser.startElement('status', AttributesImpl({ 'state': host.status['state']}) ) self.write_parser.endElement('status') ################## # Address elements for address in host.address: self.__remove_none(address) self.write_parser.startElement('address', AttributesImpl({ 'addr': address.get('addr', ''), 'vendor': address.get('vendor', ''), 'addrtype': address.get('addrtype', '')}) ) self.write_parser.endElement('address') # End of Address elements ######################### ################### # Hostnames element self.write_parser.startElement('hostnames', AttributesImpl({})) for hname in host.hostnames: if not isinstance(hname, dict): continue self.write_parser.startElement('hostname', AttributesImpl({ 'name': hname.get('name', ''), 'type': hname.get('type', '')}) ) self.write_parser.endElement('hostname') self.write_parser.endElement('hostnames') # End of Hostnames element ########################## ############### # Ports element self.write_parser.startElement('ports', AttributesImpl({})) ## Extraports elements for export in host.extraports: self.__remove_none(export) self.write_parser.startElement('extraports', AttributesImpl({ 'count': str(export.get('count', '')), 'state': export.get('state', '')}) ) self.write_parser.endElement('extraports') ## Port elements for port in host.ports: self.__remove_none(port) self.write_parser.startElement('port', AttributesImpl({ 'portid': port.get('portid', ''), 'protocol': port.get('protocol', '')}) ) ### Port state self.write_parser.startElement('state', AttributesImpl({ 'state': port.get('state', '')}) ) self.write_parser.endElement('state') ### Port service info self.write_parser.startElement('service', AttributesImpl({ 'conf': port.get('conf', ''), 'method': port.get('method', ''), 'name': port.get('name', ''), 'product': port.get('product', ''), 'version': port.get('version', ''), 'extrainfo': port.get('extrainfo', '')}) ) self.write_parser.endElement('service') self.write_parser.endElement('port') self.write_parser.endElement('ports') # End of Ports element ###################### ############ # OS element self.write_parser.startElement('os', AttributesImpl({})) ## Ports used elements for pu in host.portused: if not isinstance(pu, dict): continue self.__remove_none(pu) self.write_parser.startElement('portused', AttributesImpl({ 'state': pu.get('state', ''), 'proto': pu.get('proto', ''), 'portid': pu.get('portid', '')}) ) self.write_parser.endElement('portused') ## Osclass elements for oc in host.osclass: if not isinstance(oc, dict): continue self.__remove_none(oc) self.write_parser.startElement('osclass', AttributesImpl({ 'vendor': oc.get('vendor', ''), 'osfamily': oc.get('osfamily', ''), 'type': oc.get('type', ''), 'osgen': oc.get('osgen', ''), 'accuracy': oc.get('accuracy', '')}) ) self.write_parser.endElement('osclass') ## Osmatch elements for om in host.osmatch: if not isinstance(om, dict): continue self.__remove_none(om) self.write_parser.startElement('osmatch', AttributesImpl({ 'name': om.get('name', ''), 'accuracy': om.get('accuracy', '')}) ) self.write_parser.endElement('osmatch') ## Osfingerprint element if isinstance(host.osfingerprint, dict): self.__remove_none(host.osfingerprint) self.write_parser.startElement('osfingerprint', AttributesImpl({ 'fingerprint': host.osfingerprint.get( 'fingerprint', '')}) ) self.write_parser.endElement('osfingerprint') self.write_parser.endElement('os') # End of OS element ################### # Uptime element if isinstance(host.uptime, dict): self.write_parser.startElement('uptime', AttributesImpl({ 'seconds': host.uptime.get('seconds', ''), 'lastboot': host.uptime.get('lastboot', '')}) ) self.write_parser.endElement('uptime') ##################### # Sequences elementes ## TCP Sequence element if isinstance(host.tcpsequence, dict): self.write_parser.startElement('tcpsequence', AttributesImpl({ 'index': host.tcpsequence.get('index', ''), 'class': host.tcpsequence.get('class', ''), 'difficulty': host.tcpsequence.get('difficulty', ''), 'values': host.tcpsequence.get('values', '')}) ) self.write_parser.endElement('tcpsequence') ## IP ID Sequence element if isinstance(host.ipidsequence, dict): self.write_parser.startElement('ipidsequence', AttributesImpl({ 'class': host.ipidsequence.get('class', ''), 'values': host.ipidsequence.get('values', '')}) ) self.write_parser.endElement('ipidsequence') ## TCP TS Sequence element if isinstance(host.tcptssequence, dict): self.write_parser.startElement('tcptssequence', AttributesImpl({ 'class': host.tcptssequence.get('class', ''), 'values': host.tcptssequence.get('values', '')}) ) self.write_parser.endElement('tcptssequence') # End of sequences elements ########################### # Trace elements if isinstance(host.trace, dict): self.write_parser.startElement('trace', AttributesImpl({ 'port': host.trace.get('port', ''), 'proto': host.trace.get('proto', '')}) ) # Write hops: for hop in host.trace['hop']: self.write_parser.startElement('hop', AttributesImpl(hop)) self.write_parser.endElement('hop') self.write_parser.endElement('trace') # End trace elements # End host element self.write_parser.endElement('host') def _write_debugging(self): self.write_parser.startElement('debugging', AttributesImpl({ 'level': str(self.debugging_level)}) ) self.write_parser.endElement('debugging') def _write_verbose(self): self.write_parser.startElement('verbose', AttributesImpl({ 'level': str(self.verbose_level)}) ) self.write_parser.endElement('verbose') def _write_scaninfo(self): for scan in self.scaninfo: if not isinstance(scan, dict): continue self.write_parser.startElement('scaninfo', AttributesImpl({ 'type': scan.get('type', ''), 'protocol': scan.get('protocol', ''), 'numservices': scan.get('numservices', ''), 'services': scan.get('services', '')}) ) self.write_parser.endElement('scaninfo') def _write_nmaprun(self): self.write_parser.startElement('nmaprun', AttributesImpl({ 'annotation': str(self.profile_annotation), 'args': str(self.nmap_command), 'description': str(self.profile_description), 'hint': str(self.profile_hint), 'nmap_output': str(self.nmap_output), 'options': str(self.profile_options), 'profile': str(self.profile), 'profile_name': str(self.profile_name), 'scanner': str(self.scanner), 'start': str(self.start), 'startstr': str(self.formated_date), 'target': str(self.target), 'version': str(self.scanner_version), 'scan_name': str(self.scan_name)}) ) def _verify_file(self, xml_file): # let errors be raised if isinstance(xml_file, basestring): xml_file = open(xml_file, 'w') else: mode = xml_file.mode if mode in ('r+', 'w', 'w+'): xml_file.seek(0) return xml_file def __remove_none(self, dic): # saxutils will have problems if your dic contain any None items # (it will try to use the replace method, for example, which a # None object doesn't have). for k, v in dic.items(): if k is None or v is None: del dic[k] def is_unsaved(self): return self.unsaved
class SeqXmlWriter(SequenceWriter): """Writes SeqRecords into seqXML file. SeqXML requires the sequence alphabet be explicitly RNA, DNA or protein, i.e. an instance or subclass of Bio.Alphabet.RNAAlphabet, Bio.Alphabet.DNAAlphabet or Bio.Alphabet.ProteinAlphabet. """ def __init__(self, target, source=None, source_version=None, species=None, ncbiTaxId=None): """Create Object and start the xml generator. Arguments: - target - Output stream opened in binary mode, or a path to a file. - source - The source program/database of the file, for example UniProt. - source_version - The version or release number of the source program or database from which the data originated. - species - The scientific name of the species of origin of all entries in the file. - ncbiTaxId - The NCBI taxonomy identifier of the species of origin. """ super().__init__(target, "wb") handle = self.handle self.xml_generator = XMLGenerator(handle, "utf-8") self.xml_generator.startDocument() self.source = source self.source_version = source_version self.species = species self.ncbiTaxId = ncbiTaxId def write_header(self): """Write root node with document metadata.""" attrs = { "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "xsi:noNamespaceSchemaLocation": "http://www.seqxml.org/0.4/seqxml.xsd", "seqXMLversion": "0.4", } if self.source is not None: attrs["source"] = self.source if self.source_version is not None: attrs["sourceVersion"] = self.source_version if self.species is not None: if not isinstance(self.species, str): raise TypeError("species should be of type string") attrs["speciesName"] = self.species if self.ncbiTaxId is not None: if not isinstance(self.ncbiTaxId, (str, int)): raise TypeError("ncbiTaxID should be of type string or int") attrs["ncbiTaxID"] = self.ncbiTaxId self.xml_generator.startElement("seqXML", AttributesImpl(attrs)) def write_record(self, record): """Write one record.""" if not record.id or record.id == "<unknown id>": raise ValueError("SeqXML requires identifier") if not isinstance(record.id, str): raise TypeError("Identifier should be of type string") attrb = {"id": record.id} if ("source" in record.annotations and self.source != record.annotations["source"]): if not isinstance(record.annotations["source"], str): raise TypeError("source should be of type string") attrb["source"] = record.annotations["source"] self.xml_generator.startElement("entry", AttributesImpl(attrb)) self._write_species(record) self._write_description(record) self._write_seq(record) self._write_dbxrefs(record) self._write_properties(record) self.xml_generator.endElement("entry") def write_footer(self): """Close the root node and finish the XML document.""" self.xml_generator.endElement("seqXML") self.xml_generator.endDocument() def _write_species(self, record): """Write the species if given (PRIVATE).""" local_ncbi_taxid = None if "ncbi_taxid" in record.annotations: local_ncbi_taxid = record.annotations["ncbi_taxid"] if isinstance(local_ncbi_taxid, list): # SwissProt parser uses a list (which could cope with chimeras) if len(local_ncbi_taxid) == 1: local_ncbi_taxid = local_ncbi_taxid[0] elif len(local_ncbi_taxid) == 0: local_ncbi_taxid = None else: ValueError( "Multiple entries for record.annotations['ncbi_taxid'], %r" % local_ncbi_taxid) if "organism" in record.annotations and local_ncbi_taxid: local_org = record.annotations["organism"] if not isinstance(local_org, str): raise TypeError("organism should be of type string") if not isinstance(local_ncbi_taxid, (str, int)): raise TypeError("ncbiTaxID should be of type string or int") # The local species definition is only written if it differs from the global species definition if local_org != self.species or local_ncbi_taxid != self.ncbiTaxId: attr = {"name": local_org, "ncbiTaxID": str(local_ncbi_taxid)} self.xml_generator.startElement("species", AttributesImpl(attr)) self.xml_generator.endElement("species") def _write_description(self, record): """Write the description if given (PRIVATE).""" if record.description: if not isinstance(record.description, str): raise TypeError("Description should be of type string") description = record.description if description == "<unknown description>": description = "" if len(record.description) > 0: self.xml_generator.startElement("description", AttributesImpl({})) self.xml_generator.characters(description) self.xml_generator.endElement("description") def _write_seq(self, record): """Write the sequence (PRIVATE). Note that SeqXML requires a DNA, RNA or protein alphabet. """ if isinstance(record.seq, UnknownSeq): raise TypeError( "Sequence type is UnknownSeq but SeqXML requires sequence") seq = str(record.seq) if not len(seq) > 0: raise ValueError("The sequence length should be greater than 0") molecule_type = record.annotations.get("molecule_type") if molecule_type is None: raise ValueError("molecule_type is not defined") elif "DNA" in molecule_type: seqElem = "DNAseq" elif "RNA" in molecule_type: seqElem = "RNAseq" elif molecule_type == "protein": seqElem = "AAseq" else: raise ValueError("unknown molecule_type '%s'" % molecule_type) self.xml_generator.startElement(seqElem, AttributesImpl({})) self.xml_generator.characters(seq) self.xml_generator.endElement(seqElem) def _write_dbxrefs(self, record): """Write all database cross references (PRIVATE).""" if record.dbxrefs is not None: for dbxref in record.dbxrefs: if not isinstance(dbxref, str): raise TypeError("dbxrefs should be of type list of string") if dbxref.find(":") < 1: raise ValueError( "dbxrefs should be in the form ['source:id', 'source:id' ]" ) dbsource, dbid = dbxref.split(":", 1) attr = {"source": dbsource, "id": dbid} self.xml_generator.startElement("DBRef", AttributesImpl(attr)) self.xml_generator.endElement("DBRef") def _write_properties(self, record): """Write all annotations that are key value pairs with values of a primitive type or list of primitive types (PRIVATE).""" for key, value in record.annotations.items(): if key not in ("organism", "ncbi_taxid", "source"): if value is None: attr = {"name": key} self.xml_generator.startElement("property", AttributesImpl(attr)) self.xml_generator.endElement("property") elif isinstance(value, list): for v in value: if isinstance(value, (int, float, str)): attr = {"name": key, "value": v} self.xml_generator.startElement( "property", AttributesImpl(attr)) self.xml_generator.endElement("property") elif isinstance(value, (int, float, str)): attr = {"name": key, "value": str(value)} self.xml_generator.startElement("property", AttributesImpl(attr)) self.xml_generator.endElement("property")
def func(out): gen = XMLGenerator(out) gen.startDocument() gen.startElement("doc", {})
def toXml(self, result, out): atom = "http://www.w3.org/2005/Atom" tf = "http://sdk.nokia.com/test-framework/ns/1.0" gen = XMLGenerator(out, 'utf-8') gen.startDocument() gen.startPrefixMapping('atom', atom) gen.startPrefixMapping('tf', tf) startElement(gen, atom, 'entry') writeElement(gen, atom, 'title', result.constructTitle()) writeElement(gen, atom, 'updated', datetime.datetime.now().isoformat()) writeElement(gen, tf, 'errorSummary', exitStatusAsString(result.status())) writeElement(gen, tf, 'host', socket.gethostname()) if result._testStart != None: writeElement(gen, tf, 'testStart', result._testStart.isoformat()) else: result._internalErrors.append( "Result generator: no start timestamp found.") if result._testEnd != None: writeElement(gen, tf, 'testEnd', result._testEnd.isoformat()) else: result._internalErrors.append( "Result generator: no end timestamp found.") startElement(gen, tf, 'installer') writeElement(gen, tf, 'sourceUrl', result._installerSourceLocation) writeElement(gen, tf, 'platform', result._installerTargetPlatform) #TODO revision endElement(gen, tf, 'installer') if result._testcase != None: startElement(gen, tf, 'testCase') writeElement(gen, tf, 'name', result._testcase.name()) writeElement(gen, tf, 'path', result._testcase.path()) writeElement(gen, tf, 'installScript', result._testcase.installscript()) endElement(gen, tf, 'testCase') else: result._internalErrors.append( "Result generator: No test case given.") if result._installationResult != None: startElement(gen, tf, 'installationResult') writeElement(gen, tf, 'exitCode', str(result._installationResult.exitCode)) writeElement( gen, tf, 'exitStatus', exitStatusAsString(result._installationResult.exitStatus)) endElement(gen, tf, 'installationResult') else: result._internalErrors.append( "Result generator: No installation result given.") startElement(gen, tf, 'checkerResult') for err in result._checkerErrors: writeElement(gen, tf, 'error', err) endElement(gen, tf, 'checkerResult') startElement(gen, tf, 'virtualMachine') writeElement(gen, tf, 'path', result._vm.vmxPath()) writeElement(gen, tf, 'platform', result._vm.ostype()) writeElement(gen, tf, 'snapshot', result._vm.snapshot()) endElement(gen, tf, 'virtualMachine') startElement(gen, tf, 'internalErrors') for i in result._internalErrors: writeElement(gen, tf, 'internalError', str(i)) endElement(gen, tf, 'internalErrors') if result._errorSnapshot != None: writeElement(gen, tf, 'errorSnapshot', result._errorSnapshot) endElement(gen, atom, 'entry') gen.endDocument()
class XMLEncoderAdapter(object): """Adapts a WebAPIEncoder to output XML. This takes an existing encoder and adapts it to output a simple XML format. """ def __init__(self, encoder, *args, **kwargs): self.encoder = encoder def encode(self, o, *args, **kwargs): self.level = 0 self.doIndent = False stream = StringIO() self.xml = XMLGenerator(stream, settings.DEFAULT_CHARSET) self.xml.startDocument() self.startElement("rsp") self.__encode(o, *args, **kwargs) self.endElement("rsp") self.xml.endDocument() self.xml = None return stream.getvalue() def __encode(self, o, *args, **kwargs): if isinstance(o, dict): for key, value in six.iteritems(o): attrs = {} if isinstance(key, six.integer_types): attrs['value'] = str(key) key = 'int' self.startElement(key, attrs) self.__encode(value, *args, **kwargs) self.endElement(key) elif isinstance(o, (tuple, list)): self.startElement("array") for i in o: self.startElement("item") self.__encode(i, *args, **kwargs) self.endElement("item") self.endElement("array") elif isinstance(o, six.string_types): self.text(o) elif isinstance(o, six.integer_types): self.text("%d" % o) elif isinstance(o, float): self.text("%s" % o) elif isinstance(o, bool): if o: self.text("True") else: self.text("False") elif o is None: pass else: result = self.encoder.encode(o, *args, **kwargs) if result is None: raise TypeError("%r is not XML serializable" % (o,)) return self.__encode(result, *args, **kwargs) def startElement(self, name, attrs={}): self.addIndent() self.xml.startElement(name, attrs) self.level += 1 self.doIndent = True def endElement(self, name): self.level -= 1 self.addIndent() self.xml.endElement(name) self.doIndent = True def text(self, value): self.xml.characters(value) self.doIndent = False def addIndent(self): if self.doIndent: self.xml.ignorableWhitespace('\n' + ' ' * self.level)
def _open(self): """open a new communication channel from src to dst""" generator = XMLGenerator(self.worker, encoding='UTF-8') generator.startDocument() generator.startElement('channel', {})
class XMLMapSaver(object): def __init__(self, filepath, engine, map, importList, state=0, datastate=0): self.SModel, self.SMap, self.SLayer, self.SInstances, self.SObject, self.SAction = list( range(6)) self.engine = engine self.model = self.engine.getModel() self.image_manager = self.engine.getImageManager() if (state): self.state = state if (state == self.SMap): self.map = datastate else: assert 0, "Invalid initialization state." else: self.state = self.SModel self.stack = [self.SModel] self.datastack = [] self.file = open(filepath, 'w') self.xmlout = XMLGenerator(self.file, 'ascii') self.xmlout.startDocument() self.indent_level = '' self.nspace = None self.map = map self.importList = importList def startElement(self, name, attrs): self.file.write(self.indent_level) self.xmlout.startElementNS((None, name), name, attrs) self.file.write('\n') self.indent_level = self.indent_level + '\t' def endElement(self, name): self.indent_level = self.indent_level[0:(len(self.indent_level) - 1)] self.file.write(self.indent_level) self.xmlout.endElementNS((None, name), name) self.file.write('\n') def write_map(self): assert self.state == self.SModel, "Declaration of <map> not at the top level." attr_vals = { (None, 'id'): self.map.getId(), (None, 'format'): MAPFORMAT, } attr_names = { (None, 'id'): 'id', (None, 'format'): 'format', } attrs = AttributesNSImpl(attr_vals, attr_names) self.startElement('map', attrs) self.state = self.SMap self.write_imports(self.map, self.importList) self.write_layers(self.map) self.write_camera(self.map) self.endElement('map') def write_imports(self, map, importList): for importdir in importList: self.write_importdir(root_subfile(map.getFilename(), importdir)) imports = [] for layer in map.getLayers(): for instance in layer.getInstances(): file = instance.getObject().getFilename() if not (file in imports): if not self.have_superdir(file, importList): imports.append(file) self.write_import(root_subfile(map.getFilename(), file)) def have_superdir(self, file, importList): '''returns true, if file is in directories given in importList''' for dir in importList: have = True for test in zip(dir.split(os.path.sep), file.split(os.path.sep)): if test[0] != test[1]: have = False if have: return True return False def write_import(self, file): attr_vals = { (None, 'file'): file, } attr_names = { (None, 'file'): 'file', } attrs = AttributesNSImpl(attr_vals, attr_names) self.file.write(self.indent_level) self.xmlout.startElementNS((None, 'import'), 'import', attrs) self.xmlout.endElementNS((None, 'import'), 'import') self.file.write('\n') def write_importdir(self, dir): attr_vals = { (None, 'dir'): dir, } attr_names = { (None, 'dir'): 'dir', } attrs = AttributesNSImpl(attr_vals, attr_names) self.file.write(self.indent_level) self.xmlout.startElementNS((None, 'import'), 'import', attrs) self.xmlout.endElementNS((None, 'import'), 'import') self.file.write('\n') def pathing_val_to_str(self, val): if val == fife.CELL_EDGES_AND_DIAGONALS: return "cell_edges_and_diagonals" if val == fife.FREEFORM: return "freeform" return "cell_edges_only" def layer_type_to_str(self, layer): if layer.isWalkable(): return "walkable" elif layer.isInteract(): return "interact" return "" def write_layers(self, map): for layer in map.getLayers(): cellgrid = layer.getCellGrid() attr_vals = { (None, 'id'): layer.getId(), (None, 'grid_type'): cellgrid.getType(), (None, 'x_scale'): str(cellgrid.getXScale()), (None, 'y_scale'): str(cellgrid.getYScale()), (None, 'rotation'): str(cellgrid.getRotation()), (None, 'x_offset'): str(cellgrid.getXShift()), (None, 'y_offset'): str(cellgrid.getYShift()), (None, 'z_offset'): str(cellgrid.getZShift()), (None, 'pathing'): self.pathing_val_to_str(layer.getPathingStrategy()), (None, 'transparency'): str(layer.getLayerTransparency()), (None, 'layer_type'): str(self.layer_type_to_str(layer)), (None, 'layer_type_id'): str(layer.getWalkableId()), } attr_names = { (None, 'id'): 'id', (None, 'grid_type'): 'grid_type', (None, 'scaling'): 'scaling', (None, 'rotation'): 'rotation', (None, 'x_offset'): 'x_offset', (None, 'y_offset'): 'y_offset', (None, 'z_offset'): 'z_offset', (None, 'pathing'): 'pathing', (None, 'layer_type'): 'layer_type', (None, 'layer_type_id'): 'layer_type_id', } attrs = AttributesNSImpl(attr_vals, attr_names) self.startElement('layer', attrs) self.write_instances(layer) self.write_lights(layer) self.endElement('layer') def write_instances(self, layer): attrs = AttributesNSImpl({}, {}) self.startElement('instances', attrs) for inst in layer.getInstances(): position = inst.getLocationRef().getExactLayerCoordinates() attr_vals = { (None, 'o'): inst.getObject().getId(), (None, 'x'): str(position.x), (None, 'y'): str(position.y), (None, 'z'): str(position.z), (None, 'r'): str(inst.getRotation()), } attr_names = { (None, 'o'): 'o', (None, 'x'): 'x', (None, 'y'): 'y', (None, 'z'): 'z', (None, 'r'): 'r', } visual = inst.get2dGfxVisual() if visual: attr_vals[(None, 'stackpos')] = str(visual.getStackPosition()) attr_names[(None, 'stackpos')] = 'stackpos' nspace = inst.getObject().getNamespace() if nspace != self.nspace: attr_vals[(None, 'ns')] = inst.getObject().getNamespace() attr_names[(None, 'ns')] = 'ns' self.nspace = nspace instId = inst.getId() if instId: attr_vals[(None, 'id')] = inst.getId() attr_names[(None, 'id')] = 'id' if inst.isOverrideBlocking(): attr_vals[(None, 'override_blocking')] = str( int(inst.isOverrideBlocking())) attr_names[(None, 'override_blocking')] = 'override_blocking' if inst.getObject().isBlocking() is not inst.isBlocking(): attr_vals[(None, 'blocking')] = str(int(inst.isBlocking())) attr_names[(None, 'blocking')] = 'blocking' attrs = AttributesNSImpl(attr_vals, attr_names) self.file.write(self.indent_level) self.xmlout.startElementNS((None, 'i'), 'i', attrs) self.xmlout.endElementNS((None, 'i'), 'i') self.file.write('\n') self.endElement('instances') def write_lights(self, layer): attrs = AttributesNSImpl({}, {}) self.startElement('lights', attrs) cameras = layer.getMap().getCameras() for cam in cameras: hit = False layers = cam.getRenderer("LightRenderer").getActiveLayers() for lay in layers: if lay.getId() == layer.getId(): hit = True if hit == False: continue renderer = fife.LightRenderer.getInstance(cam) groups = renderer.getGroups() for group in groups: infos = renderer.getLightInfo(group) for info in infos: attr_vals = {} attr_names = {} type = info.getName() attr_vals[(None, 'group')] = str(group) attr_names[(None, 'group')] = 'group' attr_vals[(None, 'type')] = str(type) attr_names[(None, 'type')] = 'type' attr_vals[(None, 'instance')] = str( info.getNode().getInstance().getId()) attr_names[(None, 'instance')] = 'instance' if info.getSrcBlend() > -1: attr_vals[(None, 'src')] = str(info.getSrcBlend()) attr_names[(None, 'src')] = 'src' if info.getDstBlend() > -1: attr_vals[(None, 'dst')] = str(info.getDstBlend()) attr_names[(None, 'dst')] = 'dst' if info.getStencil() > -1: attr_vals[(None, 's_ref')] = str(info.getStencil()) attr_names[(None, 's_ref')] = 's_ref' attr_vals[(None, 'a_ref')] = str(info.getAlpha()) attr_names[(None, 'a_ref')] = 'a_ref' if type == 'simple': if info.getRadius() > 0: attr_vals[(None, 'radius')] = str(info.getRadius()) attr_names[(None, 'radius')] = 'radius' if info.getColor(): color = info.getColor() attr_vals[(None, 'color')] = '%d,%d,%d' % ( color[0], color[1], color[2]) attr_vals[(None, 'intensity')] = str(color[3]) attr_names[(None, 'color')] = 'color' attr_names[(None, 'intensity')] = 'intensity' if info.getSubdivisions() is not 32: attr_vals[(None, 'subdivisions')] = str( info.getSubdivisions()) attr_names[(None, 'subdivisions')] = 'subdivisions' if info.getXStretch() > 1.001 or info.getXStretch( ) < 0.999: attr_vals[(None, 'xstretch')] = str(info.getXStretch()) attr_names[(None, 'xstretch')] = 'xstretch' if info.getYStretch() > 1.001 or info.getYStretch( ) < 0.999: attr_vals[(None, 'ystretch')] = str(info.getYStretch()) attr_names[(None, 'ystretch')] = 'ystretch' elif type == 'image': if info.getImage() == 0: continue img = info.getImage() name = img.getName() attr_vals[(None, 'image')] = str('../' + name) attr_names[(None, 'image')] = 'image' elif type == 'animation': if info.getAnimation() == 0: continue ani = info.getAnimation() count = 0 newstr = '' image = ani.getFrame(ani.getActionFrame()) fname = image.getName() strings = ([str(s) for s in fname.split('/')]) leng = len(strings) - 1 while count < leng: newstr = str(newstr + strings[count] + '/') count += 1 name = str('../' + newstr + 'animation.' + fileExtensions[0]) attr_vals[(None, 'animation')] = str(name) attr_names[(None, 'animation')] = 'animation' else: continue attrs = AttributesNSImpl(attr_vals, attr_names) self.file.write(self.indent_level) self.xmlout.startElementNS((None, 'l'), 'l', attrs) self.xmlout.endElementNS((None, 'l'), 'l') self.file.write('\n') self.endElement('lights') # Save the linked camera of a map. def write_camera(self, map): cameralist = map.getCameras() for cam in cameralist: if cam.getMap().getId() == map.getId(): celldimensions = cam.getCellImageDimensions() viewport = cam.getViewPort() attr_names = { (None, 'id'): 'id', (None, 'zoom'): 'zoom', (None, 'tilt'): 'tile', (None, 'rotation'): 'rotation', (None, 'ref_cell_width'): 'ref_cell_width', (None, 'ref_cell_height'): 'ref_cell_height', } attr_vals = { (None, 'id'): cam.getId(), (None, 'zoom'): str(cam.getZoom()), (None, 'tilt'): str(cam.getTilt()), (None, 'rotation'): str(cam.getRotation()), (None, 'ref_cell_width'): str(celldimensions.x), (None, 'ref_cell_height'): str(celldimensions.y), } # add a viewport entry if the cam isn't full sized if not (viewport == self.engine.getRenderBackend().getArea()): attr_names[(None, 'viewport')] = 'viewport' attr_vals[(None, 'viewport')] = '%d,%d,%d,%d' % ( viewport.x, viewport.y, viewport.w, viewport.h) colors = cam.getLightingColor() if colors[0] < 1.0 or colors[1] < 1.0 or colors[2] < 1.0: attr_names[(None, 'light_color')] = 'light_color' attr_vals[(None, 'light_color')] = '%f,%f,%f' % ( colors[0], colors[1], colors[2]) attrs = AttributesNSImpl(attr_vals, attr_names) self.startElement('camera', attrs) self.endElement('camera') def flush(self): self.xmlout.endDocument() self.file.close() def saveResource(self): self.write_map()
def end_test(self, result): """Called after each test.""" failures = errors = skipped = disabled = 0 if result.eofs == 'O': pass elif result.eofs == 'S': skipped = 1 elif result.eofs == 'F': failures = 1 elif result.eofs == 'E': errors = 1 else: errors = 1 classname = encode(result.case.uid.replace("/", ".")) if classname.endswith('.py'): classname = classname[:-3] filename = os.path.join(self.outdir, '%s.xml' % (result.case.uid, )) dirname = os.path.dirname(filename) try: os.makedirs(dirname) except OSError as ex: if ex.errno != errno.EEXIST: raise f_report = open(filename, 'w') try: xml = XMLGenerator(f_report, encoding='utf-8') xml.startDocument() xml.startElement( 'testsuite', { 'name': classname, 'tests': '%d' % (1, ), 'failures': '%d' % (failures, ), 'errors': '%d' % (errors, ), 'time': '%0.3f' % (result.duration / 1000.0, ), 'disabled': '%d' % (disabled, ), 'skipped': '%d' % (skipped, ), 'timestamp': self.now.isoformat(), 'hostname': os.uname()[1], }) xml.startElement('properties', {}) xml.startElement('property', { 'name': 'hostname', 'value': result.environment.hostname, }) xml.endElement('property') xml.startElement('property', { 'name': 'architecture', 'value': result.environment.architecture, }) xml.endElement('property') xml.startElement('property', { 'name': 'role', 'value': result.environment.role, }) xml.endElement('property') xml.startElement( 'property', { 'name': 'version', 'value': '%s' % (result.environment.ucs_version, ), }) xml.endElement('property') if result.case.description: xml.startElement( 'property', { 'name': 'description', 'value': encode(result.case.description or result.case.uid), }) xml.endElement('property') xml.endElement('properties') xml.startElement( 'testcase', { 'name': result.environment.hostname, # 'assertions': '%d' % (0,), 'time': '%0.3f' % (result.duration / 1000.0, ), 'classname': classname, # 'status': '???', }) if skipped: try: mime, content = result.artifacts['check'] except KeyError: msg = '' else: msg = '\n'.join(['%s' % (c, ) for c in content]) xml.startElement('skipped', { 'message': msg, }) xml.endElement('skipped') elif errors: xml.startElement('error', { 'type': 'TestError', 'message': '%s' % (result.result, ), }) xml.endElement('error') elif failures: msg = TestCodes.MESSAGE.get(result.reason, '') xml.startElement( 'failure', { 'type': 'TestFailure', 'message': '{} ({})'.format( msg, result.case.description or result.case.uid), }) xml.endElement('failure') try: mime, content = result.artifacts['stdout'] except KeyError: pass else: xml.startElement('system-out', {}) xml.characters(self.utf8(content)) xml.endElement('system-out') try: mime, content = result.artifacts['stderr'] except KeyError: pass else: xml.startElement('system-err', {}) xml.characters(self.utf8(content)) xml.endElement('system-err') xml.endElement('testcase') xml.endElement('testsuite') xml.endDocument() finally: f_report.close() super(Junit, self).end_test(result)
class XmlAnnotationWriter: VERSION = '1.1' def __init__(self, f): self.xmlgen = XMLGenerator(f, 'utf-8') self._level = 0 def _indent(self, newline=True): if newline: self.xmlgen.ignorableWhitespace('\n') self.xmlgen.ignorableWhitespace(' ' * self._level) def _add_version(self): self._indent() self.xmlgen.startElement('version', {}) self.xmlgen.characters(self.VERSION) self.xmlgen.endElement('version') def open_root(self): self.xmlgen.startDocument() self.xmlgen.startElement('annotations', {}) self._level += 1 self._add_version() def _add_meta(self, meta): self._level += 1 for k, v in meta.items(): if isinstance(v, OrderedDict): self._indent() self.xmlgen.startElement(k, {}) self._add_meta(v) self._indent() self.xmlgen.endElement(k) elif isinstance(v, list): self._indent() self.xmlgen.startElement(k, {}) for tup in v: self._add_meta(OrderedDict([tup])) self._indent() self.xmlgen.endElement(k) else: self._indent() self.xmlgen.startElement(k, {}) self.xmlgen.characters(v) self.xmlgen.endElement(k) self._level -= 1 def write_meta(self, meta): self._indent() self.xmlgen.startElement('meta', {}) self._add_meta(meta) self._indent() self.xmlgen.endElement('meta') def open_track(self, track): self._indent() self.xmlgen.startElement('track', track) self._level += 1 def open_image(self, image): self._indent() self.xmlgen.startElement('image', image) self._level += 1 def open_box(self, box): self._indent() self.xmlgen.startElement('box', box) self._level += 1 def open_polygon(self, polygon): self._indent() self.xmlgen.startElement('polygon', polygon) self._level += 1 def open_polyline(self, polyline): self._indent() self.xmlgen.startElement('polyline', polyline) self._level += 1 def open_points(self, points): self._indent() self.xmlgen.startElement('points', points) self._level += 1 def open_tag(self, tag): self._indent() self.xmlgen.startElement("tag", tag) self._level += 1 def add_attribute(self, attribute): self._indent() self.xmlgen.startElement('attribute', {'name': attribute['name']}) self.xmlgen.characters(attribute['value']) self.xmlgen.endElement('attribute') def _close_element(self, element): self._level -= 1 self._indent() self.xmlgen.endElement(element) def close_box(self): self._close_element('box') def close_polygon(self): self._close_element('polygon') def close_polyline(self): self._close_element('polyline') def close_points(self): self._close_element('points') def close_tag(self): self._close_element('tag') def close_image(self): self._close_element('image') def close_track(self): self._close_element('track') def close_root(self): self._close_element('annotations') self.xmlgen.endDocument()
def gen(): stream = io.StringIO() try: writer = XMLGenerator(stream, 'utf-8') writer.startDocument() start_element_attrs = {} if xmlns and schema_name: start_element_attrs['xmlns'] = xmlns start_element_attrs[ 'xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance' schema_url = get_xml_schema_url(xmlns, schema_name) start_element_attrs['xsi:schemaLocation'] = '{} {}'.format( xmlns, schema_url) for elem_name in root_element_name.split('.'): writer.startElement(elem_name, attrs=start_element_attrs) stream.seek(0) yield stream.getvalue() stream.truncate(0) i = 0 iterator = models.iterator() if isinstance(models, QuerySet) else models for m in iterator: model_to_xml(writer, m, field_map, model_name, show_sequence_index=show_sequence_index, sequence_index=i) stream.seek(0) yield stream.getvalue() stream.truncate(0) i += 1 if sub_models is not None and sub_models_field_map is not None and sub_models_element_name is not None: writer.startElement(sub_models_element_name, attrs={}) stream.seek(0) yield stream.getvalue() stream.truncate(0) i = 0 iterator = sub_models.iterator() if isinstance( sub_models, QuerySet) else sub_models for m in iterator: model_to_xml(writer, m, sub_models_field_map, sub_model_name, show_sequence_index=show_sequence_index, sequence_index=i) stream.seek(0) yield stream.getvalue() stream.truncate(0) i += 1 writer.endElement(sub_models_element_name) for elem_name in root_element_name.split('.')[::-1]: writer.endElement(elem_name) writer.endDocument() stream.seek(0) yield stream.getvalue() except Exception as e: logger.error('Error in iterator: {}'.format(str(e))) raise finally: stream.close()
def Load(self): try: self.file.seek(0) cdr = RiffChunk() cdr.load(self.file.read()) app.updateInfo(inf2=_("Parsing is finished"), inf3=10) summary = [ ('CDR version', cdr.infocollector.cdr_version), ('pages', cdr.infocollector.pages - 1), ('layers', cdr.infocollector.layers / cdr.infocollector.pages), ('groups', cdr.infocollector.groups), ('objects', cdr.infocollector.objects), ('bitmaps', cdr.infocollector.bitmaps), ] if cdr.infocollector.compression: summary.append(('compression', 'yes')) else: summary.append(('compression', 'no')) if self.filename == None: return from xml.sax.saxutils import XMLGenerator try: file = open(self.filename, 'w') except (IOError, os.error), value: import sys sys.stderr('cannot write parsing result into %s: %s' % ( ` filename `, value[1])) return writer = XMLGenerator(out=file, encoding='utf-8') writer.startDocument() writer.startElement('riffDocument', {}) writer.characters('\n') writer.startElement('docSummary', {}) writer.characters('\n') for key, value in summary: writer.characters('\t') writer.startElement('%s' % key, {}) writer.characters('%s' % ` value `) writer.endElement('%s' % key) writer.characters('\n') writer.endElement('docSummary') writer.characters('\n') writer.startElement('docStructure', {}) writer.characters('\n') if cdr.infocollector.cdr_version > 6: self.info = cdr.infocollector self.info.loader = self self.info.process_properties() self.import_curves(writer) else: writer.characters('\t') writer.startElement('info', {}) value = 'Parsed file contains usupported CorelDRAW ver.%u' % cdr.infocollector.cdr_version + '.0 drawing' writer.characters('%s' % ` value `) writer.endElement('info') writer.characters('\n')
class SphinxXML(object): TAG_ROOT = 'sphinx:docset' TAG_SCHEMA = 'sphinx:schema' TAG_DOCUMENT = 'sphinx:document' def __init__(self, output=stdout): self._generator = XMLGenerator(encoding='utf-8', out=output) self._output = output self._logger = logging.getLogger(self.__class__.__name__) self._schema = {'field': [], 'attr': []} self._document_id = 0 def add_field(self, name): self._schema['field'].append({"name": name}) def add_attr(self, name, attr_type, **kwargs): attr = kwargs attr['name'] = name attr['type'] = attr_type self._schema['attr'].append(attr) def start(self): self._generator.startDocument() self._generator.startElement( self.TAG_ROOT, {'xmlns:sphinx': 'http://sphinxsearch.com/'}) # print schema self._generator.ignorableWhitespace("\n\n") self._generator.startElement(self.TAG_SCHEMA, {}) for key, items in self._schema.items(): for item in items: self._generator.ignorableWhitespace("\n\t") self._generator.startElement('sphinx:{}'.format(key), attrs=item) self._generator.endElement('sphinx:{}'.format(key)) self._generator.ignorableWhitespace("\n") self._generator.endElement(self.TAG_SCHEMA) self._generator.ignorableWhitespace("\n\n") self._output.flush() def add_document(self, **kwargs): # auto-generate incrementing document IDs self._document_id += 1 self._logger.info('Adding document #{}'.format(self._document_id)) self._generator.startElement(self.TAG_DOCUMENT, {"id": str(self._document_id)}) try: for key, val in kwargs.items(): self._generator.ignorableWhitespace("\n\t") self._generator.startElement(key, {}) self._generator.characters(val) self._generator.endElement(key) except ValueError: self._logger.error('add_document failed (doc ID #{})'.format( self._document_id), exc_info=True) self._generator.ignorableWhitespace("\n") self._generator.endElement(self.TAG_DOCUMENT) self._generator.ignorableWhitespace("\n\n") self._output.flush() def end(self): self._generator.endElement(self.TAG_ROOT) self._generator.endDocument() self._logger.info('XML closed')