blob: d288e9d700e6d2e55b65ab3f2322a635bdb39d43 [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
Lars Gustäbelc5cec512000-09-21 08:25:28 +000026 def __init__(self, out=None, encoding="iso-8859-1"):
Fred Drakea12adfe2000-09-18 17:40:22 +000027 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
Lars Gustäbelc5cec512000-09-21 08:25:28 +000032 self._ns_contexts = [{}] # contains uri -> prefix dicts
33 self._current_context = self._ns_contexts[-1]
34 self._encoding = encoding
Fred Drake45cd9de2000-06-29 19:34:54 +000035
36 # ContentHandler methods
Fred Drakea12adfe2000-09-18 17:40:22 +000037
Fred Drake45cd9de2000-06-29 19:34:54 +000038 def startDocument(self):
Lars Gustäbelc5cec512000-09-21 08:25:28 +000039 self._out.write('<?xml version="1.0" encoding="%s"?>\n' %
40 self._encoding)
Fred Drake45cd9de2000-06-29 19:34:54 +000041
42 def startPrefixMapping(self, prefix, uri):
Lars Gustäbelc5cec512000-09-21 08:25:28 +000043 self._ns_contexts.append(self._current_context.copy())
44 self._current_context[uri] = prefix
Fred Drake45cd9de2000-06-29 19:34:54 +000045
46 def endPrefixMapping(self, prefix):
Lars Gustäbelc5cec512000-09-21 08:25:28 +000047 del self._current_context[-1]
Fred Drake45cd9de2000-06-29 19:34:54 +000048
49 def startElement(self, name, attrs):
Fred Drake45cd9de2000-06-29 19:34:54 +000050 self._out.write('<' + name)
51 for (name, value) in attrs.items():
52 self._out.write(' %s="%s"' % (name, escape(value)))
53 self._out.write('>')
Lars Gustäbelc5cec512000-09-21 08:25:28 +000054
Fred Drake45cd9de2000-06-29 19:34:54 +000055 def endElement(self, name):
Fred Drake45cd9de2000-06-29 19:34:54 +000056 self._out.write('</%s>' % name)
57
Lars Gustäbelc5cec512000-09-21 08:25:28 +000058 def startElementNS(self, name, qname, attrs):
59 name = self._current_context[name[0]] + ":" + name[1]
60 self._out.write('<' + name)
61 for (name, value) in attrs.items():
62 name = self._current_context[name[0]] + ":" + name[1]
63 self._out.write(' %s="%s"' % (name, escape(value)))
64 self._out.write('>')
65
66 def endElementNS(self, name, qname):
67 name = self._current_context[name[0]] + ":" + name[1]
68 self._out.write('</%s>' % name)
69
Fred Drake45cd9de2000-06-29 19:34:54 +000070 def characters(self, content):
71 self._out.write(escape(content))
72
73 def ignorableWhitespace(self, content):
74 self._out.write(content)
Fred Drakea12adfe2000-09-18 17:40:22 +000075
Fred Drake45cd9de2000-06-29 19:34:54 +000076 def processingInstruction(self, target, data):
77 self._out.write('<?%s %s?>' % (target, data))
78
Fred Drakea12adfe2000-09-18 17:40:22 +000079
Fred Drake45cd9de2000-06-29 19:34:54 +000080class XMLFilterBase:
81 """This class is designed to sit between an XMLReader and the
82 client application's event handlers. By default, it does nothing
83 but pass requests up to the reader and events on to the handlers
84 unmodified, but subclasses can override specific methods to modify
85 the event stream or the configuration requests as they pass
86 through."""
87
88 # ErrorHandler methods
89
90 def error(self, exception):
91 self._err_handler.error(exception)
92
93 def fatalError(self, exception):
94 self._err_handler.fatalError(exception)
95
96 def warning(self, exception):
97 self._err_handler.warning(exception)
98
99 # ContentHandler methods
Fred Drakea12adfe2000-09-18 17:40:22 +0000100
Fred Drake45cd9de2000-06-29 19:34:54 +0000101 def setDocumentLocator(self, locator):
102 self._cont_handler.setDocumentLocator(locator)
Fred Drakea12adfe2000-09-18 17:40:22 +0000103
Fred Drake45cd9de2000-06-29 19:34:54 +0000104 def startDocument(self):
105 self._cont_handler.startDocument()
106
107 def endDocument(self):
108 self._cont_handler.endDocument()
109
110 def startPrefixMapping(self, prefix, uri):
111 self._cont_handler.startPrefixMapping(prefix, uri)
112
113 def endPrefixMapping(self, prefix):
114 self._cont_handler.endPrefixMapping(prefix)
115
116 def startElement(self, name, attrs):
117 self._cont_handler.startElement(name, attrs)
118
Lars Gustäbelc5cec512000-09-21 08:25:28 +0000119 def endElement(self, name):
120 self._cont_handler.endElement(name)
121
122 def startElementNS(self, name, qname, attrs):
123 self._cont_handler.startElement(name, attrs)
124
125 def endElementNS(self, name, qname):
126 self._cont_handler.endElementNS(name, qname)
Fred Drake45cd9de2000-06-29 19:34:54 +0000127
128 def characters(self, content):
129 self._cont_handler.characters(content)
130
131 def ignorableWhitespace(self, chars, start, end):
132 self._cont_handler.ignorableWhitespace(chars, start, end)
133
134 def processingInstruction(self, target, data):
135 self._cont_handler.processingInstruction(target, data)
136
137 def skippedEntity(self, name):
138 self._cont_handler.skippedEntity(name)
139
140 # DTDHandler methods
141
142 def notationDecl(self, name, publicId, systemId):
143 self._dtd_handler.notationDecl(name, publicId, systemId)
144
145 def unparsedEntityDecl(self, name, publicId, systemId, ndata):
146 self._dtd_handler.unparsedEntityDecl(name, publicId, systemId, ndata)
147
148 # EntityResolver methods
149
150 def resolveEntity(self, publicId, systemId):
151 self._ent_handler.resolveEntity(publicId, systemId)
152
153 # XMLReader methods
154
155 def parse(self, source):
156 self._parent.setContentHandler(self)
157 self._parent.setErrorHandler(self)
158 self._parent.setEntityResolver(self)
159 self._parent.setDTDHandler(self)
160 self._parent.parse(source)
161
162 def setLocale(self, locale):
163 self._parent.setLocale(locale)
Fred Drakea12adfe2000-09-18 17:40:22 +0000164
Fred Drake45cd9de2000-06-29 19:34:54 +0000165 def getFeature(self, name):
166 return self._parent.getFeature(name)
167
168 def setFeature(self, name, state):
169 self._parent.setFeature(name, state)
170
171 def getProperty(self, name):
172 return self._parent.getProperty(name)
173
174 def setProperty(self, name, value):
175 self._parent.setProperty(name, value)