blob: 86bdd92d2dda5b5e2810f176a8b36c8c9773a98a [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 Veillard1cd4dae2005-01-15 17:45:28 +0000234 def __str__(self):
235 return self.serialize()
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000236 def get_parent(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000237 ret = libxml2mod.parent(self._o)
238 if ret == None:
239 return None
240 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000241 def get_children(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000242 ret = libxml2mod.children(self._o)
243 if ret == None:
244 return None
245 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000246 def get_last(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000247 ret = libxml2mod.last(self._o)
248 if ret == None:
249 return None
250 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000251 def get_next(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000252 ret = libxml2mod.next(self._o)
253 if ret == None:
254 return None
255 return xmlNode(_obj=ret)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000256 def get_properties(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000257 ret = libxml2mod.properties(self._o)
258 if ret == None:
259 return None
260 return xmlAttr(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000261 def get_prev(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000262 ret = libxml2mod.prev(self._o)
263 if ret == None:
264 return None
265 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000266 def get_content(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000267 return libxml2mod.xmlNodeGetContent(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000268 getContent = get_content # why is this duplicate naming needed ?
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000269 def get_name(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000270 return libxml2mod.name(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000271 def get_type(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000272 return libxml2mod.type(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000273 def get_doc(self):
274 ret = libxml2mod.doc(self._o)
275 if ret == None:
276 if self.type in ["document_xml", "document_html"]:
277 return xmlDoc(_obj=self._o)
278 else:
279 return None
280 return xmlDoc(_obj=ret)
281 #
282 # Those are common attributes to nearly all type of nodes
283 # defined as python2 properties
284 #
285 import sys
286 if float(sys.version[0:3]) < 2.2:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000287 def __getattr__(self, attr):
288 if attr == "parent":
289 ret = libxml2mod.parent(self._o)
290 if ret == None:
291 return None
292 return xmlNode(_obj=ret)
293 elif attr == "properties":
294 ret = libxml2mod.properties(self._o)
295 if ret == None:
296 return None
297 return xmlAttr(_obj=ret)
298 elif attr == "children":
299 ret = libxml2mod.children(self._o)
300 if ret == None:
301 return None
302 return xmlNode(_obj=ret)
303 elif attr == "last":
304 ret = libxml2mod.last(self._o)
305 if ret == None:
306 return None
307 return xmlNode(_obj=ret)
308 elif attr == "next":
309 ret = libxml2mod.next(self._o)
310 if ret == None:
311 return None
312 return xmlNode(_obj=ret)
313 elif attr == "prev":
314 ret = libxml2mod.prev(self._o)
315 if ret == None:
316 return None
317 return xmlNode(_obj=ret)
318 elif attr == "content":
319 return libxml2mod.xmlNodeGetContent(self._o)
320 elif attr == "name":
321 return libxml2mod.name(self._o)
322 elif attr == "type":
323 return libxml2mod.type(self._o)
324 elif attr == "doc":
325 ret = libxml2mod.doc(self._o)
326 if ret == None:
327 if self.type == "document_xml" or self.type == "document_html":
328 return xmlDoc(_obj=self._o)
329 else:
330 return None
331 return xmlDoc(_obj=ret)
332 raise AttributeError,attr
Daniel Veillard51a447a2003-01-04 19:42:46 +0000333 else:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000334 parent = property(get_parent, None, None, "Parent node")
335 children = property(get_children, None, None, "First child node")
336 last = property(get_last, None, None, "Last sibling node")
337 next = property(get_next, None, None, "Next sibling node")
338 prev = property(get_prev, None, None, "Previous sibling node")
339 properties = property(get_properties, None, None, "List of properies")
340 content = property(get_content, None, None, "Content of this node")
341 name = property(get_name, None, None, "Node name")
342 type = property(get_type, None, None, "Node type")
343 doc = property(get_doc, None, None, "The document this node belongs to")
Daniel Veillard1e774382002-03-06 17:35:40 +0000344
345 #
346 # Serialization routines, the optional arguments have the following
347 # meaning:
348 # encoding: string to ask saving in a specific encoding
Daniel Veillard51a447a2003-01-04 19:42:46 +0000349 # indent: if 1 the serializer is asked to indent the output
Daniel Veillard1e774382002-03-06 17:35:40 +0000350 #
351 def serialize(self, encoding = None, format = 0):
352 return libxml2mod.serializeNode(self._o, encoding, format)
353 def saveTo(self, file, encoding = None, format = 0):
354 return libxml2mod.saveNodeTo(self._o, file, encoding, format)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000355
Daniel Veillardf742d342002-03-07 00:05:35 +0000356 #
Daniel Veillardd5e198a2004-03-09 09:03:28 +0000357 # Canonicalization routines:
358 #
359 # nodes: the node set (tuple or list) to be included in the
360 # canonized image or None if all document nodes should be
361 # included.
362 # exclusive: the exclusive flag (0 - non-exclusive
363 # canonicalization; otherwise - exclusive canonicalization)
364 # prefixes: the list of inclusive namespace prefixes (strings),
365 # or None if there is no inclusive namespaces (only for
366 # exclusive canonicalization, ignored otherwise)
367 # with_comments: include comments in the result (!=0) or not
368 # (==0)
369 def c14nMemory(self,
370 nodes=None,
371 exclusive=0,
372 prefixes=None,
373 with_comments=0):
374 if nodes:
375 nodes = map(lambda n: n._o, nodes)
376 return libxml2mod.xmlC14NDocDumpMemory(
377 self.get_doc()._o,
378 nodes,
379 exclusive != 0,
380 prefixes,
381 with_comments != 0)
382 def c14nSaveTo(self,
383 file,
384 nodes=None,
385 exclusive=0,
386 prefixes=None,
387 with_comments=0):
388 if nodes:
389 nodes = map(lambda n: n._o, nodes)
390 return libxml2mod.xmlC14NDocSaveTo(
391 self.get_doc()._o,
392 nodes,
393 exclusive != 0,
394 prefixes,
395 with_comments != 0,
396 file)
397
398 #
Daniel Veillardf742d342002-03-07 00:05:35 +0000399 # Selecting nodes using XPath, a bit slow because the context
400 # is allocated/freed every time but convenient.
401 #
402 def xpathEval(self, expr):
William M. Brack1d75c8a2003-10-27 13:48:16 +0000403 doc = self.doc
404 if doc == None:
405 return None
406 ctxt = doc.xpathNewContext()
407 ctxt.setContextNode(self)
408 res = ctxt.xpathEval(expr)
409 ctxt.xpathFreeContext()
410 return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000411
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000412# #
413# # Selecting nodes using XPath, faster because the context
414# # is allocated just once per xmlDoc.
415# #
416# # Removed: DV memleaks c.f. #126735
417# #
418# def xpathEval2(self, expr):
419# doc = self.doc
420# if doc == None:
421# return None
422# try:
423# doc._ctxt.setContextNode(self)
424# except:
425# doc._ctxt = doc.xpathNewContext()
426# doc._ctxt.setContextNode(self)
427# res = doc._ctxt.xpathEval(expr)
428# return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000429 def xpathEval2(self, expr):
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000430 return self.xpathEval(expr)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000431
Daniel Veillardf9cf6f52005-04-12 01:02:29 +0000432 # Remove namespaces
433 def removeNsDef(self, href):
434 """
435 Remove a namespace definition from a node. If href is None,
436 remove all of the ns definitions on that node. The removed
437 namespaces are returned as a linked list.
438
439 Note: If any child nodes referred to the removed namespaces,
440 they will be left with dangling links. You should call
441 renciliateNs() to fix those pointers.
442
443 Note: This method does not free memory taken by the ns
444 definitions. You will need to free it manually with the
445 freeNsList() method on the returns xmlNs object.
446 """
447
448 ret = libxml2mod.xmlNodeRemoveNsDef(self._o, href)
449 if ret is None:return None
450 __tmp = xmlNs(_obj=ret)
451 return __tmp
452
Daniel Veillard51a447a2003-01-04 19:42:46 +0000453 # support for python2 iterators
454 def walk_depth_first(self):
455 return xmlCoreDepthFirstItertor(self)
456 def walk_breadth_first(self):
457 return xmlCoreBreadthFirstItertor(self)
458 __iter__ = walk_depth_first
459
460 def free(self):
461 try:
462 self.doc._ctxt.xpathFreeContext()
463 except:
464 pass
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000465 libxml2mod.xmlFreeDoc(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000466
467
468#
469# implements the depth-first iterator for libxml2 DOM tree
470#
471class xmlCoreDepthFirstItertor:
472 def __init__(self, node):
473 self.node = node
474 self.parents = []
475 def __iter__(self):
476 return self
477 def next(self):
478 while 1:
479 if self.node:
480 ret = self.node
481 self.parents.append(self.node)
482 self.node = self.node.children
483 return ret
484 try:
485 parent = self.parents.pop()
486 except IndexError:
487 raise StopIteration
488 self.node = parent.next
489
490#
491# implements the breadth-first iterator for libxml2 DOM tree
492#
493class xmlCoreBreadthFirstItertor:
494 def __init__(self, node):
495 self.node = node
496 self.parents = []
497 def __iter__(self):
498 return self
499 def next(self):
500 while 1:
501 if self.node:
502 ret = self.node
503 self.parents.append(self.node)
504 self.node = self.node.next
505 return ret
506 try:
507 parent = self.parents.pop()
508 except IndexError:
509 raise StopIteration
510 self.node = parent.children
511
Daniel Veillard36ed5292002-01-30 23:49:06 +0000512#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000513# converters to present a nicer view of the XPath returns
514#
515def nodeWrap(o):
516 # TODO try to cast to the most appropriate node class
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000517 name = libxml2mod.type(o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000518 if name == "element" or name == "text":
519 return xmlNode(_obj=o)
520 if name == "attribute":
521 return xmlAttr(_obj=o)
522 if name[0:8] == "document":
523 return xmlDoc(_obj=o)
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000524 if name == "namespace":
Daniel Veillard1971ee22002-01-31 20:29:19 +0000525 return xmlNs(_obj=o)
526 if name == "elem_decl":
527 return xmlElement(_obj=o)
528 if name == "attribute_decl":
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000529 return xmlAttribute(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000530 if name == "entity_decl":
531 return xmlEntity(_obj=o)
532 if name == "dtd":
Daniel Veillarde59494f2003-01-04 16:35:29 +0000533 return xmlDtd(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000534 return xmlNode(_obj=o)
535
536def xpathObjectRet(o):
537 if type(o) == type([]) or type(o) == type(()):
538 ret = map(lambda x: nodeWrap(x), o)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000539 return ret
Daniel Veillard1971ee22002-01-31 20:29:19 +0000540 return o
541
542#
Daniel Veillarda7340c82002-02-01 17:56:45 +0000543# register an XPath function
544#
545def registerXPathFunction(ctxt, name, ns_uri, f):
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000546 ret = libxml2mod.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
Daniel Veillarda7340c82002-02-01 17:56:45 +0000547
548#
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000549# For the xmlTextReader parser configuration
550#
551PARSER_LOADDTD=1
552PARSER_DEFAULTATTRS=2
553PARSER_VALIDATE=3
Daniel Veillarde18fc182002-12-28 22:56:33 +0000554PARSER_SUBST_ENTITIES=4
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000555
556#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000557# For the error callback severities
Daniel Veillard26f70262003-01-16 22:45:08 +0000558#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000559PARSER_SEVERITY_VALIDITY_WARNING=1
560PARSER_SEVERITY_VALIDITY_ERROR=2
561PARSER_SEVERITY_WARNING=3
562PARSER_SEVERITY_ERROR=4
Daniel Veillard26f70262003-01-16 22:45:08 +0000563
564#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000565# register the libxml2 error handler
Daniel Veillard36ed5292002-01-30 23:49:06 +0000566#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000567def registerErrorHandler(f, ctx):
568 """Register a Python written function to for error reporting.
569 The function is called back as f(ctx, error). """
570 import sys
571 if not sys.modules.has_key('libxslt'):
572 # normal behaviour when libxslt is not imported
573 ret = libxml2mod.xmlRegisterErrorHandler(f,ctx)
574 else:
575 # when libxslt is already imported, one must
576 # use libxst's error handler instead
577 import libxslt
578 ret = libxslt.registerErrorHandler(f,ctx)
579 return ret
580
Daniel Veillarde6227e02003-01-14 11:42:39 +0000581class parserCtxtCore:
582
583 def __init__(self, _obj=None):
584 if _obj != None:
585 self._o = _obj;
586 return
587 self._o = None
588
589 def __del__(self):
590 if self._o != None:
591 libxml2mod.xmlFreeParserCtxt(self._o)
William M. Brack1d75c8a2003-10-27 13:48:16 +0000592 self._o = None
Daniel Veillarde6227e02003-01-14 11:42:39 +0000593
Daniel Veillard417be3a2003-01-20 21:26:34 +0000594 def setErrorHandler(self,f,arg):
595 """Register an error handler that will be called back as
596 f(arg,msg,severity,reserved).
597
598 @reserved is currently always None."""
599 libxml2mod.xmlParserCtxtSetErrorHandler(self._o,f,arg)
Daniel Veillarde6227e02003-01-14 11:42:39 +0000600
Daniel Veillard417be3a2003-01-20 21:26:34 +0000601 def getErrorHandler(self):
602 """Return (f,arg) as previously registered with setErrorHandler
603 or (None,None)."""
604 return libxml2mod.xmlParserCtxtGetErrorHandler(self._o)
605
Daniel Veillard54396242003-04-23 07:36:50 +0000606 def addLocalCatalog(self, uri):
607 """Register a local catalog with the parser"""
608 return libxml2mod.addLocalCatalog(self._o, uri)
609
610
Daniel Veillard0e460da2005-03-30 22:47:10 +0000611class ValidCtxtCore:
612
613 def __init__(self, *args, **kw):
614 pass
615
616 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
617 """
618 Register error and warning handlers for DTD validation.
619 These will be called back as f(msg,arg)
620 """
621 libxml2mod.xmlSetValidErrors(self._o, err_func, warn_func, arg)
622
623
624class SchemaValidCtxtCore:
625
626 def __init__(self, *args, **kw):
627 pass
628
629 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
630 """
631 Register error and warning handlers for Schema validation.
632 These will be called back as f(msg,arg)
633 """
634 libxml2mod.xmlSchemaSetValidErrors(self._o, err_func, warn_func, arg)
635
636
637class relaxNgValidCtxtCore:
638
639 def __init__(self, *args, **kw):
640 pass
641
642 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
643 """
644 Register error and warning handlers for RelaxNG validation.
645 These will be called back as f(msg,arg)
646 """
647 libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg)
648
649
Daniel Veillard417be3a2003-01-20 21:26:34 +0000650def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator):
651 """Intermediate callback to wrap the locator"""
652 return f(arg,msg,severity,xmlTextReaderLocator(locator))
Daniel Veillarde6227e02003-01-14 11:42:39 +0000653
Daniel Veillard26f70262003-01-16 22:45:08 +0000654class xmlTextReaderCore:
655
656 def __init__(self, _obj=None):
657 self.input = None
658 if _obj != None:self._o = _obj;return
659 self._o = None
660
661 def __del__(self):
662 if self._o != None:
663 libxml2mod.xmlFreeTextReader(self._o)
664 self._o = None
665
Daniel Veillard417be3a2003-01-20 21:26:34 +0000666 def SetErrorHandler(self,f,arg):
Daniel Veillard26f70262003-01-16 22:45:08 +0000667 """Register an error handler that will be called back as
Daniel Veillard417be3a2003-01-20 21:26:34 +0000668 f(arg,msg,severity,locator)."""
669 if f is None:
670 libxml2mod.xmlTextReaderSetErrorHandler(\
671 self._o,None,None)
672 else:
673 libxml2mod.xmlTextReaderSetErrorHandler(\
674 self._o,_xmlTextReaderErrorFunc,(f,arg))
Daniel Veillard26f70262003-01-16 22:45:08 +0000675
Daniel Veillard417be3a2003-01-20 21:26:34 +0000676 def GetErrorHandler(self):
Daniel Veillard26f70262003-01-16 22:45:08 +0000677 """Return (f,arg) as previously registered with setErrorHandler
678 or (None,None)."""
Daniel Veillard417be3a2003-01-20 21:26:34 +0000679 f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)
680 if f is None:
681 return None,None
682 else:
683 # assert f is _xmlTextReaderErrorFunc
684 return arg
Daniel Veillard26f70262003-01-16 22:45:08 +0000685
Daniel Veillardf93a8662004-07-01 12:56:30 +0000686#
687# The cleanup now goes though a wrappe in libxml.c
688#
689def cleanupParser():
690 libxml2mod.xmlPythonCleanupParser()
Daniel Veillard87ab1c12003-12-21 13:01:56 +0000691
Daniel Veillard3e20a292003-01-10 13:14:40 +0000692# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
693#
694# Everything before this line comes from libxml.py
695# Everything after this line is automatically generated
696#
697# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
Daniel Veillard1971ee22002-01-31 20:29:19 +0000698