xmllib.py
来自「mallet是自然语言处理、机器学习领域的一个开源项目。」· Python 代码 · 共 930 行 · 第 1/3 页
PY
930 行
ns = self.__namespaces.get(prefix) if ns is not None: nstag = ns + ' ' + nstag elif prefix != '': nstag = prefix + ':' + nstag # undo split self.stack[-1] = tagname, nsdict, nstag # translate namespace of attributes attrnamemap = {} # map from new name to old name (used for error reporting) for key in attrdict.keys(): attrnamemap[key] = key if self.__use_namespaces: nattrdict = {} for key, val in attrdict.items(): okey = key res = qname.match(key) if res is not None: aprefix, key = res.group('prefix', 'local') if self.__map_case: key = key.lower() if aprefix is None: aprefix = '' ans = None for t, d, nst in self.stack: if d.has_key(aprefix): ans = d[aprefix] if ans is None and aprefix != '': ans = self.__namespaces.get(aprefix) if ans is not None: key = ans + ' ' + key elif aprefix != '': key = aprefix + ':' + key elif ns is not None: key = ns + ' ' + key nattrdict[key] = val attrnamemap[key] = okey attrdict = nattrdict attributes = self.attributes.get(nstag) if attributes is not None: for key in attrdict.keys(): if not attributes.has_key(key): self.syntax_error("unknown attribute `%s' in tag `%s'" % (attrnamemap[key], tagname)) for key, val in attributes.items(): if val is not None and not attrdict.has_key(key): attrdict[key] = val method = self.elements.get(nstag, (None, None))[0] self.finish_starttag(nstag, attrdict, method) if tag.group('slash') == '/': self.finish_endtag(tagname) return tag.end(0) # Internal -- parse endtag def parse_endtag(self, i): rawdata = self.rawdata end = endbracketfind.match(rawdata, i+1) if end is None: return -1 res = tagfind.match(rawdata, i+2) if res is None: if self.literal: self.handle_data(rawdata[i]) return i+1 if not self.__accept_missing_endtag_name: self.syntax_error('no name specified in end tag') tag = self.stack[-1][0] k = i+2 else: tag = res.group(0) if self.__map_case: tag = tag.lower() if self.literal: if not self.stack or tag != self.stack[-1][0]: self.handle_data(rawdata[i]) return i+1 k = res.end(0) if endbracket.match(rawdata, k) is None: self.syntax_error('garbage in end tag') self.finish_endtag(tag) return end.end(0) # Internal -- finish processing of start tag def finish_starttag(self, tagname, attrdict, method): if method is not None: self.handle_starttag(tagname, method, attrdict) else: self.unknown_starttag(tagname, attrdict) # Internal -- finish processing of end tag def finish_endtag(self, tag): self.literal = 0 if not tag: self.syntax_error('name-less end tag') found = len(self.stack) - 1 if found < 0: self.unknown_endtag(tag) return else: found = -1 for i in range(len(self.stack)): if tag == self.stack[i][0]: found = i if found == -1: self.syntax_error('unopened end tag') return while len(self.stack) > found: if found < len(self.stack) - 1: self.syntax_error('missing close tag for %s' % self.stack[-1][2]) nstag = self.stack[-1][2] method = self.elements.get(nstag, (None, None))[1] if method is not None: self.handle_endtag(nstag, method) else: self.unknown_endtag(nstag) if self.__use_namespaces == len(self.stack): self.__use_namespaces = 0 del self.stack[-1] # Overridable -- handle xml processing instruction def handle_xml(self, encoding, standalone): pass # Overridable -- handle DOCTYPE def handle_doctype(self, tag, pubid, syslit, data): pass # Overridable -- handle start tag def handle_starttag(self, tag, method, attrs): method(attrs) # Overridable -- handle end tag def handle_endtag(self, tag, method): method() # Example -- handle character reference, no need to override def handle_charref(self, name): try: if name[0] == 'x': n = int(name[1:], 16) else: n = int(name) except ValueError: self.unknown_charref(name) return if not 0 <= n <= 255: self.unknown_charref(name) return self.handle_data(chr(n)) # Definition of entities -- derived classes may override entitydefs = {'lt': '<', # must use charref 'gt': '>', 'amp': '&', # must use charref 'quot': '"', 'apos': ''', } # Example -- handle data, should be overridden def handle_data(self, data): pass # Example -- handle cdata, could be overridden def handle_cdata(self, data): pass # Example -- handle comment, could be overridden def handle_comment(self, data): pass # Example -- handle processing instructions, could be overridden def handle_proc(self, name, data): pass # Example -- handle relatively harmless syntax errors, could be overridden def syntax_error(self, message): raise Error('Syntax error at line %d: %s' % (self.lineno, message)) # To be overridden -- handlers for unknown objects def unknown_starttag(self, tag, attrs): pass def unknown_endtag(self, tag): pass def unknown_charref(self, ref): pass def unknown_entityref(self, name): self.syntax_error("reference to unknown entity `&%s;'" % name)class TestXMLParser(XMLParser): def __init__(self, **kw): self.testdata = "" apply(XMLParser.__init__, (self,), kw) def handle_xml(self, encoding, standalone): self.flush() print 'xml: encoding =',encoding,'standalone =',standalone def handle_doctype(self, tag, pubid, syslit, data): self.flush() print 'DOCTYPE:',tag, `data` def handle_data(self, data): self.testdata = self.testdata + data if len(`self.testdata`) >= 70: self.flush() def flush(self): data = self.testdata if data: self.testdata = "" print 'data:', `data` def handle_cdata(self, data): self.flush() print 'cdata:', `data` def handle_proc(self, name, data): self.flush() print 'processing:',name,`data` def handle_comment(self, data): self.flush() r = `data` if len(r) > 68: r = r[:32] + '...' + r[-32:] print 'comment:', r def syntax_error(self, message): print 'error at line %d:' % self.lineno, message def unknown_starttag(self, tag, attrs): self.flush() if not attrs: print 'start tag: <' + tag + '>' else: print 'start tag: <' + tag, for name, value in attrs.items(): print name + '=' + '"' + value + '"', print '>' def unknown_endtag(self, tag): self.flush() print 'end tag: </' + tag + '>' def unknown_entityref(self, ref): self.flush() print '*** unknown entity ref: &' + ref + ';' def unknown_charref(self, ref): self.flush() print '*** unknown char ref: &#' + ref + ';' def close(self): XMLParser.close(self) self.flush()def test(args = None): import sys, getopt from time import time if not args: args = sys.argv[1:] opts, args = getopt.getopt(args, 'st') klass = TestXMLParser do_time = 0 for o, a in opts: if o == '-s': klass = XMLParser elif o == '-t': do_time = 1 if args: file = args[0] else: file = 'test.xml' if file == '-': f = sys.stdin else: try: f = open(file, 'r') except IOError, msg: print file, ":", msg sys.exit(1) data = f.read() if f is not sys.stdin: f.close() x = klass() t0 = time() try: if do_time: x.feed(data) x.close() else: for c in data: x.feed(c) x.close() except Error, msg: t1 = time() print msg if do_time: print 'total time: %g' % (t1-t0) sys.exit(1) t1 = time() if do_time: print 'total time: %g' % (t1-t0)if __name__ == '__main__': test()
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?