E5XML/XMLHandlerBase.py

changeset 609
463fc2891cbf
parent 608
d8fea1e76975
child 613
5a6ee2af8ec0
equal deleted inserted replaced
608:d8fea1e76975 609:463fc2891cbf
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2004 - 2010 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a base class for all of eric5s XML handlers.
8 """
9
10 import pickle
11 import base64
12
13 from xml.sax.handler import ContentHandler
14
15 class XMLHandlerBase(ContentHandler):
16 """
17 Class implementing the base class for al of eric5s XML handlers.
18 """
19 def __init__(self):
20 """
21 Constructor
22 """
23 self.startDocumentSpecific = None
24
25 self.elements = {
26 'none' : (self.defaultStartElement, self.endNone),
27 'int' : (self.defaultStartElement, self.endInt),
28 'float' : (self.defaultStartElement, self.endFloat),
29 'complex' : (self.defaultStartElement, self.endComplex),
30 'bool' : (self.defaultStartElement, self.endBool),
31 'string' : (self.defaultStartElement, self.endString),
32 'bytes' : (self.defaultStartElement, self.endBytes),
33 'bytearray' : (self.defaultStartElement, self.endBytearray),
34 'tuple' : (self.startTuple, self.endTuple),
35 'list' : (self.startList, self.endList),
36 'dict' : (self.startDictionary, self.endDictionary),
37 'set' : (self.startSet, self.endSet),
38 'frozenset' : (self.startFrozenset, self.endFrozenset),
39 'pickle' : (self.startPickle, self.endPickle),
40 # for backward compatibility
41 'long' : (self.defaultStartElement, self.endInt),
42 'unicode' : (self.defaultStartElement, self.endString),
43 }
44
45 self.buffer = ""
46 self.stack = []
47 self._marker = '__MARKER__'
48
49 self.NEWPARA = chr(0x2029)
50 self.NEWLINE = chr(0x2028)
51
52 def unescape(self, text, attribute = False):
53 """
54 Public method used to unescape certain characters.
55
56 @param text the text to unescape (string)
57 @param attribute flag indicating unescaping is done for an attribute
58 """
59 if attribute:
60 return text.replace("&quot;",'"').replace("&gt;",">")\
61 .replace("&lt;","<").replace("&amp;","&")
62 else:
63 return text.replace("&gt;",">").replace("&lt;","<").replace("&amp;","&")
64
65 def decodedNewLines(self, text):
66 """
67 Public method to decode newlines and paragraph breaks.
68
69 @param text text to decode (string)
70 """
71 return text.replace(self.NEWPARA, "\n\n").replace(self.NEWLINE, "\n")
72
73 def startDocument(self):
74 """
75 Handler called, when the document parsing is started.
76 """
77 self.buffer = ""
78 if self.startDocumentSpecific is not None:
79 self.startDocumentSpecific()
80
81 def startElement(self, name, attrs):
82 """
83 Handler called, when a starting tag is found.
84
85 @param name name of the tag (string)
86 @param attrs list of tag attributes
87 """
88 try:
89 self.elements[name][0](attrs)
90 except KeyError:
91 pass
92
93 def endElement(self, name):
94 """
95 Handler called, when an ending tag is found.
96
97 @param name name of the tag (string)
98 """
99 try:
100 self.elements[name][1]()
101 except KeyError:
102 pass
103
104 def characters(self, chars):
105 """
106 Handler called for ordinary text.
107
108 @param chars the scanned text (string)
109 """
110 self.buffer += chars
111
112 def defaultStartElement(self, attrs):
113 """
114 Handler method for common start tags.
115
116 @param attrs list of tag attributes
117 """
118 self.buffer = ""
119
120 def defaultEndElement(self):
121 """
122 Handler method for the common end tags.
123 """
124 pass
125
126 def _prepareBasics(self):
127 """
128 Protected method to prepare the parsing of XML for basic python types.
129 """
130 self.stack = []
131
132 ############################################################################
133 ## The various handler methods for basic types
134 ############################################################################
135
136 def endNone(self):
137 """
138 Handler method for the "none" end tag.
139 """
140 self.stack.append(None)
141
142 def endInt(self):
143 """
144 Handler method for the "int" end tag.
145 """
146 self.stack.append(int(self.buffer.strip()))
147
148 def endBool(self):
149 """
150 Handler method for the "bool" end tag.
151 """
152 if self.buffer.strip() == "True":
153 self.stack.append(True)
154 else:
155 self.stack.append(False)
156
157 def endFloat(self):
158 """
159 Handler method for the "float" end tag.
160 """
161 self.stack.append(float(self.buffer.strip()))
162
163 def endComplex(self):
164 """
165 Handler method for the "complex" end tag.
166 """
167 real, imag = self.buffer.strip().split()
168 self.stack.append(float(real) + float(imag)*1j)
169
170 def endString(self):
171 """
172 Handler method for the "string" end tag.
173 """
174 s = str(self.unescape(self.buffer))
175 self.stack.append(s)
176
177 def endBytes(self):
178 """
179 Handler method for the "bytes" end tag.
180 """
181 by = bytes([int(b) for b in self.buffer.strip().split(",")])
182 self.stack.append(by)
183
184 def endBytearray(self):
185 """
186 Handler method for the "bytearray" end tag.
187 """
188 by = bytearray([int(b) for b in self.buffer.strip().split(",")])
189 self.stack.append(by)
190
191 def startList(self, attrs):
192 """
193 Handler method for the "list" start tag.
194
195 @param attrs list of tag attributes
196 """
197 self.stack.append(self._marker)
198
199 def endList(self):
200 """
201 Handler method for the "list" end tag.
202 """
203 for i in range(len(self.stack) - 1, -1, -1):
204 if self.stack[i] is self._marker:
205 break
206 assert i != -1
207 l = self.stack[i + 1:len(self.stack)]
208 self.stack[i:] = [l]
209
210 def startTuple(self, attrs):
211 """
212 Handler method for the "tuple" start tag.
213
214 @param attrs list of tag attributes
215 """
216 self.stack.append(self._marker)
217
218 def endTuple(self):
219 """
220 Handler method for the "tuple" end tag.
221 """
222 for i in range(len(self.stack) - 1, -1, -1):
223 if self.stack[i] is self._marker:
224 break
225 assert i != -1
226 t = tuple(self.stack[i + 1:len(self.stack)])
227 self.stack[i:] = [t]
228
229 def startDictionary(self, attrs):
230 """
231 Handler method for the "dictionary" start tag.
232
233 @param attrs list of tag attributes
234 """
235 self.stack.append(self._marker)
236
237 def endDictionary(self):
238 """
239 Handler method for the "dictionary" end tag.
240 """
241 for i in range(len(self.stack) - 1, -1, -1):
242 if self.stack[i] is self._marker:
243 break
244 assert i != -1
245 d = {}
246 for j in range(i + 1, len(self.stack), 2):
247 d[self.stack[j]] = self.stack[j + 1]
248 self.stack[i:] = [d]
249
250 def startSet(self, attrs):
251 """
252 Handler method for the "set" start tag.
253
254 @param attrs list of tag attributes
255 """
256 self.stack.append(self._marker)
257
258 def endSet(self):
259 """
260 Handler method for the "set" end tag.
261 """
262 for i in range(len(self.stack) - 1, -1, -1):
263 if self.stack[i] is self._marker:
264 break
265 assert i != -1
266 s = set(self.stack[i + 1:len(self.stack)])
267 self.stack[i:] = [s]
268
269 def startFrozenset(self, attrs):
270 """
271 Handler method for the "frozenset" start tag.
272
273 @param attrs list of tag attributes
274 """
275 self.stack.append(self._marker)
276
277 def endFrozenset(self):
278 """
279 Handler method for the "frozenset" end tag.
280 """
281 for i in range(len(self.stack) - 1, -1, -1):
282 if self.stack[i] is self._marker:
283 break
284 assert i != -1
285 f = frozenset(self.stack[i + 1:len(self.stack)])
286 self.stack[i:] = [f]
287
288 def startPickle(self, attrs):
289 """
290 Handler method for the "pickle" start tag.
291
292 @param attrs list of tag attributes
293 """
294 self.pickleEnc = attrs.get("encoding", "base64")
295
296 def endPickle(self):
297 """
298 Handler method for the "pickle" end tag.
299 """
300 pic = base64.b64decode(self.buffer.encode("ASCII"))
301 self.stack.append(pickle.loads(pic))

eric ide

mercurial