blob: cd6426a15b4b8a4bd76950c6e75c9548d422d365 [file] [log] [blame]
Fred Drakea12adfe2000-09-18 17:40:22 +00001"""\
2A library of useful helper classes to the SAX classes, for the
Fred Drake45cd9de2000-06-29 19:34:54 +00003convenience of application and driver writers.
Fred Drake45cd9de2000-06-29 19:34:54 +00004"""
5
Fred Drake45cd9de2000-06-29 19:34:54 +00006import handler
7
Fred Drakea12adfe2000-09-18 17:40:22 +00008
9def escape(data, entities={}):
Fred Drake45cd9de2000-06-29 19:34:54 +000010 """Escape &, <, and > in a string of data.
Fred Drakea12adfe2000-09-18 17:40:22 +000011
Fred Drake45cd9de2000-06-29 19:34:54 +000012 You can escape other strings of data by passing a dictionary as
13 the optional entities parameter. The keys and values must all be
14 strings; each key will be replaced with its corresponding value.
15 """
Fred Drakea12adfe2000-09-18 17:40:22 +000016 data = data.replace("&", "&amp;")
17 data = data.replace("<", "&lt;")
18 data = data.replace(">", "&gt;")
Fred Drake45cd9de2000-06-29 19:34:54 +000019 for chars, entity in entities.items():
Fred Drakea12adfe2000-09-18 17:40:22 +000020 data = data.replace(chars, entity)
Fred Drake45cd9de2000-06-29 19:34:54 +000021 return data
22
Fred Drakea12adfe2000-09-18 17:40:22 +000023
Fred Drake45cd9de2000-06-29 19:34:54 +000024class XMLGenerator(handler.ContentHandler):
25
Fred Drakea12adfe2000-09-18 17:40:22 +000026 def __init__(self, out=None):
27 if out is None:
28 import sys
29 out = sys.stdout
Fred Drake45cd9de2000-06-29 19:34:54 +000030 handler.ContentHandler.__init__(self)
31 self._out = out
32
33 # ContentHandler methods
Fred Drakea12adfe2000-09-18 17:40:22 +000034
Fred Drake45cd9de2000-06-29 19:34:54 +000035 def startDocument(self):
36 self._out.write('<?xml version="1.0" encoding="iso-8859-1"?>\n')
37
38 def startPrefixMapping(self, prefix, uri):
39 pass
40
41 def endPrefixMapping(self, prefix):
42 pass
43
44 def startElement(self, name, attrs):
Fred Drakea12adfe2000-09-18 17:40:22 +000045 if type(name) is type(()):
46 uri, localname, prefix = name
47 name = "%s:%s"%(prefix,localname)
Fred Drake45cd9de2000-06-29 19:34:54 +000048 self._out.write('<' + name)
49 for (name, value) in attrs.items():
50 self._out.write(' %s="%s"' % (name, escape(value)))
51 self._out.write('>')
52
53 def endElement(self, name):
54 # FIXME: not namespace friendly yet
55 self._out.write('</%s>' % name)
56
57 def characters(self, content):
58 self._out.write(escape(content))
59
60 def ignorableWhitespace(self, content):
61 self._out.write(content)
Fred Drakea12adfe2000-09-18 17:40:22 +000062
Fred Drake45cd9de2000-06-29 19:34:54 +000063 def processingInstruction(self, target, data):
64 self._out.write('<?%s %s?>' % (target, data))
65
Fred Drakea12adfe2000-09-18 17:40:22 +000066
Fred Drake45cd9de2000-06-29 19:34:54 +000067class XMLFilterBase:
68 """This class is designed to sit between an XMLReader and the
69 client application's event handlers. By default, it does nothing
70 but pass requests up to the reader and events on to the handlers
71 unmodified, but subclasses can override specific methods to modify
72 the event stream or the configuration requests as they pass
73 through."""
74
75 # ErrorHandler methods
76
77 def error(self, exception):
78 self._err_handler.error(exception)
79
80 def fatalError(self, exception):
81 self._err_handler.fatalError(exception)
82
83 def warning(self, exception):
84 self._err_handler.warning(exception)
85
86 # ContentHandler methods
Fred Drakea12adfe2000-09-18 17:40:22 +000087
Fred Drake45cd9de2000-06-29 19:34:54 +000088 def setDocumentLocator(self, locator):
89 self._cont_handler.setDocumentLocator(locator)
Fred Drakea12adfe2000-09-18 17:40:22 +000090
Fred Drake45cd9de2000-06-29 19:34:54 +000091 def startDocument(self):
92 self._cont_handler.startDocument()
93
94 def endDocument(self):
95 self._cont_handler.endDocument()
96
97 def startPrefixMapping(self, prefix, uri):
98 self._cont_handler.startPrefixMapping(prefix, uri)
99
100 def endPrefixMapping(self, prefix):
101 self._cont_handler.endPrefixMapping(prefix)
102
103 def startElement(self, name, attrs):
104 self._cont_handler.startElement(name, attrs)
105
106 def endElement(self, name, qname):
107 self._cont_handler.endElement(name, qname)
108
109 def characters(self, content):
110 self._cont_handler.characters(content)
111
112 def ignorableWhitespace(self, chars, start, end):
113 self._cont_handler.ignorableWhitespace(chars, start, end)
114
115 def processingInstruction(self, target, data):
116 self._cont_handler.processingInstruction(target, data)
117
118 def skippedEntity(self, name):
119 self._cont_handler.skippedEntity(name)
120
121 # DTDHandler methods
122
123 def notationDecl(self, name, publicId, systemId):
124 self._dtd_handler.notationDecl(name, publicId, systemId)
125
126 def unparsedEntityDecl(self, name, publicId, systemId, ndata):
127 self._dtd_handler.unparsedEntityDecl(name, publicId, systemId, ndata)
128
129 # EntityResolver methods
130
131 def resolveEntity(self, publicId, systemId):
132 self._ent_handler.resolveEntity(publicId, systemId)
133
134 # XMLReader methods
135
136 def parse(self, source):
137 self._parent.setContentHandler(self)
138 self._parent.setErrorHandler(self)
139 self._parent.setEntityResolver(self)
140 self._parent.setDTDHandler(self)
141 self._parent.parse(source)
142
143 def setLocale(self, locale):
144 self._parent.setLocale(locale)
Fred Drakea12adfe2000-09-18 17:40:22 +0000145
Fred Drake45cd9de2000-06-29 19:34:54 +0000146 def getFeature(self, name):
147 return self._parent.getFeature(name)
148
149 def setFeature(self, name, state):
150 self._parent.setFeature(name, state)
151
152 def getProperty(self, name):
153 return self._parent.getProperty(name)
154
155 def setProperty(self, name, value):
156 self._parent.setProperty(name, value)