blob: 4c9fe92f94ffb273f77ee69cc27825f11382644a [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):
Daniel Veillardeaccdc62005-10-27 14:10:52 +0000214 #print msg
Daniel Veillard745648b2006-02-27 09:59:30 +0000215 pass
Daniel Veillard8d24cc12002-03-05 15:41:29 +0000216
217 def error(self, msg):
218 raise parserError(msg)
219
220 def fatalError(self, msg):
221 raise parserError(msg)
222
223#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000224# This class is the ancestor of all the Node classes. It provides
225# the basic functionalities shared by all nodes (and handle
226# gracefylly the exception), like name, navigation in the tree,
Daniel Veillard1e774382002-03-06 17:35:40 +0000227# doc reference, content access and serializing to a string or URI
Daniel Veillard1971ee22002-01-31 20:29:19 +0000228#
Daniel Veillard36ed5292002-01-30 23:49:06 +0000229class xmlCore:
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000230 def __init__(self, _obj=None):
231 if _obj != None:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000232 self._o = _obj;
233 return
234 self._o = None
William M. Brack40cca612006-06-26 18:25:40 +0000235
236 def __eq__(self, other):
237 if other == None:
238 return False
239 ret = libxml2mod.compareNodesEqual(self._o, other._o)
240 if ret == None:
241 return False
242 return ret == True
243 def __ne__(self, other):
244 if other == None:
245 return True
246 ret = libxml2mod.compareNodesEqual(self._o, other._o)
247 return not ret
248 def __hash__(self):
249 ret = libxml2mod.nodeHash(self._o)
250 return ret
251
Daniel Veillard1cd4dae2005-01-15 17:45:28 +0000252 def __str__(self):
253 return self.serialize()
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000254 def get_parent(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000255 ret = libxml2mod.parent(self._o)
256 if ret == None:
257 return None
258 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000259 def get_children(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000260 ret = libxml2mod.children(self._o)
261 if ret == None:
262 return None
263 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000264 def get_last(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000265 ret = libxml2mod.last(self._o)
266 if ret == None:
267 return None
268 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000269 def get_next(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000270 ret = libxml2mod.next(self._o)
271 if ret == None:
272 return None
273 return xmlNode(_obj=ret)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000274 def get_properties(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000275 ret = libxml2mod.properties(self._o)
276 if ret == None:
277 return None
278 return xmlAttr(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000279 def get_prev(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000280 ret = libxml2mod.prev(self._o)
281 if ret == None:
282 return None
283 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000284 def get_content(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000285 return libxml2mod.xmlNodeGetContent(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000286 getContent = get_content # why is this duplicate naming needed ?
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000287 def get_name(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000288 return libxml2mod.name(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000289 def get_type(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000290 return libxml2mod.type(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000291 def get_doc(self):
292 ret = libxml2mod.doc(self._o)
293 if ret == None:
294 if self.type in ["document_xml", "document_html"]:
295 return xmlDoc(_obj=self._o)
296 else:
297 return None
298 return xmlDoc(_obj=ret)
299 #
300 # Those are common attributes to nearly all type of nodes
301 # defined as python2 properties
302 #
303 import sys
304 if float(sys.version[0:3]) < 2.2:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000305 def __getattr__(self, attr):
306 if attr == "parent":
307 ret = libxml2mod.parent(self._o)
308 if ret == None:
309 return None
310 return xmlNode(_obj=ret)
311 elif attr == "properties":
312 ret = libxml2mod.properties(self._o)
313 if ret == None:
314 return None
315 return xmlAttr(_obj=ret)
316 elif attr == "children":
317 ret = libxml2mod.children(self._o)
318 if ret == None:
319 return None
320 return xmlNode(_obj=ret)
321 elif attr == "last":
322 ret = libxml2mod.last(self._o)
323 if ret == None:
324 return None
325 return xmlNode(_obj=ret)
326 elif attr == "next":
327 ret = libxml2mod.next(self._o)
328 if ret == None:
329 return None
330 return xmlNode(_obj=ret)
331 elif attr == "prev":
332 ret = libxml2mod.prev(self._o)
333 if ret == None:
334 return None
335 return xmlNode(_obj=ret)
336 elif attr == "content":
337 return libxml2mod.xmlNodeGetContent(self._o)
338 elif attr == "name":
339 return libxml2mod.name(self._o)
340 elif attr == "type":
341 return libxml2mod.type(self._o)
342 elif attr == "doc":
343 ret = libxml2mod.doc(self._o)
344 if ret == None:
345 if self.type == "document_xml" or self.type == "document_html":
346 return xmlDoc(_obj=self._o)
347 else:
348 return None
349 return xmlDoc(_obj=ret)
350 raise AttributeError,attr
Daniel Veillard51a447a2003-01-04 19:42:46 +0000351 else:
William M. Brack1d75c8a2003-10-27 13:48:16 +0000352 parent = property(get_parent, None, None, "Parent node")
353 children = property(get_children, None, None, "First child node")
354 last = property(get_last, None, None, "Last sibling node")
355 next = property(get_next, None, None, "Next sibling node")
356 prev = property(get_prev, None, None, "Previous sibling node")
357 properties = property(get_properties, None, None, "List of properies")
358 content = property(get_content, None, None, "Content of this node")
359 name = property(get_name, None, None, "Node name")
360 type = property(get_type, None, None, "Node type")
361 doc = property(get_doc, None, None, "The document this node belongs to")
Daniel Veillard1e774382002-03-06 17:35:40 +0000362
363 #
364 # Serialization routines, the optional arguments have the following
365 # meaning:
366 # encoding: string to ask saving in a specific encoding
Daniel Veillard51a447a2003-01-04 19:42:46 +0000367 # indent: if 1 the serializer is asked to indent the output
Daniel Veillard1e774382002-03-06 17:35:40 +0000368 #
369 def serialize(self, encoding = None, format = 0):
370 return libxml2mod.serializeNode(self._o, encoding, format)
371 def saveTo(self, file, encoding = None, format = 0):
372 return libxml2mod.saveNodeTo(self._o, file, encoding, format)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000373
Daniel Veillardf742d342002-03-07 00:05:35 +0000374 #
Daniel Veillardd5e198a2004-03-09 09:03:28 +0000375 # Canonicalization routines:
376 #
377 # nodes: the node set (tuple or list) to be included in the
378 # canonized image or None if all document nodes should be
379 # included.
380 # exclusive: the exclusive flag (0 - non-exclusive
381 # canonicalization; otherwise - exclusive canonicalization)
382 # prefixes: the list of inclusive namespace prefixes (strings),
383 # or None if there is no inclusive namespaces (only for
384 # exclusive canonicalization, ignored otherwise)
385 # with_comments: include comments in the result (!=0) or not
386 # (==0)
387 def c14nMemory(self,
388 nodes=None,
389 exclusive=0,
390 prefixes=None,
391 with_comments=0):
392 if nodes:
393 nodes = map(lambda n: n._o, nodes)
394 return libxml2mod.xmlC14NDocDumpMemory(
395 self.get_doc()._o,
396 nodes,
397 exclusive != 0,
398 prefixes,
399 with_comments != 0)
400 def c14nSaveTo(self,
401 file,
402 nodes=None,
403 exclusive=0,
404 prefixes=None,
405 with_comments=0):
406 if nodes:
407 nodes = map(lambda n: n._o, nodes)
408 return libxml2mod.xmlC14NDocSaveTo(
409 self.get_doc()._o,
410 nodes,
411 exclusive != 0,
412 prefixes,
413 with_comments != 0,
414 file)
415
416 #
Daniel Veillardf742d342002-03-07 00:05:35 +0000417 # Selecting nodes using XPath, a bit slow because the context
418 # is allocated/freed every time but convenient.
419 #
420 def xpathEval(self, expr):
William M. Brack1d75c8a2003-10-27 13:48:16 +0000421 doc = self.doc
422 if doc == None:
423 return None
424 ctxt = doc.xpathNewContext()
425 ctxt.setContextNode(self)
426 res = ctxt.xpathEval(expr)
427 ctxt.xpathFreeContext()
428 return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000429
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000430# #
431# # Selecting nodes using XPath, faster because the context
432# # is allocated just once per xmlDoc.
433# #
434# # Removed: DV memleaks c.f. #126735
435# #
436# def xpathEval2(self, expr):
437# doc = self.doc
438# if doc == None:
439# return None
440# try:
441# doc._ctxt.setContextNode(self)
442# except:
443# doc._ctxt = doc.xpathNewContext()
444# doc._ctxt.setContextNode(self)
445# res = doc._ctxt.xpathEval(expr)
446# return res
Daniel Veillard51a447a2003-01-04 19:42:46 +0000447 def xpathEval2(self, expr):
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000448 return self.xpathEval(expr)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000449
Daniel Veillardf9cf6f52005-04-12 01:02:29 +0000450 # Remove namespaces
451 def removeNsDef(self, href):
452 """
453 Remove a namespace definition from a node. If href is None,
454 remove all of the ns definitions on that node. The removed
455 namespaces are returned as a linked list.
456
457 Note: If any child nodes referred to the removed namespaces,
458 they will be left with dangling links. You should call
459 renciliateNs() to fix those pointers.
460
461 Note: This method does not free memory taken by the ns
462 definitions. You will need to free it manually with the
463 freeNsList() method on the returns xmlNs object.
464 """
465
466 ret = libxml2mod.xmlNodeRemoveNsDef(self._o, href)
467 if ret is None:return None
468 __tmp = xmlNs(_obj=ret)
469 return __tmp
470
Daniel Veillard51a447a2003-01-04 19:42:46 +0000471 # support for python2 iterators
472 def walk_depth_first(self):
473 return xmlCoreDepthFirstItertor(self)
474 def walk_breadth_first(self):
475 return xmlCoreBreadthFirstItertor(self)
476 __iter__ = walk_depth_first
477
478 def free(self):
479 try:
480 self.doc._ctxt.xpathFreeContext()
481 except:
482 pass
Daniel Veillardf88d8cf2003-12-08 10:25:02 +0000483 libxml2mod.xmlFreeDoc(self._o)
Daniel Veillard51a447a2003-01-04 19:42:46 +0000484
485
486#
487# implements the depth-first iterator for libxml2 DOM tree
488#
489class xmlCoreDepthFirstItertor:
490 def __init__(self, node):
491 self.node = node
492 self.parents = []
493 def __iter__(self):
494 return self
495 def next(self):
496 while 1:
497 if self.node:
498 ret = self.node
499 self.parents.append(self.node)
500 self.node = self.node.children
501 return ret
502 try:
503 parent = self.parents.pop()
504 except IndexError:
505 raise StopIteration
506 self.node = parent.next
507
508#
509# implements the breadth-first iterator for libxml2 DOM tree
510#
511class xmlCoreBreadthFirstItertor:
512 def __init__(self, node):
513 self.node = node
514 self.parents = []
515 def __iter__(self):
516 return self
517 def next(self):
518 while 1:
519 if self.node:
520 ret = self.node
521 self.parents.append(self.node)
522 self.node = self.node.next
523 return ret
524 try:
525 parent = self.parents.pop()
526 except IndexError:
527 raise StopIteration
528 self.node = parent.children
529
Daniel Veillard36ed5292002-01-30 23:49:06 +0000530#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000531# converters to present a nicer view of the XPath returns
532#
533def nodeWrap(o):
534 # TODO try to cast to the most appropriate node class
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000535 name = libxml2mod.type(o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000536 if name == "element" or name == "text":
537 return xmlNode(_obj=o)
538 if name == "attribute":
539 return xmlAttr(_obj=o)
540 if name[0:8] == "document":
541 return xmlDoc(_obj=o)
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000542 if name == "namespace":
Daniel Veillard1971ee22002-01-31 20:29:19 +0000543 return xmlNs(_obj=o)
544 if name == "elem_decl":
545 return xmlElement(_obj=o)
546 if name == "attribute_decl":
Daniel Veillard1f8658a2004-08-14 21:46:31 +0000547 return xmlAttribute(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000548 if name == "entity_decl":
549 return xmlEntity(_obj=o)
550 if name == "dtd":
Daniel Veillarde59494f2003-01-04 16:35:29 +0000551 return xmlDtd(_obj=o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000552 return xmlNode(_obj=o)
553
554def xpathObjectRet(o):
Daniel Veillard46459062006-10-10 08:40:04 +0000555 otype = type(o)
556 if otype == type([]):
557 ret = map(xpathObjectRet, o)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000558 return ret
Daniel Veillard46459062006-10-10 08:40:04 +0000559 elif otype == type(()):
560 ret = map(xpathObjectRet, o)
561 return tuple(ret)
562 elif otype == type('') or otype == type(0) or otype == type(0.0):
563 return o
564 else:
565 return nodeWrap(o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000566
567#
Daniel Veillarda7340c82002-02-01 17:56:45 +0000568# register an XPath function
569#
570def registerXPathFunction(ctxt, name, ns_uri, f):
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000571 ret = libxml2mod.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
Daniel Veillarda7340c82002-02-01 17:56:45 +0000572
573#
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000574# For the xmlTextReader parser configuration
575#
576PARSER_LOADDTD=1
577PARSER_DEFAULTATTRS=2
578PARSER_VALIDATE=3
Daniel Veillarde18fc182002-12-28 22:56:33 +0000579PARSER_SUBST_ENTITIES=4
Daniel Veillardf25b4ca2002-12-27 15:18:35 +0000580
581#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000582# For the error callback severities
Daniel Veillard26f70262003-01-16 22:45:08 +0000583#
Daniel Veillard417be3a2003-01-20 21:26:34 +0000584PARSER_SEVERITY_VALIDITY_WARNING=1
585PARSER_SEVERITY_VALIDITY_ERROR=2
586PARSER_SEVERITY_WARNING=3
587PARSER_SEVERITY_ERROR=4
Daniel Veillard26f70262003-01-16 22:45:08 +0000588
589#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000590# register the libxml2 error handler
Daniel Veillard36ed5292002-01-30 23:49:06 +0000591#
Daniel Veillard3e20a292003-01-10 13:14:40 +0000592def registerErrorHandler(f, ctx):
593 """Register a Python written function to for error reporting.
594 The function is called back as f(ctx, error). """
595 import sys
596 if not sys.modules.has_key('libxslt'):
597 # normal behaviour when libxslt is not imported
598 ret = libxml2mod.xmlRegisterErrorHandler(f,ctx)
599 else:
600 # when libxslt is already imported, one must
601 # use libxst's error handler instead
602 import libxslt
603 ret = libxslt.registerErrorHandler(f,ctx)
604 return ret
605
Daniel Veillarde6227e02003-01-14 11:42:39 +0000606class parserCtxtCore:
607
608 def __init__(self, _obj=None):
609 if _obj != None:
610 self._o = _obj;
611 return
612 self._o = None
613
614 def __del__(self):
615 if self._o != None:
616 libxml2mod.xmlFreeParserCtxt(self._o)
William M. Brack1d75c8a2003-10-27 13:48:16 +0000617 self._o = None
Daniel Veillarde6227e02003-01-14 11:42:39 +0000618
Daniel Veillard417be3a2003-01-20 21:26:34 +0000619 def setErrorHandler(self,f,arg):
620 """Register an error handler that will be called back as
621 f(arg,msg,severity,reserved).
622
623 @reserved is currently always None."""
624 libxml2mod.xmlParserCtxtSetErrorHandler(self._o,f,arg)
Daniel Veillarde6227e02003-01-14 11:42:39 +0000625
Daniel Veillard417be3a2003-01-20 21:26:34 +0000626 def getErrorHandler(self):
627 """Return (f,arg) as previously registered with setErrorHandler
628 or (None,None)."""
629 return libxml2mod.xmlParserCtxtGetErrorHandler(self._o)
630
Daniel Veillard54396242003-04-23 07:36:50 +0000631 def addLocalCatalog(self, uri):
632 """Register a local catalog with the parser"""
633 return libxml2mod.addLocalCatalog(self._o, uri)
634
635
Daniel Veillard0e460da2005-03-30 22:47:10 +0000636class ValidCtxtCore:
637
638 def __init__(self, *args, **kw):
639 pass
640
641 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
642 """
643 Register error and warning handlers for DTD validation.
644 These will be called back as f(msg,arg)
645 """
646 libxml2mod.xmlSetValidErrors(self._o, err_func, warn_func, arg)
647
648
649class SchemaValidCtxtCore:
650
651 def __init__(self, *args, **kw):
652 pass
653
654 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
655 """
656 Register error and warning handlers for Schema validation.
657 These will be called back as f(msg,arg)
658 """
659 libxml2mod.xmlSchemaSetValidErrors(self._o, err_func, warn_func, arg)
660
661
662class relaxNgValidCtxtCore:
663
664 def __init__(self, *args, **kw):
665 pass
666
667 def setValidityErrorHandler(self, err_func, warn_func, arg=None):
668 """
669 Register error and warning handlers for RelaxNG validation.
670 These will be called back as f(msg,arg)
671 """
672 libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg)
673
674
Daniel Veillard417be3a2003-01-20 21:26:34 +0000675def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator):
676 """Intermediate callback to wrap the locator"""
677 return f(arg,msg,severity,xmlTextReaderLocator(locator))
Daniel Veillarde6227e02003-01-14 11:42:39 +0000678
Daniel Veillard26f70262003-01-16 22:45:08 +0000679class xmlTextReaderCore:
680
681 def __init__(self, _obj=None):
682 self.input = None
683 if _obj != None:self._o = _obj;return
684 self._o = None
685
686 def __del__(self):
687 if self._o != None:
688 libxml2mod.xmlFreeTextReader(self._o)
689 self._o = None
690
Daniel Veillard417be3a2003-01-20 21:26:34 +0000691 def SetErrorHandler(self,f,arg):
Daniel Veillard26f70262003-01-16 22:45:08 +0000692 """Register an error handler that will be called back as
Daniel Veillard417be3a2003-01-20 21:26:34 +0000693 f(arg,msg,severity,locator)."""
694 if f is None:
695 libxml2mod.xmlTextReaderSetErrorHandler(\
696 self._o,None,None)
697 else:
698 libxml2mod.xmlTextReaderSetErrorHandler(\
699 self._o,_xmlTextReaderErrorFunc,(f,arg))
Daniel Veillard26f70262003-01-16 22:45:08 +0000700
Daniel Veillard417be3a2003-01-20 21:26:34 +0000701 def GetErrorHandler(self):
Daniel Veillard26f70262003-01-16 22:45:08 +0000702 """Return (f,arg) as previously registered with setErrorHandler
703 or (None,None)."""
Daniel Veillard417be3a2003-01-20 21:26:34 +0000704 f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)
705 if f is None:
706 return None,None
707 else:
708 # assert f is _xmlTextReaderErrorFunc
709 return arg
Daniel Veillard26f70262003-01-16 22:45:08 +0000710
Daniel Veillardf93a8662004-07-01 12:56:30 +0000711#
712# The cleanup now goes though a wrappe in libxml.c
713#
714def cleanupParser():
715 libxml2mod.xmlPythonCleanupParser()
Daniel Veillard87ab1c12003-12-21 13:01:56 +0000716
Daniel Veillard3e20a292003-01-10 13:14:40 +0000717# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
718#
719# Everything before this line comes from libxml.py
720# Everything after this line is automatically generated
721#
722# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
Daniel Veillard1971ee22002-01-31 20:29:19 +0000723