E5XML/XMLHandlerBase.py

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

eric ide

mercurial