blob: 588e86247da03659c273f019b622fc8a41148eb0 [file] [log] [blame]
Daniel Veillard5e5c2d02002-02-09 18:03:01 +00001import libxml2mod
Daniel Veillard85bb5b02003-12-04 14:12:05 +00002import types
Daniel Veillardd2897fd2002-01-30 16:37:32 +00003
Daniel Veillarda81355e2004-09-28 11:08:27 +00004# The root of all libxml2 errors.
5class libxmlError(Exception): pass
6
Daniel Veillard1971ee22002-01-31 20:29:19 +00007#
Daniel Veillard8d24cc12002-03-05 15:41:29 +00008# Errors raised by the wrappers when some tree handling failed.
9#
Daniel Veillarda81355e2004-09-28 11:08:27 +000010class treeError(libxmlError):
Daniel Veillard8d24cc12002-03-05 15:41:29 +000011 def __init__(self, msg):
12 self.msg = msg
13 def __str__(self):
14 return self.msg
15
Daniel Veillarda81355e2004-09-28 11:08:27 +000016class parserError(libxmlError):
Daniel Veillard8d24cc12002-03-05 15:41:29 +000017 def __init__(self, msg):
18 self.msg = msg
19 def __str__(self):
20 return self.msg
21
Daniel Veillarda81355e2004-09-28 11:08:27 +000022class uriError(libxmlError):
Daniel Veillard8d24cc12002-03-05 15:41:29 +000023 def __init__(self, msg):
24 self.msg = msg
25 def __str__(self):
26 return self.msg
27
Daniel Veillarda81355e2004-09-28 11:08:27 +000028class xpathError(libxmlError):
Daniel Veillard8d24cc12002-03-05 15:41:29 +000029 def __init__(self, msg):
30 self.msg = msg
31 def __str__(self):
32 return self.msg
33
Daniel Veillardc6d4a932002-09-12 15:00:57 +000034class ioWrapper:
35 def __init__(self, _obj):
36 self.__io = _obj
37 self._o = None
38
39 def io_close(self):
40 if self.__io == None:
William M. Brack1d75c8a2003-10-27 13:48:16 +000041 return(-1)
42 self.__io.close()
43 self.__io = None
44 return(0)
Daniel Veillardc6d4a932002-09-12 15:00:57 +000045
46 def io_flush(self):
47 if self.__io == None:
William M. Brack1d75c8a2003-10-27 13:48:16 +000048 return(-1)
49 self.__io.flush()
50 return(0)
Daniel Veillardc6d4a932002-09-12 15:00:57 +000051
52 def io_read(self, len = -1):
53 if self.__io == None:
William M. Brack1d75c8a2003-10-27 13:48:16 +000054 return(-1)
Daniel Veillardc6d4a932002-09-12 15:00:57 +000055 if len < 0:
William M. Brack1d75c8a2003-10-27 13:48:16 +000056 return(self.__io.read())
57 return(self.__io.read(len))
Daniel Veillardc6d4a932002-09-12 15:00:57 +000058
59 def io_write(self, str, len = -1):
60 if self.__io == None:
William M. Brack1d75c8a2003-10-27 13:48:16 +000061 return(-1)
Daniel Veillardc6d4a932002-09-12 15:00:57 +000062 if len < 0:
William M. Brack1d75c8a2003-10-27 13:48:16 +000063 return(self.__io.write(str))
64 return(self.__io.write(str, len))
Daniel Veillardc6d4a932002-09-12 15:00:57 +000065
66class ioReadWrapper(ioWrapper):
67 def __init__(self, _obj, enc = ""):
68 ioWrapper.__init__(self, _obj)
69 self._o = libxml2mod.xmlCreateInputBuffer(self, enc)
70
71 def __del__(self):
72 print "__del__"
73 self.io_close()
74 if self._o != None:
75 libxml2mod.xmlFreeParserInputBuffer(self._o)
76 self._o = None
77
78 def close(self):
79 self.io_close()
80 if self._o != None:
81 libxml2mod.xmlFreeParserInputBuffer(self._o)
82 self._o = None
83
84class ioWriteWrapper(ioWrapper):
85 def __init__(self, _obj, enc = ""):
Daniel Veillard85bb5b02003-12-04 14:12:05 +000086# print "ioWriteWrapper.__init__", _obj
87 if type(_obj) == type(''):
William M. Brack37e63942004-07-12 16:27:37 +000088 print "write io from a string"
89 self.o = None
90 elif type(_obj) == types.InstanceType:
91 print "write io from instance of %s" % (_obj.__class__)
92 ioWrapper.__init__(self, _obj)
93 self._o = libxml2mod.xmlCreateOutputBuffer(self, enc)
94 else:
95 file = libxml2mod.outputBufferGetPythonFile(_obj)
96 if file != None:
97 ioWrapper.__init__(self, file)
98 else:
99 ioWrapper.__init__(self, _obj)
100 self._o = _obj
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000101
102 def __del__(self):
Daniel Veillard85bb5b02003-12-04 14:12:05 +0000103# print "__del__"
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000104 self.io_close()
105 if self._o != None:
106 libxml2mod.xmlOutputBufferClose(self._o)
107 self._o = None
108
Daniel Veillard85bb5b02003-12-04 14:12:05 +0000109 def flush(self):
110 self.io_flush()
111 if self._o != None:
112 libxml2mod.xmlOutputBufferClose(self._o)
113 self._o = None
114
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000115 def close(self):
Daniel Veillard85bb5b02003-12-04 14:12:05 +0000116 self.io_flush()
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000117 if self._o != None:
118 libxml2mod.xmlOutputBufferClose(self._o)
119 self._o = None
120
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000121#
122# Example of a class to handle SAX events
123#
124class SAXCallback:
125 """Base class for SAX handlers"""
126 def startDocument(self):
127 """called at the start of the document"""
128 pass
129
130 def endDocument(self):
131 """called at the end of the document"""
132 pass
133
134 def startElement(self, tag, attrs):
135 """called at the start of every element, tag is the name of
William M. Brack1d75c8a2003-10-27 13:48:16 +0000136 the element, attrs is a dictionary of the element's attributes"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000137 pass
138
139 def endElement(self, tag):
140 """called at the start of every element, tag is the name of
William M. Brack1d75c8a2003-10-27 13:48:16 +0000141 the element"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000142 pass
143
144 def characters(self, data):
145 """called when character data have been read, data is the string
William M. Brack1d75c8a2003-10-27 13:48:16 +0000146 containing the data, multiple consecutive characters() callback
147 are possible."""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000148 pass
149
150 def cdataBlock(self, data):
151 """called when CDATA section have been read, data is the string
William M. Brack1d75c8a2003-10-27 13:48:16 +0000152 containing the data, multiple consecutive cdataBlock() callback
153 are possible."""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000154 pass
155
156 def reference(self, name):
157 """called when an entity reference has been found"""
158 pass
159
160 def ignorableWhitespace(self, data):
161 """called when potentially ignorable white spaces have been found"""
162 pass
163
164 def processingInstruction(self, target, data):
165 """called when a PI has been found, target contains the PI name and
William M. Brack1d75c8a2003-10-27 13:48:16 +0000166 data is the associated data in the PI"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000167 pass
168
169 def comment(self, content):
170 """called when a comment has been found, content contains the comment"""
171 pass
172
173 def externalSubset(self, name, externalID, systemID):
174 """called when a DOCTYPE declaration has been found, name is the
William M. Brack1d75c8a2003-10-27 13:48:16 +0000175 DTD name and externalID, systemID are the DTD public and system
176 identifier for that DTd if available"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000177 pass
178
179 def internalSubset(self, name, externalID, systemID):
180 """called when a DOCTYPE declaration has been found, name is the
William M. Brack1d75c8a2003-10-27 13:48:16 +0000181 DTD name and externalID, systemID are the DTD public and system
182 identifier for that DTD if available"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000183 pass
184
185 def entityDecl(self, name, type, externalID, systemID, content):
186 """called when an ENTITY declaration has been found, name is the
William M. Brack1d75c8a2003-10-27 13:48:16 +0000187 entity name and externalID, systemID are the entity public and
188 system identifier for that entity if available, type indicates
189 the entity type, and content reports it's string content"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000190 pass
191
192 def notationDecl(self, name, externalID, systemID):
193 """called when an NOTATION declaration has been found, name is the
William M. Brack1d75c8a2003-10-27 13:48:16 +0000194 notation name and externalID, systemID are the notation public and
195 system identifier for that notation if available"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000196 pass
197
198 def attributeDecl(self, elem, name, type, defi, defaultValue, nameList):
199 """called when an ATTRIBUTE definition has been found"""
William M. Brack1d75c8a2003-10-27 13:48:16 +0000200 pass
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000201
202 def elementDecl(self, name, type, content):
203 """called when an ELEMENT definition has been found"""
William M. Brack1d75c8a2003-10-27 13:48:16 +0000204 pass
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000205
206 def entityDecl(self, name, publicId, systemID, notationName):
207 """called when an unparsed ENTITY declaration has been found,
William M. Brack1d75c8a2003-10-27 13:48:16 +0000208 name is the entity name and publicId,, systemID are the entity
209 public and system identifier for that entity if available,
210 and notationName indicate the associated NOTATION"""
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000211 pass
212
213 def warning(self, msg):
214 print msg
215
216 def error(self, msg):
217 raise parserError(msg)
218
219 def fatalError(self, msg):
220 raise parserError(msg)
221
222#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000223# This class is the ancestor of all the Node classes. It provides
224# the basic functionalities shared by all nodes (and handle
225# gracefylly the exception), like name, navigation in the tree,
Daniel Veillard1e774382002-03-06 17:35:40 +0000226# doc reference, content access and serializing to a string or URI
Daniel Veillard1971ee22002-01-31 20:29:19 +0000227#
Daniel Veillard36ed5292002-01-30 23:49:06 +0000228class xmlCore:
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000229 def __init__(self, _obj=None):
230 if _obj != None:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000231 self._o = _obj;
232 return
233 self._o = None
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000234 def get_parent(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000235 ret = libxml2mod.parent(self._o)
236 if ret == None:
237 return None
238 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000239 def get_children(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000240 ret = libxml2mod.children(self._o)
241 if ret == None:
242 return None
243 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000244 def get_last(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000245 ret = libxml2mod.last(self._o)
246 if ret == None:
247 return None
248 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000249 def get_next(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000250 ret = libxml2mod.next(self._o)
251 if ret == None:
252 return None
253 return xmlNode(_obj=ret)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000254 def get_properties(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000255 ret = libxml2mod.properties(self._o)
256 if ret == None:
257 return None
258 return xmlAttr(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000259 def get_prev(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000260 ret = libxml2mod.prev(self._o)
261 if ret == None:
262 return None
263 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000264 def get_content(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000265 return libxml2mod.xmlNodeGetContent(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000266 getContent = get_content # why is this duplicate naming needed ?
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000267 def get_name(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000268 return libxml2mod.name(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000269 def get_type(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000270 return libxml2mod.type(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000271 def get_doc(self):
272 ret = libxml2mod.doc(self._o)
273 if ret == None:
274 if self.type in ["document_xml", "document_html"]:
275 return xmlDoc(_obj=self._o)
276 else:
277 return None
278 return xmlDoc(_obj=ret)
279 #
280 # Those are common attributes to nearly all type of nodes
281 # defined as python2 properties
282 #
283 import sys
284 if float(sys.version[0:3]) < 2.2:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000285 def __getattr__(self, attr):
286 if attr == "parent":
287 ret = libxml2mod.parent(self._o)
288 if ret == None:
289 return None
290 return xmlNode(_obj=ret)
291 elif attr == "properties":
292 ret = libxml2mod.properties(self._o)
293 if ret == None:
294 return None
295 return xmlAttr(_obj=ret)
296 elif attr == "children":
297 ret = libxml2mod.children(self._o)
298 if ret == None:
299 return None
300 return xmlNode(_obj=ret)
301 elif attr == "last":
302 ret = libxml2mod.last(self._o)
303 if ret == None:
304 return None
305 return xmlNode(_obj=ret)
306 elif attr == "next":
307 ret = libxml2mod.next(self._o)
308 if ret == None:
309 return None
310 return xmlNode(_obj=ret)
311 elif attr == "prev":
312 ret = libxml2mod.prev(self._o)
313 if ret == None:
314 return None
315 return xmlNode(_obj=ret)
316 elif attr == "content":
317 return libxml2mod.xmlNodeGetContent(self._o)
318 elif attr == "name":
319 return libxml2mod.name(self._o)
320 elif attr == "type":
321 return libxml2mod.type(self._o)
322 elif attr == "doc":
323 ret = libxml2mod.doc(self._o)
324 if ret == None:
325 if self.type == "document_xml" or self.type == "document_html":
326 return xmlDoc(_obj=self._o)
327 else:
328 return None
329 return xmlDoc(_obj=ret)
330 raise AttributeError,attr
Daniel Veillard51a447a2003-01-04 19:42:46 +0000331 else:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000332 parent = property(get_parent, None, None, "Parent node")
333 children = property(get_children, None, None, "First child node")
334 last = property(get_last, None, None, "Last sibling node")
335 next = property(get_next, None, None, "Next sibling node")
336 prev = property(get_prev, None, None, "Previous sibling node")
337 properties = property(get_properties, None, None, "List of properies")
338 content = property(get_content, None, None, "Content of this node")
339 name = property(get_name, None, None, "Node name")
340 type = property(get_type, None, None, "Node type")
341 doc = property(get_doc, None, None, "The document this node belongs to")
Daniel Veillard1e774382002-03-06 17:35:40 +0000342
343 #
344 # Serialization routines, the optional arguments have the following
345 # meaning:
346 # encoding: string to ask saving in a specific encoding
Daniel Veillard51a447a2003-01-04 19:42:46 +0000347 # indent: if 1 the serializer is asked to indent the output
Daniel Veillard1e774382002-03-06 17:35:40 +0000348 #
349 def serialize(self, encoding = None, format = 0):
350 return libxml2mod.serializeNode(self._o, encoding, format)
351 def saveTo(self, file, encoding = None, format = 0):
352 return libxml2mod.saveNodeTo(self._o, file, encoding, format)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000353
Daniel Veillardf742d342002-03-07 00:05:35 +0000354 #
Daniel Veillardd5e198a2004-03-09 09:03:28 +0000355 # Canonicalization routines:
356 #
357 # nodes: the node set (tuple or list) to be included in the
358 # canonized image or None if all document nodes should be
359 # included.
360 # exclusive: the exclusive flag (0 - non-exclusive
361 # canonicalization; otherwise - exclusive canonicalization)
362 # prefixes: the list of inclusive namespace prefixes (strings),
363 # or None if there is no inclusive namespaces (only for
364 # exclusive canonicalization, ignored otherwise)
365 # with_comments: include comments in the result (!=0) or not
366 # (==0)
367 def c14nMemory(self,
368 nodes=None,
369 exclusive=0,
370 prefixes=None,
371 with_comments=0):
372 if nodes:
373 nodes = map(lambda n: n._o, nodes)
374 return libxml2mod.xmlC14NDocDumpMemory(
375 self.get_doc()._o,
376 nodes,
377 exclusive != 0,
378 prefixes,
379 with_comments != 0)
380 def c14nSaveTo(self,
381 file,
382 nodes=None,
383 exclusive=0,
384 prefixes=None,
385 with_comments=0):
386 if nodes:
387 nodes = map(lambda n: n._o, nodes)
388 return libxml2mod.xmlC14NDocSaveTo(
389 self.get_doc()._o,
390 nodes,
391 exclusive != 0,
392 prefixes,
393 with_comments != 0,
394 file)
395
396 #
Daniel Veillardf742d342002-03-07 00:05:35 +0000397 # Selecting nodes using XPath, a bit slow because the context
398 # is allocated/freed every time but convenient.
399 #
400 def xpathEval(self, expr):
William M. Brack1d75c8a2003-10-27 13:48:16 +0000401 doc = self.doc
402 if doc == None:
403 return None
404 ctxt = doc.xpathNewContext()
405 ctxt.setContextNode(self)
406 res = ctxt.xpathEval(expr)
407 ctxt.xpathFreeContext()
408 return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000409
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000410# #
411# # Selecting nodes using XPath, faster because the context
412# # is allocated just once per xmlDoc.
413# #
414# # Removed: DV memleaks c.f. #126735
415# #
416# def xpathEval2(self, expr):
417# doc = self.doc
418# if doc == None:
419# return None
420# try:
421# doc._ctxt.setContextNode(self)
422# except:
423# doc._ctxt = doc.xpathNewContext()
424# doc._ctxt.setContextNode(self)
425# res = doc._ctxt.xpathEval(expr)
426# return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000427 def xpathEval2(self, expr):
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000428 return self.xpathEval(expr)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000429
430 # support for python2 iterators
431 def walk_depth_first(self):
432 return xmlCoreDepthFirstItertor(self)
433 def walk_breadth_first(self):
434 return xmlCoreBreadthFirstItertor(self)
435 __iter__ = walk_depth_first
436
437 def free(self):
438 try:
439 self.doc._ctxt.xpathFreeContext()
440 except:
441 pass
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000442 libxml2mod.xmlFreeDoc(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000443
444
445#
446# implements the depth-first iterator for libxml2 DOM tree
447#
448class xmlCoreDepthFirstItertor:
449 def __init__(self, node):
450 self.node = node
451 self.parents = []
452 def __iter__(self):
453 return self
454 def next(self):
455 while 1:
456 if self.node:
457 ret = self.node
458 self.parents.append(self.node)
459 self.node = self.node.children
460 return ret
461 try:
462 parent = self.parents.pop()
463 except IndexError:
464 raise StopIteration
465 self.node = parent.next
466
467#
468# implements the breadth-first iterator for libxml2 DOM tree
469#
470class xmlCoreBreadthFirstItertor:
471 def __init__(self, node):
472 self.node = node
473 self.parents = []
474 def __iter__(self):
475 return self
476 def next(self):
477 while 1:
478 if self.node:
479 ret = self.node
480 self.parents.append(self.node)
481 self.node = self.node.next
482 return ret
483 try:
484 parent = self.parents.pop()
485 except IndexError:
486 raise StopIteration
487 self.node = parent.children
488
Daniel Veillard36ed5292002-01-30 23:49:06 +0000489#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000490# converters to present a nicer view of the XPath returns
491#
492def nodeWrap(o):
493 # TODO try to cast to the most appropriate node class
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000494 name = libxml2mod.type(o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000495 if name == "element" or name == "text":
496 return xmlNode(_obj=o)
497 if name == "attribute":
498 return xmlAttr(_obj=o)
499 if name[0:8] == "document":
500 return xmlDoc(_obj=o)
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000501 if name == "namespace":
Daniel Veillard1971ee22002-01-31 20:29:19 +0000502 return xmlNs(_obj=o)
503 if name == "elem_decl":
504 return xmlElement(_obj=o)
505 if name == "attribute_decl":
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000506 return xmlAttribute(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000507 if name == "entity_decl":
508 return xmlEntity(_obj=o)
509 if name == "dtd":
Daniel Veillarde59494f2003-01-04 16:35:29 +0000510 return xmlDtd(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000511 return xmlNode(_obj=o)
512
513def xpathObjectRet(o):
514 if type(o) == type([]) or type(o) == type(()):
515 ret = map(lambda x: nodeWrap(x), o)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000516 return ret
Daniel Veillard1971ee22002-01-31 20:29:19 +0000517 return o
518
519#
Daniel Veillarda7340c82002-02-01 17:56:45 +0000520# register an XPath function
521#
522def registerXPathFunction(ctxt, name, ns_uri, f):
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000523 ret = libxml2mod.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
Daniel Veillarda7340c82002-02-01 17:56:45 +0000524
525#
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000526# For the xmlTextReader parser configuration
527#
528PARSER_LOADDTD=1
529PARSER_DEFAULTATTRS=2
530PARSER_VALIDATE=3
Daniel Veillarde18fc182002-12-28 22:56:33 +0000531PARSER_SUBST_ENTITIES=4
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000532
533#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000534# For the error callback severities
Daniel Veillard26f70262003-01-16 22:45:08 +0000535#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000536PARSER_SEVERITY_VALIDITY_WARNING=1
537PARSER_SEVERITY_VALIDITY_ERROR=2
538PARSER_SEVERITY_WARNING=3
539PARSER_SEVERITY_ERROR=4
Daniel Veillard26f70262003-01-16 22:45:08 +0000540
541#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000542# register the libxml2 error handler
Daniel Veillard36ed5292002-01-30 23:49:06 +0000543#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000544def registerErrorHandler(f, ctx):
545 """Register a Python written function to for error reporting.
546 The function is called back as f(ctx, error). """
547 import sys
548 if not sys.modules.has_key('libxslt'):
549 # normal behaviour when libxslt is not imported
550 ret = libxml2mod.xmlRegisterErrorHandler(f,ctx)
551 else:
552 # when libxslt is already imported, one must
553 # use libxst's error handler instead
554 import libxslt
555 ret = libxslt.registerErrorHandler(f,ctx)
556 return ret
557
Daniel Veillarde6227e02003-01-14 11:42:39 +0000558class parserCtxtCore:
559
560 def __init__(self, _obj=None):
561 if _obj != None:
562 self._o = _obj;
563 return
564 self._o = None
565
566 def __del__(self):
567 if self._o != None:
568 libxml2mod.xmlFreeParserCtxt(self._o)
William M. Brack1d75c8a2003-10-27 13:48:16 +0000569 self._o = None
Daniel Veillarde6227e02003-01-14 11:42:39 +0000570
Daniel Veillard417be3a2003-01-20 21:26:34 +0000571 def setErrorHandler(self,f,arg):
572 """Register an error handler that will be called back as
573 f(arg,msg,severity,reserved).
574
575 @reserved is currently always None."""
576 libxml2mod.xmlParserCtxtSetErrorHandler(self._o,f,arg)
Daniel Veillarde6227e02003-01-14 11:42:39 +0000577
Daniel Veillard417be3a2003-01-20 21:26:34 +0000578 def getErrorHandler(self):
579 """Return (f,arg) as previously registered with setErrorHandler
580 or (None,None)."""
581 return libxml2mod.xmlParserCtxtGetErrorHandler(self._o)
582
Daniel Veillard54396242003-04-23 07:36:50 +0000583 def addLocalCatalog(self, uri):
584 """Register a local catalog with the parser"""
585 return libxml2mod.addLocalCatalog(self._o, uri)
586
587
Daniel Veillard417be3a2003-01-20 21:26:34 +0000588def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator):
589 """Intermediate callback to wrap the locator"""
590 return f(arg,msg,severity,xmlTextReaderLocator(locator))
Daniel Veillarde6227e02003-01-14 11:42:39 +0000591
Daniel Veillard26f70262003-01-16 22:45:08 +0000592class xmlTextReaderCore:
593
594 def __init__(self, _obj=None):
595 self.input = None
596 if _obj != None:self._o = _obj;return
597 self._o = None
598
599 def __del__(self):
600 if self._o != None:
601 libxml2mod.xmlFreeTextReader(self._o)
602 self._o = None
603
Daniel Veillard417be3a2003-01-20 21:26:34 +0000604 def SetErrorHandler(self,f,arg):
Daniel Veillard26f70262003-01-16 22:45:08 +0000605 """Register an error handler that will be called back as
Daniel Veillard417be3a2003-01-20 21:26:34 +0000606 f(arg,msg,severity,locator)."""
607 if f is None:
608 libxml2mod.xmlTextReaderSetErrorHandler(\
609 self._o,None,None)
610 else:
611 libxml2mod.xmlTextReaderSetErrorHandler(\
612 self._o,_xmlTextReaderErrorFunc,(f,arg))
Daniel Veillard26f70262003-01-16 22:45:08 +0000613
Daniel Veillard417be3a2003-01-20 21:26:34 +0000614 def GetErrorHandler(self):
Daniel Veillard26f70262003-01-16 22:45:08 +0000615 """Return (f,arg) as previously registered with setErrorHandler
616 or (None,None)."""
Daniel Veillard417be3a2003-01-20 21:26:34 +0000617 f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)
618 if f is None:
619 return None,None
620 else:
621 # assert f is _xmlTextReaderErrorFunc
622 return arg
Daniel Veillard26f70262003-01-16 22:45:08 +0000623
Daniel Veillardf93a8662004-07-01 12:56:30 +0000624#
625# The cleanup now goes though a wrappe in libxml.c
626#
627def cleanupParser():
628 libxml2mod.xmlPythonCleanupParser()
Daniel Veillard87ab1c12003-12-21 13:01:56 +0000629
Daniel Veillard3e20a292003-01-10 13:14:40 +0000630# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
631#
632# Everything before this line comes from libxml.py
633# Everything after this line is automatically generated
634#
635# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
Daniel Veillard1971ee22002-01-31 20:29:19 +0000636