blob: 8bc33d8392954ab6f192fda7f4ec4bdf5822cced [file] [log] [blame]
Fred Drake45cd9de2000-06-29 19:34:54 +00001import handler
2
3"""An XML Reader is the SAX 2 name for an XML parser. XML Parsers
4should be based on this code. """
5# ===== XMLREADER =====
6
7class XMLReader:
8 def __init__(self):
Skip Montanarof9059eb2000-07-06 03:01:40 +00009 self._cont_handler = handler.ContentHandler()
10 #self._dtd_handler = handler.DTDHandler()
11 #self._ent_handler = handler.EntityResolver()
12 self._err_handler = handler.ErrorHandler()
Fred Drake45cd9de2000-06-29 19:34:54 +000013
14 def parse(self, source):
Skip Montanarof9059eb2000-07-06 03:01:40 +000015 "Parse an XML document from a system identifier or an InputSource."
Fred Drake45cd9de2000-06-29 19:34:54 +000016 raise NotImplementedError("This method must be implemented!")
17
18 def getContentHandler(self):
19 "Returns the current ContentHandler."
20 return self._cont_handler
21
22 def setContentHandler(self, handler):
23 "Registers a new object to receive document content events."
24 self._cont_handler = handler
25
26 def getDTDHandler(self):
27 "Returns the current DTD handler."
28 return self._dtd_handler
29
30 def setDTDHandler(self, handler):
Skip Montanarof9059eb2000-07-06 03:01:40 +000031 "Register an object to receive basic DTD-related events."
32 self._dtd_handler = handler
Fred Drake45cd9de2000-06-29 19:34:54 +000033
34 def getEntityResolver(self):
35 "Returns the current EntityResolver."
36 return self._ent_handler
37
38 def setEntityResolver(self, resolver):
Skip Montanarof9059eb2000-07-06 03:01:40 +000039 "Register an object to resolve external entities."
40 self._ent_handler = resolver
Fred Drake45cd9de2000-06-29 19:34:54 +000041
42 def getErrorHandler(self):
43 "Returns the current ErrorHandler."
44 return self._err_handler
45
46 def setErrorHandler(self, handler):
Skip Montanarof9059eb2000-07-06 03:01:40 +000047 "Register an object to receive error-message events."
48 self._err_handler = handler
Fred Drake45cd9de2000-06-29 19:34:54 +000049
50 def setLocale(self, locale):
51 """Allow an application to set the locale for errors and warnings.
52
53 SAX parsers are not required to provide localisation for errors
54 and warnings; if they cannot support the requested locale,
55 however, they must throw a SAX exception. Applications may
56 request a locale change in the middle of a parse."""
57 raise SAXNotSupportedException("Locale support not implemented")
58
59 def getFeature(self, name):
60 "Looks up and returns the state of a SAX2 feature."
61 raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
62
63 def setFeature(self, name, state):
64 "Sets the state of a SAX2 feature."
65 raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
66
67 def getProperty(self, name):
68 "Looks up and returns the value of a SAX2 property."
69 raise SAXNotRecognizedException("Property '%s' not recognized" % name)
70
71 def setProperty(self, name, value):
72 "Sets the value of a SAX2 property."
73 raise SAXNotRecognizedException("Property '%s' not recognized" % name)
74
75
76class IncrementalParser(XMLReader):
77 """This interface adds three extra methods to the XMLReader
78 interface that allow XML parsers to support incremental
79 parsing. Support for this interface is optional, since not all
80 underlying XML parsers support this functionality.
81
82 When the parser is instantiated it is ready to begin accepting
83 data from the feed method immediately. After parsing has been
84 finished with a call to close the reset method must be called to
85 make the parser ready to accept new data, either from feed or
86 using the parse method.
87
88 Note that these methods must _not_ be called during parsing, that
89 is, after parse has been called and before it returns.
90
91 By default, the class also implements the parse method of the XMLReader
92 interface using the feed, close and reset methods of the
93 IncrementalParser interface as a convenience to SAX 2.0 driver
94 writers."""
95 def __init__(self, bufsize=2**16 ):
96 self._bufsize=bufsize
97 XMLReader.__init__( self )
98
99 def parse(self, source):
100 self.prepareParser(source)
101 #FIXME: do some type checking: could be already stream, URL or
102 # filename
103 inf=open( source )
104 buffer = inf.read(self._bufsize)
105 while buffer != "":
106 self.feed(buffer)
107 buffer = inf.read(self._bufsize)
108 self.close()
109 self.reset()
110
111 def feed(self, data):
112 """This method gives the raw XML data in the data parameter to
113 the parser and makes it parse the data, emitting the
114 corresponding events. It is allowed for XML constructs to be
115 split across several calls to feed.
116
117 feed may raise SAXException."""
118 raise NotImplementedError("This method must be implemented!")
119 def prepareParser(self, source):
120 """This method is called by the parse implementation to allow
121 the SAX 2.0 driver to prepare itself for parsing."""
122 raise NotImplementedError("prepareParser must be overridden!")
123
124 def close(self):
125 """This method is called when the entire XML document has been
126 passed to the parser through the feed method, to notify the
127 parser that there are no more data. This allows the parser to
128 do the final checks on the document and empty the internal
129 data buffer.
130
131 The parser will not be ready to parse another document until
132 the reset method has been called.
133
134 close may raise SAXException."""
135 raise NotImplementedError("This method must be implemented!")
136
137 def reset(self):
138 """This method is called after close has been called to reset
139 the parser so that it is ready to parse new documents. The
140 results of calling parse or feed after close without calling
141 reset are undefined."""
142 raise NotImplementedError("This method must be implemented!")
143
144# ===== LOCATOR =====
145class Locator:
146 """Interface for associating a SAX event with a document
147 location. A locator object will return valid results only during
148 calls to DocumentHandler methods; at any other time, the
149 results are unpredictable."""
150
151 def getColumnNumber(self):
Skip Montanarof9059eb2000-07-06 03:01:40 +0000152 "Return the column number where the current event ends."
153 return -1
Fred Drake45cd9de2000-06-29 19:34:54 +0000154
155 def getLineNumber(self):
Skip Montanarof9059eb2000-07-06 03:01:40 +0000156 "Return the line number where the current event ends."
157 return -1
Fred Drake45cd9de2000-06-29 19:34:54 +0000158
159 def getPublicId(self):
Skip Montanarof9059eb2000-07-06 03:01:40 +0000160 "Return the public identifier for the current event."
161 return None
Fred Drake45cd9de2000-06-29 19:34:54 +0000162
163 def getSystemId(self):
Skip Montanarof9059eb2000-07-06 03:01:40 +0000164 "Return the system identifier for the current event."
165 return None
Fred Drake45cd9de2000-06-29 19:34:54 +0000166
167# --- AttributesImpl
168class AttributesImpl:
169 def __init__(self, attrs, rawnames):
170 self._attrs = attrs
171 self._rawnames = rawnames
172
173 def getLength(self):
174 return len(self._attrs)
175
176 def getType(self, name):
177 return "CDATA"
178
179 def getValue(self, name):
180 return self._attrs[name]
181
182 def getValueByQName(self, name):
183 return self._attrs[self._rawnames[name]]
184
185 def getNameByQName(self, name):
186 return self._rawnames[name]
187
188 def getNames(self):
189 return self._attrs.keys()
190
191 def getQNames(self):
192 return self._rawnames.keys()
193
194 def __len__(self):
195 return len(self._attrs)
196
197 def __getitem__(self, name):
198 return self._attrs[name]
199
200 def keys(self):
201 return self._attrs.keys()
202
203 def has_key(self, name):
204 return self._attrs.has_key(name)
205
206 def get(self, name, alternative=None):
207 return self._attrs.get(name, alternative)
208
209 def copy(self):
210 return self.__class__(self._attrs, self._rawnames)
211
212 def items(self):
213 return self._attrs.items()
214
215 def values(self):
216 return self._attrs.values()
217
218def _test():
219 XMLReader()
220 IncrementalParser()
221 Locator()
222 AttributesImpl()
223
224if __name__=="__main__":
225 _test()