blob: 3c15102ceca8668be2ade29d1ab6452a3c0f9187 [file] [log] [blame]
Daniel Veillard5e5c2d02002-02-09 18:03:01 +00001import libxml2mod
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002
Daniel Veillard1971ee22002-01-31 20:29:19 +00003#
Daniel Veillard8d24cc12002-03-05 15:41:29 +00004# Errors raised by the wrappers when some tree handling failed.
5#
6class treeError:
7 def __init__(self, msg):
8 self.msg = msg
9 def __str__(self):
10 return self.msg
11
12class parserError:
13 def __init__(self, msg):
14 self.msg = msg
15 def __str__(self):
16 return self.msg
17
18class uriError:
19 def __init__(self, msg):
20 self.msg = msg
21 def __str__(self):
22 return self.msg
23
24class xpathError:
25 def __init__(self, msg):
26 self.msg = msg
27 def __str__(self):
28 return self.msg
29
30#
31# Example of a class to handle SAX events
32#
33class SAXCallback:
34 """Base class for SAX handlers"""
35 def startDocument(self):
36 """called at the start of the document"""
37 pass
38
39 def endDocument(self):
40 """called at the end of the document"""
41 pass
42
43 def startElement(self, tag, attrs):
44 """called at the start of every element, tag is the name of
45 the element, attrs is a dictionary of the element's attributes"""
46 pass
47
48 def endElement(self, tag):
49 """called at the start of every element, tag is the name of
50 the element"""
51 pass
52
53 def characters(self, data):
54 """called when character data have been read, data is the string
55 containing the data, multiple consecutive characters() callback
56 are possible."""
57 pass
58
59 def cdataBlock(self, data):
60 """called when CDATA section have been read, data is the string
61 containing the data, multiple consecutive cdataBlock() callback
62 are possible."""
63 pass
64
65 def reference(self, name):
66 """called when an entity reference has been found"""
67 pass
68
69 def ignorableWhitespace(self, data):
70 """called when potentially ignorable white spaces have been found"""
71 pass
72
73 def processingInstruction(self, target, data):
74 """called when a PI has been found, target contains the PI name and
75 data is the associated data in the PI"""
76 pass
77
78 def comment(self, content):
79 """called when a comment has been found, content contains the comment"""
80 pass
81
82 def externalSubset(self, name, externalID, systemID):
83 """called when a DOCTYPE declaration has been found, name is the
84 DTD name and externalID, systemID are the DTD public and system
85 identifier for that DTd if available"""
86 pass
87
88 def internalSubset(self, name, externalID, systemID):
89 """called when a DOCTYPE declaration has been found, name is the
90 DTD name and externalID, systemID are the DTD public and system
91 identifier for that DTD if available"""
92 pass
93
94 def entityDecl(self, name, type, externalID, systemID, content):
95 """called when an ENTITY declaration has been found, name is the
96 entity name and externalID, systemID are the entity public and
97 system identifier for that entity if available, type indicates
98 the entity type, and content reports it's string content"""
99 pass
100
101 def notationDecl(self, name, externalID, systemID):
102 """called when an NOTATION declaration has been found, name is the
103 notation name and externalID, systemID are the notation public and
104 system identifier for that notation if available"""
105 pass
106
107 def attributeDecl(self, elem, name, type, defi, defaultValue, nameList):
108 """called when an ATTRIBUTE definition has been found"""
109 pass
110
111 def elementDecl(self, name, type, content):
112 """called when an ELEMENT definition has been found"""
113 pass
114
115 def entityDecl(self, name, publicId, systemID, notationName):
116 """called when an unparsed ENTITY declaration has been found,
117 name is the entity name and publicId,, systemID are the entity
118 public and system identifier for that entity if available,
119 and notationName indicate the associated NOTATION"""
120 pass
121
122 def warning(self, msg):
123 print msg
124
125 def error(self, msg):
126 raise parserError(msg)
127
128 def fatalError(self, msg):
129 raise parserError(msg)
130
131#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000132# This class is the ancestor of all the Node classes. It provides
133# the basic functionalities shared by all nodes (and handle
134# gracefylly the exception), like name, navigation in the tree,
Daniel Veillard1e774382002-03-06 17:35:40 +0000135# doc reference, content access and serializing to a string or URI
Daniel Veillard1971ee22002-01-31 20:29:19 +0000136#
Daniel Veillard36ed5292002-01-30 23:49:06 +0000137class xmlCore:
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000138 def __init__(self, _obj=None):
139 if _obj != None:
Daniel Veillard01a6d412002-02-11 18:42:20 +0000140 self._o = _obj;
141 return
142 self._o = None
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000143
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000144 def __getattr__(self, attr):
145 if attr == "parent":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000146 ret = libxml2mod.parent(self._o)
147 if ret == None:
148 return None
149 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000150 elif attr == "properties":
Daniel Veillard01a6d412002-02-11 18:42:20 +0000151 ret = libxml2mod.properties(self._o)
152 if ret == None:
153 return None
154 return xmlAttr(_obj=ret)
155 elif attr == "children":
156 ret = libxml2mod.children(self._o)
157 if ret == None:
158 return None
159 return xmlNode(_obj=ret)
160 elif attr == "last":
161 ret = libxml2mod.last(self._o)
162 if ret == None:
163 return None
164 return xmlNode(_obj=ret)
165 elif attr == "next":
166 ret = libxml2mod.next(self._o)
167 if ret == None:
168 return None
169 return xmlNode(_obj=ret)
170 elif attr == "prev":
171 ret = libxml2mod.prev(self._o)
172 if ret == None:
173 return None
174 return xmlNode(_obj=ret)
175 elif attr == "content":
176 return libxml2mod.xmlNodeGetContent(self._o)
177 elif attr == "name":
178 return libxml2mod.name(self._o)
179 elif attr == "type":
180 return libxml2mod.type(self._o)
181 elif attr == "doc":
182 ret = libxml2mod.doc(self._o)
183 if ret == None:
Daniel Veillardf742d342002-03-07 00:05:35 +0000184 if self.type == "document_xml" or self.type == "document_html":
185 return xmlDoc(_obj=self._o)
186 else:
187 return None
188 return xmlDoc(_obj=ret)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000189 raise AttributeError,attr
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000190
Daniel Veillard01a6d412002-02-11 18:42:20 +0000191 #
192 # Those are common attributes to nearly all type of nodes
193 #
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000194 def get_parent(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000195 ret = libxml2mod.parent(self._o)
196 if ret == None:
197 return None
198 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000199 def get_children(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000200 ret = libxml2mod.children(self._o)
201 if ret == None:
202 return None
203 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000204 def get_last(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000205 ret = libxml2mod.last(self._o)
206 if ret == None:
207 return None
208 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000209 def get_next(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000210 ret = libxml2mod.next(self._o)
211 if ret == None:
212 return None
213 return xmlNode(_obj=ret)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000214 def get_properties(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000215 ret = libxml2mod.properties(self._o)
216 if ret == None:
217 return None
218 return xmlAttr(_obj=ret)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000219 def get_doc(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000220 ret = libxml2mod.doc(self._o)
221 if ret == None:
222 return None
223 return xmlDoc(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000224 def get_prev(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000225 ret = libxml2mod.prev(self._o)
226 if ret == None:
227 return None
228 return xmlNode(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000229 def get_content(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000230 return libxml2mod.xmlNodeGetContent(self._o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000231 def getContent(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000232 return libxml2mod.xmlNodeGetContent(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000233 def get_name(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000234 return libxml2mod.name(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000235 def get_type(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000236 return libxml2mod.type(self._o)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000237 def get_doc(self):
Daniel Veillard01a6d412002-02-11 18:42:20 +0000238 ret = libxml2mod.doc(self._o)
239 if ret == None:
240 return None
Daniel Veillardf742d342002-03-07 00:05:35 +0000241 return xmlDoc(_obj=ret)
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000242 def free(self):
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000243 libxml2mod.freeDoc(self._o)
Daniel Veillard1e774382002-03-06 17:35:40 +0000244
245 #
246 # Serialization routines, the optional arguments have the following
247 # meaning:
248 # encoding: string to ask saving in a specific encoding
249 # indent: if 1 the serializer is asked to indent the output
250 #
251 def serialize(self, encoding = None, format = 0):
252 return libxml2mod.serializeNode(self._o, encoding, format)
253 def saveTo(self, file, encoding = None, format = 0):
254 return libxml2mod.saveNodeTo(self._o, file, encoding, format)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000255
Daniel Veillardf742d342002-03-07 00:05:35 +0000256 #
257 # Selecting nodes using XPath, a bit slow because the context
258 # is allocated/freed every time but convenient.
259 #
260 def xpathEval(self, expr):
261 doc = self.doc
262 if doc == None:
263 return None
264 ctxt = doc.xpathNewContext()
265 ctxt.setContextNode(self)
266 res = ctxt.xpathEval(expr)
267 ctxt.xpathFreeContext()
268 return res
269
Daniel Veillard36ed5292002-01-30 23:49:06 +0000270#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000271# converters to present a nicer view of the XPath returns
272#
273def nodeWrap(o):
274 # TODO try to cast to the most appropriate node class
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000275 name = libxml2mod.name(o)
Daniel Veillard1971ee22002-01-31 20:29:19 +0000276 if name == "element" or name == "text":
277 return xmlNode(_obj=o)
278 if name == "attribute":
279 return xmlAttr(_obj=o)
280 if name[0:8] == "document":
281 return xmlDoc(_obj=o)
282 if name[0:8] == "namespace":
283 return xmlNs(_obj=o)
284 if name == "elem_decl":
285 return xmlElement(_obj=o)
286 if name == "attribute_decl":
287 return xmlAtribute(_obj=o)
288 if name == "entity_decl":
289 return xmlEntity(_obj=o)
290 if name == "dtd":
291 return xmlAttr(_obj=o)
292 return xmlNode(_obj=o)
293
294def xpathObjectRet(o):
295 if type(o) == type([]) or type(o) == type(()):
296 ret = map(lambda x: nodeWrap(x), o)
Daniel Veillard01a6d412002-02-11 18:42:20 +0000297 return ret
Daniel Veillard1971ee22002-01-31 20:29:19 +0000298 return o
299
300#
Daniel Veillarda7340c82002-02-01 17:56:45 +0000301# register an XPath function
302#
303def registerXPathFunction(ctxt, name, ns_uri, f):
Daniel Veillard5e5c2d02002-02-09 18:03:01 +0000304 ret = libxml2mod.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
Daniel Veillarda7340c82002-02-01 17:56:45 +0000305
Daniel Veillard797a5652002-02-12 13:46:21 +0000306
Daniel Veillarda7340c82002-02-01 17:56:45 +0000307#
Daniel Veillard36ed5292002-01-30 23:49:06 +0000308# Everything below this point is automatically generated
309#
Daniel Veillard1971ee22002-01-31 20:29:19 +0000310