listing22-3.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from xml.sax.handler import ContentHandler
  2. from xml.sax import parse
  3. import os
  4. class Dispatcher:
  5. def dispatch(self, prefix, name, attrs=None):
  6. mname = prefix + name.capitalize()
  7. dname = 'default' + prefix.capitalize()
  8. method = getattr(self, mname, None)
  9. if callable(method): args = ()
  10. else:
  11. method = getattr(self, dname, None)
  12. args = name,
  13. if prefix == 'start': args += attrs,
  14. if callable(method): method(*args)
  15. def startElement(self, name, attrs):
  16. self.dispatch('start', name, attrs)
  17. def endElement(self, name):
  18. self.dispatch('end', name)
  19. class WebsiteConstructor(Dispatcher, ContentHandler):
  20. passthrough = False
  21. def __init__(self, directory):
  22. self.directory = [directory]
  23. self.ensureDirectory()
  24. def ensureDirectory(self):
  25. path = os.path.join(*self.directory)
  26. os.makedirs(path, exist_ok=True)
  27. def characters(self, chars):
  28. if self.passthrough: self.out.write(chars)
  29. def defaultStart(self, name, attrs):
  30. if self.passthrough:
  31. self.out.write('<' + name)
  32. for key, val in attrs.items():
  33. self.out.write(' {}="{}"'.format(key, val))
  34. self.out.write('>')
  35. def defaultEnd(self, name):
  36. if self.passthrough:
  37. self.out.write('</{}>'.format(name))
  38. def startDirectory(self, attrs):
  39. self.directory.append(attrs['name'])
  40. self.ensureDirectory()
  41. def endDirectory(self):
  42. self.directory.pop()
  43. def startPage(self, attrs):
  44. filename = os.path.join(*self.directory + [attrs['name'] + '.html'])
  45. self.out = open(filename, 'w')
  46. self.writeHeader(attrs['title'])
  47. self.passthrough = True
  48. def endPage(self):
  49. self.passthrough = False
  50. self.writeFooter()
  51. self.out.close()
  52. def writeHeader(self, title):
  53. self.out.write('<html>\n <head>\n <title>')
  54. self.out.write(title)
  55. self.out.write('</title>\n </head>\n <body>\n')
  56. def writeFooter(self):
  57. self.out.write('\n </body>\n</html>\n')
  58. parse('website.xml', WebsiteConstructor('public_html'))