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': '&#60;',        # must use charref                  'gt': '&#62;',                  'amp': '&#38;',       # must use charref                  'quot': '&#34;',                  'apos': '&#39;',                  }    # 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 + -
显示快捷键?