home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Lib / xmllib.pyc (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2000-06-23  |  32.5 KB  |  954 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 1.5)
  3.  
  4. import re
  5. import string
  6. version = '0.2'
  7. _S = '[ \t\r\n]+'
  8. _opS = '[ \t\r\n]*'
  9. _Name = '[a-zA-Z_:][-a-zA-Z0-9._:]*'
  10. _QStr = '(?:\'[^\']*\'|"[^"]*")'
  11. illegal = re.compile('[^\t\r\n -~\xa0-\xff]')
  12. interesting = re.compile('[]&<]')
  13. amp = re.compile('&')
  14. ref = re.compile('&(' + _Name + '|#[0-9]+|#x[0-9a-fA-F]+)[^-a-zA-Z0-9._:]')
  15. entityref = re.compile('&(?P<name>' + _Name + ')[^-a-zA-Z0-9._:]')
  16. charref = re.compile('&#(?P<char>[0-9]+[^0-9]|x[0-9a-fA-F]+[^0-9a-fA-F])')
  17. space = re.compile(_S + '$')
  18. newline = re.compile('\n')
  19. attrfind = re.compile(_S + '(?P<name>' + _Name + ')(' + _opS + '=' + _opS + '(?P<value>' + _QStr + '|[-a-zA-Z0-9.:+*%?!()_#=~]+))?')
  20. starttagopen = re.compile('<' + _Name)
  21. starttagend = re.compile(_opS + '(?P<slash>/?)>')
  22. starttagmatch = re.compile('<(?P<tagname>' + _Name + ')(?P<attrs>(?:' + attrfind.pattern + ')*)' + starttagend.pattern)
  23. endtagopen = re.compile('</')
  24. endbracket = re.compile(_opS + '>')
  25. endbracketfind = re.compile('(?:[^>\'"]|' + _QStr + ')*>')
  26. tagfind = re.compile(_Name)
  27. cdataopen = re.compile('<!\\[CDATA\\[')
  28. cdataclose = re.compile('\\]\\]>')
  29. _SystemLiteral = '(?P<%s>' + _QStr + ')'
  30. _PublicLiteral = '(?P<%s>"[-\'()+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*"|\'[-()+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*\')'
  31. _ExternalId = '(?:SYSTEM|PUBLIC' + _S + _PublicLiteral % 'pubid' + ')' + _S + _SystemLiteral % 'syslit'
  32. doctype = re.compile('<!DOCTYPE' + _S + '(?P<name>' + _Name + ')(?:' + _S + _ExternalId + ')?' + _opS)
  33. xmldecl = re.compile('<\\?xml' + _S + 'version' + _opS + '=' + _opS + '(?P<version>' + _QStr + ')' + '(?:' + _S + 'encoding' + _opS + '=' + _opS + '(?P<encoding>\'[A-Za-z][-A-Za-z0-9._]*\'|"[A-Za-z][-A-Za-z0-9._]*"))?(?:' + _S + 'standalone' + _opS + '=' + _opS + '(?P<standalone>\'(?:yes|no)\'|"(?:yes|no)"))?' + _opS + '\\?>')
  34. procopen = re.compile('<\\?(?P<proc>' + _Name + ')' + _opS)
  35. procclose = re.compile(_opS + '\\?>')
  36. commentopen = re.compile('<!--')
  37. commentclose = re.compile('-->')
  38. doubledash = re.compile('--')
  39. attrtrans = string.maketrans(' \r\n\t', '    ')
  40. _NCName = '[a-zA-Z_][-a-zA-Z0-9._]*'
  41. ncname = re.compile(_NCName + '$')
  42. qname = re.compile('(?:(?P<prefix>' + _NCName + '):)?(?P<local>' + _NCName + ')$')
  43. xmlns = re.compile('xmlns(?::(?P<ncname>' + _NCName + '))?$')
  44.  
  45. class XMLParser:
  46.     attributes = { }
  47.     elements = { }
  48.     
  49.     def __init__(self):
  50.         self._XMLParser__fixed = 0
  51.         self.reset()
  52.  
  53.     
  54.     def __fixelements(self):
  55.         self._XMLParser__fixed = 1
  56.         self.elements = { }
  57.         self._XMLParser__fixdict(self.__dict__)
  58.         self._XMLParser__fixclass(self.__class__)
  59.  
  60.     
  61.     def __fixclass(self, kl):
  62.         self._XMLParser__fixdict(kl.__dict__)
  63.         for k in kl.__bases__:
  64.             self._XMLParser__fixclass(k)
  65.         
  66.  
  67.     
  68.     def __fixdict(self, dict):
  69.         for key in dict.keys():
  70.             if key[:6] == 'start_':
  71.                 tag = key[6:]
  72.                 (start, end) = self.elements.get(tag, (None, None))
  73.                 if start is None:
  74.                     self.elements[tag] = (getattr(self, key), end)
  75.                 
  76.             elif key[:4] == 'end_':
  77.                 tag = key[4:]
  78.                 (start, end) = self.elements.get(tag, (None, None))
  79.                 if end is None:
  80.                     self.elements[tag] = (start, getattr(self, key))
  81.                 
  82.             
  83.         
  84.  
  85.     
  86.     def reset(self):
  87.         self.rawdata = ''
  88.         self.stack = []
  89.         self.nomoretags = 0
  90.         self.literal = 0
  91.         self.lineno = 1
  92.         self._XMLParser__at_start = 1
  93.         self._XMLParser__seen_doctype = None
  94.         self._XMLParser__seen_starttag = 0
  95.         self._XMLParser__use_namespaces = 0
  96.         self._XMLParser__namespaces = {
  97.             'xml': None }
  98.         if self.elements is XMLParser.elements:
  99.             self._XMLParser__fixelements()
  100.         
  101.  
  102.     
  103.     def setnomoretags(self):
  104.         self.nomoretags = self.literal = 1
  105.  
  106.     
  107.     def setliteral(self, *args):
  108.         self.literal = 1
  109.  
  110.     
  111.     def feed(self, data):
  112.         self.rawdata = self.rawdata + data
  113.         self.goahead(0)
  114.  
  115.     
  116.     def close(self):
  117.         self.goahead(1)
  118.         if self._XMLParser__fixed:
  119.             self._XMLParser__fixed = 0
  120.             del self.elements
  121.         
  122.  
  123.     
  124.     def translate_references(self, data, all = 1):
  125.         i = 0
  126.         while 1:
  127.             res = amp.search(data, i)
  128.             if res is None:
  129.                 return data
  130.             
  131.             res = ref.match(data, res.start(0))
  132.             if res is None:
  133.                 self.syntax_error("bogus `&'")
  134.                 i = i + 1
  135.                 continue
  136.             
  137.             i = res.end(0)
  138.             if data[i - 1] != ';':
  139.                 self.syntax_error("`;' missing after entity/char reference")
  140.                 i = i - 1
  141.             
  142.             str = res.group(1)
  143.             pre = data[:res.start(0)]
  144.             post = data[i:]
  145.             if str[0] == '#':
  146.                 if str[1] == 'x':
  147.                     str = chr(string.atoi(str[2:], 16))
  148.                 else:
  149.                     str = chr(string.atoi(str[1:]))
  150.                 data = pre + str + post
  151.                 i = res.start(0) + len(str)
  152.             elif all:
  153.                 if self.entitydefs.has_key(str):
  154.                     data = pre + self.entitydefs[str] + post
  155.                     i = res.start(0)
  156.                 else:
  157.                     self.syntax_error("reference to unknown entity `&%s;'" % str)
  158.                     data = pre + '&' + str + ';' + post
  159.                     i = res.start(0) + len(str) + 2
  160.             
  161.  
  162.     
  163.     def goahead(self, end):
  164.         rawdata = self.rawdata
  165.         i = 0
  166.         n = len(rawdata)
  167.         while i < n:
  168.             if i > 0:
  169.                 self._XMLParser__at_start = 0
  170.             
  171.             if self.nomoretags:
  172.                 data = rawdata[i:n]
  173.                 self.handle_data(data)
  174.                 self.lineno = self.lineno + string.count(data, '\n')
  175.                 i = n
  176.                 break
  177.             
  178.             res = interesting.search(rawdata, i)
  179.             if res:
  180.                 j = res.start(0)
  181.             else:
  182.                 j = n
  183.             if i < j:
  184.                 data = rawdata[i:j]
  185.                 if self._XMLParser__at_start and space.match(data) is None:
  186.                     self.syntax_error('illegal data at start of file')
  187.                 
  188.                 self._XMLParser__at_start = 0
  189.                 if not (self.stack) and space.match(data) is None:
  190.                     self.syntax_error('data not in content')
  191.                 
  192.                 if illegal.search(data):
  193.                     self.syntax_error('illegal character in content')
  194.                 
  195.                 self.handle_data(data)
  196.                 self.lineno = self.lineno + string.count(data, '\n')
  197.             
  198.             i = j
  199.             if i == n:
  200.                 break
  201.             
  202.             if rawdata[i] == '<':
  203.                 if starttagopen.match(rawdata, i):
  204.                     if self.literal:
  205.                         data = rawdata[i]
  206.                         self.handle_data(data)
  207.                         self.lineno = self.lineno + string.count(data, '\n')
  208.                         i = i + 1
  209.                         continue
  210.                     
  211.                     k = self.parse_starttag(i)
  212.                     if k < 0:
  213.                         break
  214.                     
  215.                     self._XMLParser__seen_starttag = 1
  216.                     self.lineno = self.lineno + string.count(rawdata[i:k], '\n')
  217.                     i = k
  218.                     continue
  219.                 
  220.                 if endtagopen.match(rawdata, i):
  221.                     k = self.parse_endtag(i)
  222.                     if k < 0:
  223.                         break
  224.                     
  225.                     self.lineno = self.lineno + string.count(rawdata[i:k], '\n')
  226.                     i = k
  227.                     continue
  228.                 
  229.                 if commentopen.match(rawdata, i):
  230.                     if self.literal:
  231.                         data = rawdata[i]
  232.                         self.handle_data(data)
  233.                         self.lineno = self.lineno + string.count(data, '\n')
  234.                         i = i + 1
  235.                         continue
  236.                     
  237.                     k = self.parse_comment(i)
  238.                     if k < 0:
  239.                         break
  240.                     
  241.                     self.lineno = self.lineno + string.count(rawdata[i:k], '\n')
  242.                     i = k
  243.                     continue
  244.                 
  245.                 if cdataopen.match(rawdata, i):
  246.                     k = self.parse_cdata(i)
  247.                     if k < 0:
  248.                         break
  249.                     
  250.                     self.lineno = self.lineno + string.count(rawdata[i:i], '\n')
  251.                     i = k
  252.                     continue
  253.                 
  254.                 res = xmldecl.match(rawdata, i)
  255.                 if res:
  256.                     if not (self._XMLParser__at_start):
  257.                         self.syntax_error('<?xml?> declaration not at start of document')
  258.                     
  259.                     (version, encoding, standalone) = res.group('version', 'encoding', 'standalone')
  260.                     if version[1:-1] != '1.0':
  261.                         raise RuntimeError, 'only XML version 1.0 supported'
  262.                     
  263.                     if encoding:
  264.                         encoding = encoding[1:-1]
  265.                     
  266.                     if standalone:
  267.                         standalone = standalone[1:-1]
  268.                     
  269.                     self.handle_xml(encoding, standalone)
  270.                     i = res.end(0)
  271.                     continue
  272.                 
  273.                 res = procopen.match(rawdata, i)
  274.                 if res:
  275.                     k = self.parse_proc(i)
  276.                     if k < 0:
  277.                         break
  278.                     
  279.                     self.lineno = self.lineno + string.count(rawdata[i:k], '\n')
  280.                     i = k
  281.                     continue
  282.                 
  283.                 res = doctype.match(rawdata, i)
  284.                 if res:
  285.                     if self.literal:
  286.                         data = rawdata[i]
  287.                         self.handle_data(data)
  288.                         self.lineno = self.lineno + string.count(data, '\n')
  289.                         i = i + 1
  290.                         continue
  291.                     
  292.                     if self._XMLParser__seen_doctype:
  293.                         self.syntax_error('multiple DOCTYPE elements')
  294.                     
  295.                     if self._XMLParser__seen_starttag:
  296.                         self.syntax_error('DOCTYPE not at beginning of document')
  297.                     
  298.                     k = self.parse_doctype(res)
  299.                     if k < 0:
  300.                         break
  301.                     
  302.                     self._XMLParser__seen_doctype = res.group('name')
  303.                     self.lineno = self.lineno + string.count(rawdata[i:k], '\n')
  304.                     i = k
  305.                     continue
  306.                 
  307.             elif rawdata[i] == '&':
  308.                 if self.literal:
  309.                     data = rawdata[i]
  310.                     self.handle_data(data)
  311.                     i = i + 1
  312.                     continue
  313.                 
  314.                 res = charref.match(rawdata, i)
  315.                 if res is not None:
  316.                     i = res.end(0)
  317.                     if rawdata[i - 1] != ';':
  318.                         self.syntax_error("`;' missing in charref")
  319.                         i = i - 1
  320.                     
  321.                     if not (self.stack):
  322.                         self.syntax_error('data not in content')
  323.                     
  324.                     self.handle_charref(res.group('char')[:-1])
  325.                     self.lineno = self.lineno + string.count(res.group(0), '\n')
  326.                     continue
  327.                 
  328.                 res = entityref.match(rawdata, i)
  329.                 if res is not None:
  330.                     i = res.end(0)
  331.                     if rawdata[i - 1] != ';':
  332.                         self.syntax_error("`;' missing in entityref")
  333.                         i = i - 1
  334.                     
  335.                     name = res.group('name')
  336.                     if self.entitydefs.has_key(name):
  337.                         self.rawdata = rawdata = rawdata[:res.start(0)] + self.entitydefs[name] + rawdata[i:]
  338.                         n = len(rawdata)
  339.                         i = res.start(0)
  340.                     else:
  341.                         self.syntax_error("reference to unknown entity `&%s;'" % name)
  342.                         self.unknown_entityref(name)
  343.                     self.lineno = self.lineno + string.count(res.group(0), '\n')
  344.                     continue
  345.                 
  346.             elif rawdata[i] == ']':
  347.                 if self.literal:
  348.                     data = rawdata[i]
  349.                     self.handle_data(data)
  350.                     i = i + 1
  351.                     continue
  352.                 
  353.                 if n - i < 3:
  354.                     break
  355.                 
  356.                 if cdataclose.match(rawdata, i):
  357.                     self.syntax_error("bogus `]]>'")
  358.                 
  359.                 self.handle_data(rawdata[i])
  360.                 i = i + 1
  361.                 continue
  362.             else:
  363.                 raise RuntimeError, 'neither < nor & ??'
  364.             break
  365.         if i > 0:
  366.             self._XMLParser__at_start = 0
  367.         
  368.         if end and i < n:
  369.             data = rawdata[i]
  370.             self.syntax_error("bogus `%s'" % data)
  371.             if illegal.search(data):
  372.                 self.syntax_error('illegal character in content')
  373.             
  374.             self.handle_data(data)
  375.             self.lineno = self.lineno + string.count(data, '\n')
  376.             self.rawdata = rawdata[i + 1:]
  377.             return self.goahead(end)
  378.         
  379.         self.rawdata = rawdata[i:]
  380.         if end:
  381.             if not (self._XMLParser__seen_starttag):
  382.                 self.syntax_error('no elements in file')
  383.             
  384.             if self.stack:
  385.                 self.syntax_error('missing end tags')
  386.                 while self.stack:
  387.                     self.finish_endtag(self.stack[-1][0])
  388.             
  389.         
  390.  
  391.     
  392.     def parse_comment(self, i):
  393.         rawdata = self.rawdata
  394.         if rawdata[i:i + 4] != '<!--':
  395.             raise RuntimeError, 'unexpected call to handle_comment'
  396.         
  397.         res = commentclose.search(rawdata, i + 4)
  398.         if res is None:
  399.             return -1
  400.         
  401.         if doubledash.search(rawdata, i + 4, res.start(0)):
  402.             self.syntax_error("`--' inside comment")
  403.         
  404.         if rawdata[res.start(0) - 1] == '-':
  405.             self.syntax_error('comment cannot end in three dashes')
  406.         
  407.         if illegal.search(rawdata, i + 4, res.start(0)):
  408.             self.syntax_error('illegal character in comment')
  409.         
  410.         self.handle_comment(rawdata[i + 4:res.start(0)])
  411.         return res.end(0)
  412.  
  413.     
  414.     def parse_doctype(self, res):
  415.         rawdata = self.rawdata
  416.         n = len(rawdata)
  417.         name = res.group('name')
  418.         (pubid, syslit) = res.group('pubid', 'syslit')
  419.         if pubid is not None:
  420.             pubid = pubid[1:-1]
  421.             pubid = string.join(string.split(pubid))
  422.         
  423.         if syslit is not None:
  424.             syslit = syslit[1:-1]
  425.         
  426.         j = k = res.end(0)
  427.         if k >= n:
  428.             return -1
  429.         
  430.         if rawdata[k] == '[':
  431.             level = 0
  432.             k = k + 1
  433.             dq = sq = 0
  434.             while k < n:
  435.                 c = rawdata[k]
  436.                 if not sq and c == '"':
  437.                     dq = not dq
  438.                 elif not dq and c == "'":
  439.                     sq = not sq
  440.                 elif sq or dq:
  441.                     pass
  442.                 elif level <= 0 and c == ']':
  443.                     res = endbracket.match(rawdata, k + 1)
  444.                     if res is None:
  445.                         return -1
  446.                     
  447.                     self.handle_doctype(name, pubid, syslit, rawdata[j + 1:k])
  448.                     return res.end(0)
  449.                 elif c == '<':
  450.                     level = level + 1
  451.                 elif c == '>':
  452.                     level = level - 1
  453.                     if level < 0:
  454.                         self.syntax_error("bogus `>' in DOCTYPE")
  455.                     
  456.                 
  457.                 k = k + 1
  458.         
  459.         res = endbracketfind.match(rawdata, k)
  460.         if res is None:
  461.             return -1
  462.         
  463.         if endbracket.match(rawdata, k) is None:
  464.             self.syntax_error('garbage in DOCTYPE')
  465.         
  466.         self.handle_doctype(name, pubid, syslit, None)
  467.         return res.end(0)
  468.  
  469.     
  470.     def parse_cdata(self, i):
  471.         rawdata = self.rawdata
  472.         if rawdata[i:i + 9] != '<![CDATA[':
  473.             raise RuntimeError, 'unexpected call to parse_cdata'
  474.         
  475.         res = cdataclose.search(rawdata, i + 9)
  476.         if res is None:
  477.             return -1
  478.         
  479.         if illegal.search(rawdata, i + 9, res.start(0)):
  480.             self.syntax_error('illegal character in CDATA')
  481.         
  482.         if not (self.stack):
  483.             self.syntax_error('CDATA not in content')
  484.         
  485.         self.handle_cdata(rawdata[i + 9:res.start(0)])
  486.         return res.end(0)
  487.  
  488.     __xml_namespace_attributes = {
  489.         'ns': None,
  490.         'src': None,
  491.         'prefix': None }
  492.     
  493.     def parse_proc(self, i):
  494.         rawdata = self.rawdata
  495.         end = procclose.search(rawdata, i)
  496.         if end is None:
  497.             return -1
  498.         
  499.         j = end.start(0)
  500.         if illegal.search(rawdata, i + 2, j):
  501.             self.syntax_error('illegal character in processing instruction')
  502.         
  503.         res = tagfind.match(rawdata, i + 2)
  504.         if res is None:
  505.             raise RuntimeError, 'unexpected call to parse_proc'
  506.         
  507.         k = res.end(0)
  508.         name = res.group(0)
  509.         if name == 'xml:namespace':
  510.             self.syntax_error('old-fashioned namespace declaration')
  511.             self._XMLParser__use_namespaces = -1
  512.             if self._XMLParser__seen_doctype or self._XMLParser__seen_starttag:
  513.                 self.syntax_error('xml:namespace declaration too late in document')
  514.             
  515.             (attrdict, namespace, k) = self.parse_attributes(name, k, j)
  516.             if namespace:
  517.                 self.syntax_error('namespace declaration inside namespace declaration')
  518.             
  519.             for attrname in attrdict.keys():
  520.                 pass
  521.             
  522.             if not attrdict.has_key('ns') or not attrdict.has_key('prefix'):
  523.                 self.syntax_error('xml:namespace without required attributes')
  524.             
  525.             prefix = attrdict.get('prefix')
  526.             if ncname.match(prefix) is None:
  527.                 self.syntax_error('xml:namespace illegal prefix value')
  528.                 return end.end(0)
  529.             
  530.             if self._XMLParser__namespaces.has_key(prefix):
  531.                 self.syntax_error('xml:namespace prefix not unique')
  532.             
  533.             self._XMLParser__namespaces[prefix] = attrdict['ns']
  534.         elif string.find(string.lower(name), 'xml') >= 0:
  535.             self.syntax_error('illegal processing instruction target name')
  536.         
  537.         self.handle_proc(name, rawdata[k:j])
  538.         return end.end(0)
  539.  
  540.     
  541.     def parse_attributes(self, tag, i, j):
  542.         rawdata = self.rawdata
  543.         attrdict = { }
  544.         namespace = { }
  545.         while i < j:
  546.             res = attrfind.match(rawdata, i)
  547.             if res is None:
  548.                 break
  549.             
  550.             (attrname, attrvalue) = res.group('name', 'value')
  551.             i = res.end(0)
  552.             if attrvalue is None:
  553.                 self.syntax_error("no value specified for attribute `%s'" % attrname)
  554.                 attrvalue = attrname
  555.             elif "'" == "'":
  556.                 pass
  557.             elif not "'" == attrvalue[-1:]:
  558.                 if '"' == '"':
  559.                     pass
  560.                 elif '"' == attrvalue[-1:]:
  561.                     attrvalue = attrvalue[1:-1]
  562.                 else:
  563.                     self.syntax_error("attribute `%s' value not quoted" % attrname)
  564.             res = xmlns.match(attrname)
  565.             if '<' in attrvalue:
  566.                 self.syntax_error("`<' illegal in attribute value")
  567.             
  568.             if attrdict.has_key(attrname):
  569.                 self.syntax_error("attribute `%s' specified twice" % attrname)
  570.             
  571.             attrvalue = string.translate(attrvalue, attrtrans)
  572.             attrdict[attrname] = self.translate_references(attrvalue)
  573.         return (attrdict, namespace, i)
  574.  
  575.     
  576.     def parse_starttag(self, i):
  577.         rawdata = self.rawdata
  578.         end = endbracketfind.match(rawdata, i + 1)
  579.         if end is None:
  580.             return -1
  581.         
  582.         tag = starttagmatch.match(rawdata, i)
  583.         if tag is None or tag.end(0) != end.end(0):
  584.             self.syntax_error('garbage in starttag')
  585.             return end.end(0)
  586.         
  587.         nstag = tagname = tag.group('tagname')
  588.         if not (self._XMLParser__seen_starttag) and self._XMLParser__seen_doctype and tagname != self._XMLParser__seen_doctype:
  589.             self.syntax_error('starttag does not match DOCTYPE')
  590.         
  591.         if self._XMLParser__seen_starttag and not (self.stack):
  592.             self.syntax_error('multiple elements on top level')
  593.         
  594.         (k, j) = tag.span('attrs')
  595.         (attrdict, nsdict, k) = self.parse_attributes(tagname, k, j)
  596.         self.stack.append((tagname, nsdict, nstag))
  597.         if self._XMLParser__use_namespaces:
  598.             res = qname.match(tagname)
  599.         else:
  600.             res = None
  601.         if res is not None:
  602.             (prefix, nstag) = res.group('prefix', 'local')
  603.             if prefix is None:
  604.                 prefix = ''
  605.             
  606.             ns = None
  607.             for t, d, nst in self.stack:
  608.                 pass
  609.             
  610.             if ns is None and prefix != '':
  611.                 ns = self._XMLParser__namespaces.get(prefix)
  612.             
  613.             if ns is not None:
  614.                 nstag = ns + ' ' + nstag
  615.             elif prefix != '':
  616.                 nstag = prefix + ':' + nstag
  617.             
  618.             self.stack[-1] = (tagname, nsdict, nstag)
  619.         
  620.         if self._XMLParser__use_namespaces:
  621.             nattrdict = { }
  622.             for key, val in attrdict.items():
  623.                 res = qname.match(key)
  624.                 if res is not None:
  625.                     (aprefix, key) = res.group('prefix', 'local')
  626.                     ans = None
  627.                     for t, d, nst in self.stack:
  628.                         pass
  629.                     
  630.                     if ans is None and aprefix != '':
  631.                         ans = self._XMLParser__namespaces.get(aprefix)
  632.                     
  633.                     if ans is not None:
  634.                         key = ans + ' ' + key
  635.                     elif aprefix != '':
  636.                         key = aprefix + ':' + key
  637.                     elif ns is not None:
  638.                         key = ns + ' ' + key
  639.                     
  640.                 
  641.                 nattrdict[key] = val
  642.             
  643.             attrdict = nattrdict
  644.         
  645.         attributes = self.attributes.get(nstag)
  646.         if attributes is not None:
  647.             for key in attrdict.keys():
  648.                 pass
  649.             
  650.             for key, val in attributes.items():
  651.                 pass
  652.             
  653.         
  654.         method = self.elements.get(nstag, (None, None))[0]
  655.         self.finish_starttag(nstag, attrdict, method)
  656.         if tag.group('slash') == '/':
  657.             self.finish_endtag(tagname)
  658.         
  659.         return tag.end(0)
  660.  
  661.     
  662.     def parse_endtag(self, i):
  663.         rawdata = self.rawdata
  664.         end = endbracketfind.match(rawdata, i + 1)
  665.         if end is None:
  666.             return -1
  667.         
  668.         res = tagfind.match(rawdata, i + 2)
  669.         if res is None:
  670.             if self.literal:
  671.                 self.handle_data(rawdata[i])
  672.                 return i + 1
  673.             
  674.             self.syntax_error('no name specified in end tag')
  675.             tag = ''
  676.             k = i + 2
  677.         else:
  678.             tag = res.group(0)
  679.             if self.literal:
  680.                 if not (self.stack) or tag != self.stack[-1][0]:
  681.                     self.handle_data(rawdata[i])
  682.                     return i + 1
  683.                 
  684.                 self.literal = 0
  685.             
  686.             k = res.end(0)
  687.         if endbracket.match(rawdata, k) is None:
  688.             self.syntax_error('garbage in end tag')
  689.         
  690.         self.finish_endtag(tag)
  691.         return end.end(0)
  692.  
  693.     
  694.     def finish_starttag(self, tagname, attrdict, method):
  695.         if method is not None:
  696.             self.handle_starttag(tagname, method, attrdict)
  697.         else:
  698.             self.unknown_starttag(tagname, attrdict)
  699.  
  700.     
  701.     def finish_endtag(self, tag):
  702.         while len(self.stack) > found:
  703.             if found < len(self.stack) - 1:
  704.                 self.syntax_error('missing close tag for %s' % self.stack[-1][2])
  705.             
  706.             nstag = self.stack[-1][2]
  707.             method = self.elements.get(nstag, (None, None))[1]
  708.             if method is not None:
  709.                 self.handle_endtag(nstag, method)
  710.             else:
  711.                 self.unknown_endtag(nstag)
  712.             if self._XMLParser__use_namespaces == len(self.stack):
  713.                 self._XMLParser__use_namespaces = 0
  714.             
  715.             del self.stack[-1]
  716.  
  717.     
  718.     def handle_xml(self, encoding, standalone):
  719.         pass
  720.  
  721.     
  722.     def handle_doctype(self, tag, pubid, syslit, data):
  723.         pass
  724.  
  725.     
  726.     def handle_starttag(self, tag, method, attrs):
  727.         method(attrs)
  728.  
  729.     
  730.     def handle_endtag(self, tag, method):
  731.         method()
  732.  
  733.     
  734.     def handle_charref(self, name):
  735.         
  736.         try:
  737.             if name[0] == 'x':
  738.                 n = string.atoi(name[1:], 16)
  739.             else:
  740.                 n = string.atoi(name)
  741.         except string.atoi_error:
  742.             self.unknown_charref(name)
  743.             return None
  744.  
  745.         if not None if n <= n else n <= 255:
  746.             self.unknown_charref(name)
  747.             return None
  748.         
  749.         self.handle_data(chr(n))
  750.  
  751.     entitydefs = {
  752.         'lt': '<',
  753.         'gt': '>',
  754.         'amp': '&',
  755.         'quot': '"',
  756.         'apos': ''' }
  757.     
  758.     def handle_entityref(self, name):
  759.         table = self.entitydefs
  760.         if table.has_key(name):
  761.             self.handle_data(table[name])
  762.         else:
  763.             self.unknown_entityref(name)
  764.             return None
  765.  
  766.     
  767.     def handle_data(self, data):
  768.         pass
  769.  
  770.     
  771.     def handle_cdata(self, data):
  772.         pass
  773.  
  774.     
  775.     def handle_comment(self, data):
  776.         pass
  777.  
  778.     
  779.     def handle_proc(self, name, data):
  780.         pass
  781.  
  782.     
  783.     def syntax_error(self, message):
  784.         raise RuntimeError, 'Syntax error at line %d: %s' % (self.lineno, message)
  785.  
  786.     
  787.     def unknown_starttag(self, tag, attrs):
  788.         pass
  789.  
  790.     
  791.     def unknown_endtag(self, tag):
  792.         pass
  793.  
  794.     
  795.     def unknown_charref(self, ref):
  796.         pass
  797.  
  798.     
  799.     def unknown_entityref(self, ref):
  800.         pass
  801.  
  802.  
  803.  
  804. class TestXMLParser(XMLParser):
  805.     
  806.     def __init__(self):
  807.         self.testdata = ''
  808.         XMLParser.__init__(self)
  809.  
  810.     
  811.     def handle_xml(self, encoding, standalone):
  812.         self.flush()
  813.         print 'xml: encoding =', encoding, 'standalone =', standalone
  814.  
  815.     
  816.     def handle_doctype(self, tag, pubid, syslit, data):
  817.         self.flush()
  818.         print 'DOCTYPE:', tag, `data`
  819.  
  820.     
  821.     def handle_entity(self, name, strval, pubid, syslit, ndata):
  822.         self.flush()
  823.         print 'ENTITY:', `data`
  824.  
  825.     
  826.     def handle_data(self, data):
  827.         self.testdata = self.testdata + data
  828.         if len(`self.testdata`) >= 70:
  829.             self.flush()
  830.         
  831.  
  832.     
  833.     def flush(self):
  834.         data = self.testdata
  835.         if data:
  836.             self.testdata = ''
  837.             print 'data:', `data`
  838.         
  839.  
  840.     
  841.     def handle_cdata(self, data):
  842.         self.flush()
  843.         print 'cdata:', `data`
  844.  
  845.     
  846.     def handle_proc(self, name, data):
  847.         self.flush()
  848.         print 'processing:', name, `data`
  849.  
  850.     
  851.     def handle_comment(self, data):
  852.         self.flush()
  853.         r = `data`
  854.         if len(r) > 68:
  855.             r = r[:32] + '...' + r[-32:]
  856.         
  857.         print 'comment:', r
  858.  
  859.     
  860.     def syntax_error(self, message):
  861.         print 'error at line %d:' % self.lineno, message
  862.  
  863.     
  864.     def unknown_starttag(self, tag, attrs):
  865.         self.flush()
  866.  
  867.     
  868.     def unknown_endtag(self, tag):
  869.         self.flush()
  870.         print 'end tag: </' + tag + '>'
  871.  
  872.     
  873.     def unknown_entityref(self, ref):
  874.         self.flush()
  875.         print '*** unknown entity ref: &' + ref + ';'
  876.  
  877.     
  878.     def unknown_charref(self, ref):
  879.         self.flush()
  880.         print '*** unknown char ref: &#' + ref + ';'
  881.  
  882.     
  883.     def close(self):
  884.         XMLParser.close(self)
  885.         self.flush()
  886.  
  887.  
  888.  
  889. def test(args = None):
  890.     import sys
  891.     import getopt
  892.     time
  893.     if not args:
  894.         args = sys.argv[1:]
  895.     
  896.     (opts, args) = getopt.getopt(args, 'st')
  897.     klass = TestXMLParser
  898.     do_time = 0
  899.     for o, a in opts:
  900.         if o == '-s':
  901.             klass = XMLParser
  902.         elif o == '-t':
  903.             do_time = 1
  904.         
  905.     
  906.     if args:
  907.         file = args[0]
  908.     else:
  909.         file = 'test.xml'
  910.     if file == '-':
  911.         f = sys.stdin
  912.     else:
  913.         
  914.         try:
  915.             f = open(file, 'r')
  916.         except IOError:
  917.             msg = None
  918.             print file, ':', msg
  919.             sys.exit(1)
  920.  
  921.     data = f.read()
  922.     if f is not sys.stdin:
  923.         f.close()
  924.     
  925.     x = klass()
  926.     t0 = time()
  927.     
  928.     try:
  929.         if do_time:
  930.             x.feed(data)
  931.             x.close()
  932.         else:
  933.             for c in data:
  934.                 x.feed(c)
  935.             
  936.             x.close()
  937.     except RuntimeError:
  938.         msg = None
  939.         t1 = time()
  940.         print msg
  941.         if do_time:
  942.             print 'total time: %g' % (t1 - t0)
  943.         
  944.         sys.exit(1)
  945.  
  946.     t1 = time()
  947.     if do_time:
  948.         print 'total time: %g' % (t1 - t0)
  949.     
  950.  
  951. if __name__ == '__main__':
  952.     test()
  953.  
  954.