xref: /aosp_15_r20/external/libxml2/python/drv_libxml2.py (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker# -*- coding: iso-8859-1 -*-
2*7c568831SAndroid Build Coastguard Worker""" A SAX2 driver for libxml2, on top of it's XmlReader API
3*7c568831SAndroid Build Coastguard Worker
4*7c568831SAndroid Build Coastguard WorkerUSAGE
5*7c568831SAndroid Build Coastguard Worker    # put this file (drv_libxml2.py) in PYTHONPATH
6*7c568831SAndroid Build Coastguard Worker    import xml.sax
7*7c568831SAndroid Build Coastguard Worker    reader = xml.sax.make_parser(["drv_libxml2"])
8*7c568831SAndroid Build Coastguard Worker    # ...and the rest is standard python sax.
9*7c568831SAndroid Build Coastguard Worker
10*7c568831SAndroid Build Coastguard WorkerCAVEATS
11*7c568831SAndroid Build Coastguard Worker    - Lexical handlers are supported, except for start/endEntity
12*7c568831SAndroid Build Coastguard Worker      (waiting for XmlReader.ResolveEntity) and start/endDTD
13*7c568831SAndroid Build Coastguard Worker    - Error callbacks are not exactly synchronous, they tend
14*7c568831SAndroid Build Coastguard Worker      to be invoked before the corresponding content callback,
15*7c568831SAndroid Build Coastguard Worker      because the underlying reader interface parses
16*7c568831SAndroid Build Coastguard Worker      data by chunks of 512 bytes
17*7c568831SAndroid Build Coastguard Worker
18*7c568831SAndroid Build Coastguard WorkerTODO
19*7c568831SAndroid Build Coastguard Worker    - search for TODO
20*7c568831SAndroid Build Coastguard Worker    - some ErrorHandler events (warning)
21*7c568831SAndroid Build Coastguard Worker    - some ContentHandler events (setDocumentLocator, skippedEntity)
22*7c568831SAndroid Build Coastguard Worker    - EntityResolver (using libxml2.?)
23*7c568831SAndroid Build Coastguard Worker    - DTDHandler (if/when libxml2 exposes such node types)
24*7c568831SAndroid Build Coastguard Worker    - DeclHandler (if/when libxml2 exposes such node types)
25*7c568831SAndroid Build Coastguard Worker    - property_xml_string?
26*7c568831SAndroid Build Coastguard Worker    - feature_string_interning?
27*7c568831SAndroid Build Coastguard Worker    - Incremental parser
28*7c568831SAndroid Build Coastguard Worker    - additional performance tuning:
29*7c568831SAndroid Build Coastguard Worker      - one might cache callbacks to avoid some name lookups
30*7c568831SAndroid Build Coastguard Worker      - one might implement a smarter way to pass attributes to startElement
31*7c568831SAndroid Build Coastguard Worker        (some kind of lazy evaluation?)
32*7c568831SAndroid Build Coastguard Worker      - there might be room for improvement in start/endPrefixMapping
33*7c568831SAndroid Build Coastguard Worker      - other?
34*7c568831SAndroid Build Coastguard Worker
35*7c568831SAndroid Build Coastguard Worker"""
36*7c568831SAndroid Build Coastguard Worker
37*7c568831SAndroid Build Coastguard Worker__author__  = "St�phane Bidoul <[email protected]>"
38*7c568831SAndroid Build Coastguard Worker__version__ = "0.3"
39*7c568831SAndroid Build Coastguard Worker
40*7c568831SAndroid Build Coastguard Workerimport sys
41*7c568831SAndroid Build Coastguard Workerimport codecs
42*7c568831SAndroid Build Coastguard Worker
43*7c568831SAndroid Build Coastguard Workerif sys.version_info[0] < 3:
44*7c568831SAndroid Build Coastguard Worker    __author__  = codecs.unicode_escape_decode(__author__)[0]
45*7c568831SAndroid Build Coastguard Worker
46*7c568831SAndroid Build Coastguard Worker    StringTypes = (str, unicode)
47*7c568831SAndroid Build Coastguard Worker    # libxml2 returns strings as UTF8
48*7c568831SAndroid Build Coastguard Worker    _decoder = codecs.lookup("utf8")[1]
49*7c568831SAndroid Build Coastguard Worker    def _d(s):
50*7c568831SAndroid Build Coastguard Worker        if s is None:
51*7c568831SAndroid Build Coastguard Worker            return s
52*7c568831SAndroid Build Coastguard Worker        else:
53*7c568831SAndroid Build Coastguard Worker            return _decoder(s)[0]
54*7c568831SAndroid Build Coastguard Workerelse:
55*7c568831SAndroid Build Coastguard Worker    StringTypes = str
56*7c568831SAndroid Build Coastguard Worker    # s is Unicode `str` already
57*7c568831SAndroid Build Coastguard Worker    def _d(s):
58*7c568831SAndroid Build Coastguard Worker        return s
59*7c568831SAndroid Build Coastguard Worker
60*7c568831SAndroid Build Coastguard Workerfrom xml.sax._exceptions import *
61*7c568831SAndroid Build Coastguard Workerfrom xml.sax import xmlreader, saxutils
62*7c568831SAndroid Build Coastguard Workerfrom xml.sax.handler import \
63*7c568831SAndroid Build Coastguard Worker     feature_namespaces, \
64*7c568831SAndroid Build Coastguard Worker     feature_namespace_prefixes, \
65*7c568831SAndroid Build Coastguard Worker     feature_string_interning, \
66*7c568831SAndroid Build Coastguard Worker     feature_validation, \
67*7c568831SAndroid Build Coastguard Worker     feature_external_ges, \
68*7c568831SAndroid Build Coastguard Worker     feature_external_pes, \
69*7c568831SAndroid Build Coastguard Worker     property_lexical_handler, \
70*7c568831SAndroid Build Coastguard Worker     property_declaration_handler, \
71*7c568831SAndroid Build Coastguard Worker     property_dom_node, \
72*7c568831SAndroid Build Coastguard Worker     property_xml_string
73*7c568831SAndroid Build Coastguard Worker
74*7c568831SAndroid Build Coastguard Workertry:
75*7c568831SAndroid Build Coastguard Worker    import libxml2
76*7c568831SAndroid Build Coastguard Workerexcept ImportError:
77*7c568831SAndroid Build Coastguard Worker    raise SAXReaderNotAvailable("libxml2 not available: " \
78*7c568831SAndroid Build Coastguard Worker                                "import error was: %s" % sys.exc_info()[1])
79*7c568831SAndroid Build Coastguard Worker
80*7c568831SAndroid Build Coastguard Workerclass Locator(xmlreader.Locator):
81*7c568831SAndroid Build Coastguard Worker    """SAX Locator adapter for libxml2.xmlTextReaderLocator"""
82*7c568831SAndroid Build Coastguard Worker
83*7c568831SAndroid Build Coastguard Worker    def __init__(self,locator):
84*7c568831SAndroid Build Coastguard Worker        self.__locator = locator
85*7c568831SAndroid Build Coastguard Worker
86*7c568831SAndroid Build Coastguard Worker    def getColumnNumber(self):
87*7c568831SAndroid Build Coastguard Worker        "Return the column number where the current event ends."
88*7c568831SAndroid Build Coastguard Worker        return -1
89*7c568831SAndroid Build Coastguard Worker
90*7c568831SAndroid Build Coastguard Worker    def getLineNumber(self):
91*7c568831SAndroid Build Coastguard Worker        "Return the line number where the current event ends."
92*7c568831SAndroid Build Coastguard Worker        return self.__locator.LineNumber()
93*7c568831SAndroid Build Coastguard Worker
94*7c568831SAndroid Build Coastguard Worker    def getPublicId(self):
95*7c568831SAndroid Build Coastguard Worker        "Return the public identifier for the current event."
96*7c568831SAndroid Build Coastguard Worker        return None
97*7c568831SAndroid Build Coastguard Worker
98*7c568831SAndroid Build Coastguard Worker    def getSystemId(self):
99*7c568831SAndroid Build Coastguard Worker        "Return the system identifier for the current event."
100*7c568831SAndroid Build Coastguard Worker        return self.__locator.BaseURI()
101*7c568831SAndroid Build Coastguard Worker
102*7c568831SAndroid Build Coastguard Workerclass LibXml2Reader(xmlreader.XMLReader):
103*7c568831SAndroid Build Coastguard Worker
104*7c568831SAndroid Build Coastguard Worker    def __init__(self):
105*7c568831SAndroid Build Coastguard Worker        xmlreader.XMLReader.__init__(self)
106*7c568831SAndroid Build Coastguard Worker        # features
107*7c568831SAndroid Build Coastguard Worker        self.__ns = 0
108*7c568831SAndroid Build Coastguard Worker        self.__nspfx = 0
109*7c568831SAndroid Build Coastguard Worker        self.__validate = 0
110*7c568831SAndroid Build Coastguard Worker        self.__extparams = 1
111*7c568831SAndroid Build Coastguard Worker        # parsing flag
112*7c568831SAndroid Build Coastguard Worker        self.__parsing = 0
113*7c568831SAndroid Build Coastguard Worker        # additional handlers
114*7c568831SAndroid Build Coastguard Worker        self.__lex_handler = None
115*7c568831SAndroid Build Coastguard Worker        self.__decl_handler = None
116*7c568831SAndroid Build Coastguard Worker        # error messages accumulator
117*7c568831SAndroid Build Coastguard Worker        self.__errors = None
118*7c568831SAndroid Build Coastguard Worker
119*7c568831SAndroid Build Coastguard Worker    def _errorHandler(self,arg,msg,severity,locator):
120*7c568831SAndroid Build Coastguard Worker        if self.__errors is None:
121*7c568831SAndroid Build Coastguard Worker            self.__errors = []
122*7c568831SAndroid Build Coastguard Worker        self.__errors.append((severity,
123*7c568831SAndroid Build Coastguard Worker                              SAXParseException(msg,None,
124*7c568831SAndroid Build Coastguard Worker                                                Locator(locator))))
125*7c568831SAndroid Build Coastguard Worker
126*7c568831SAndroid Build Coastguard Worker    def _reportErrors(self,fatal):
127*7c568831SAndroid Build Coastguard Worker        for severity,exception in self.__errors:
128*7c568831SAndroid Build Coastguard Worker            if severity in (libxml2.PARSER_SEVERITY_VALIDITY_WARNING,
129*7c568831SAndroid Build Coastguard Worker                            libxml2.PARSER_SEVERITY_WARNING):
130*7c568831SAndroid Build Coastguard Worker                self._err_handler.warning(exception)
131*7c568831SAndroid Build Coastguard Worker            else:
132*7c568831SAndroid Build Coastguard Worker                # when fatal is set, the parse will stop;
133*7c568831SAndroid Build Coastguard Worker                # we consider that the last error reported
134*7c568831SAndroid Build Coastguard Worker                # is the fatal one.
135*7c568831SAndroid Build Coastguard Worker                if fatal and exception is self.__errors[-1][1]:
136*7c568831SAndroid Build Coastguard Worker                    self._err_handler.fatalError(exception)
137*7c568831SAndroid Build Coastguard Worker                else:
138*7c568831SAndroid Build Coastguard Worker                    self._err_handler.error(exception)
139*7c568831SAndroid Build Coastguard Worker        self.__errors = None
140*7c568831SAndroid Build Coastguard Worker
141*7c568831SAndroid Build Coastguard Worker    def parse(self, source):
142*7c568831SAndroid Build Coastguard Worker        self.__parsing = 1
143*7c568831SAndroid Build Coastguard Worker        try:
144*7c568831SAndroid Build Coastguard Worker            # prepare source and create reader
145*7c568831SAndroid Build Coastguard Worker            if isinstance(source, StringTypes):
146*7c568831SAndroid Build Coastguard Worker                reader = libxml2.newTextReaderFilename(source)
147*7c568831SAndroid Build Coastguard Worker            else:
148*7c568831SAndroid Build Coastguard Worker                source = saxutils.prepare_input_source(source)
149*7c568831SAndroid Build Coastguard Worker                stream = source.getCharacterStream()
150*7c568831SAndroid Build Coastguard Worker                if stream is None:
151*7c568831SAndroid Build Coastguard Worker                    stream = source.getByteStream()
152*7c568831SAndroid Build Coastguard Worker                input = libxml2.inputBuffer(stream)
153*7c568831SAndroid Build Coastguard Worker                reader = input.newTextReader(source.getSystemId())
154*7c568831SAndroid Build Coastguard Worker            reader.SetErrorHandler(self._errorHandler,None)
155*7c568831SAndroid Build Coastguard Worker            # configure reader
156*7c568831SAndroid Build Coastguard Worker            if self.__extparams:
157*7c568831SAndroid Build Coastguard Worker                reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
158*7c568831SAndroid Build Coastguard Worker                reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
159*7c568831SAndroid Build Coastguard Worker                reader.SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1)
160*7c568831SAndroid Build Coastguard Worker                reader.SetParserProp(libxml2.PARSER_VALIDATE,self.__validate)
161*7c568831SAndroid Build Coastguard Worker            else:
162*7c568831SAndroid Build Coastguard Worker                reader.SetParserProp(libxml2.PARSER_LOADDTD, 0)
163*7c568831SAndroid Build Coastguard Worker            # we reuse attribute maps (for a slight performance gain)
164*7c568831SAndroid Build Coastguard Worker            if self.__ns:
165*7c568831SAndroid Build Coastguard Worker                attributesNSImpl = xmlreader.AttributesNSImpl({},{})
166*7c568831SAndroid Build Coastguard Worker            else:
167*7c568831SAndroid Build Coastguard Worker                attributesImpl = xmlreader.AttributesImpl({})
168*7c568831SAndroid Build Coastguard Worker            # prefixes to pop (for endPrefixMapping)
169*7c568831SAndroid Build Coastguard Worker            prefixes = []
170*7c568831SAndroid Build Coastguard Worker            # start loop
171*7c568831SAndroid Build Coastguard Worker            self._cont_handler.startDocument()
172*7c568831SAndroid Build Coastguard Worker            while 1:
173*7c568831SAndroid Build Coastguard Worker                r = reader.Read()
174*7c568831SAndroid Build Coastguard Worker                # check for errors
175*7c568831SAndroid Build Coastguard Worker                if r == 1:
176*7c568831SAndroid Build Coastguard Worker                    if not self.__errors is None:
177*7c568831SAndroid Build Coastguard Worker                        self._reportErrors(0)
178*7c568831SAndroid Build Coastguard Worker                elif r == 0:
179*7c568831SAndroid Build Coastguard Worker                    if not self.__errors is None:
180*7c568831SAndroid Build Coastguard Worker                        self._reportErrors(0)
181*7c568831SAndroid Build Coastguard Worker                    break # end of parse
182*7c568831SAndroid Build Coastguard Worker                else:
183*7c568831SAndroid Build Coastguard Worker                    if not self.__errors is None:
184*7c568831SAndroid Build Coastguard Worker                        self._reportErrors(1)
185*7c568831SAndroid Build Coastguard Worker                    else:
186*7c568831SAndroid Build Coastguard Worker                        self._err_handler.fatalError(\
187*7c568831SAndroid Build Coastguard Worker                            SAXException("Read failed (no details available)"))
188*7c568831SAndroid Build Coastguard Worker                    break # fatal parse error
189*7c568831SAndroid Build Coastguard Worker                # get node type
190*7c568831SAndroid Build Coastguard Worker                nodeType = reader.NodeType()
191*7c568831SAndroid Build Coastguard Worker                # Element
192*7c568831SAndroid Build Coastguard Worker                if nodeType == 1:
193*7c568831SAndroid Build Coastguard Worker                    if self.__ns:
194*7c568831SAndroid Build Coastguard Worker                        eltName = (_d(reader.NamespaceUri()),\
195*7c568831SAndroid Build Coastguard Worker                                   _d(reader.LocalName()))
196*7c568831SAndroid Build Coastguard Worker                        eltQName = _d(reader.Name())
197*7c568831SAndroid Build Coastguard Worker                        attributesNSImpl._attrs = attrs = {}
198*7c568831SAndroid Build Coastguard Worker                        attributesNSImpl._qnames = qnames = {}
199*7c568831SAndroid Build Coastguard Worker                        newPrefixes = []
200*7c568831SAndroid Build Coastguard Worker                        while reader.MoveToNextAttribute():
201*7c568831SAndroid Build Coastguard Worker                            qname = _d(reader.Name())
202*7c568831SAndroid Build Coastguard Worker                            value = _d(reader.Value())
203*7c568831SAndroid Build Coastguard Worker                            if qname.startswith("xmlns"):
204*7c568831SAndroid Build Coastguard Worker                                if len(qname) > 5:
205*7c568831SAndroid Build Coastguard Worker                                    newPrefix = qname[6:]
206*7c568831SAndroid Build Coastguard Worker                                else:
207*7c568831SAndroid Build Coastguard Worker                                    newPrefix = None
208*7c568831SAndroid Build Coastguard Worker                                newPrefixes.append(newPrefix)
209*7c568831SAndroid Build Coastguard Worker                                self._cont_handler.startPrefixMapping(\
210*7c568831SAndroid Build Coastguard Worker                                    newPrefix,value)
211*7c568831SAndroid Build Coastguard Worker                                if not self.__nspfx:
212*7c568831SAndroid Build Coastguard Worker                                    continue # don't report xmlns attribute
213*7c568831SAndroid Build Coastguard Worker                            attName = (_d(reader.NamespaceUri()),
214*7c568831SAndroid Build Coastguard Worker                                       _d(reader.LocalName()))
215*7c568831SAndroid Build Coastguard Worker                            qnames[attName] = qname
216*7c568831SAndroid Build Coastguard Worker                            attrs[attName] = value
217*7c568831SAndroid Build Coastguard Worker                        reader.MoveToElement()
218*7c568831SAndroid Build Coastguard Worker                        self._cont_handler.startElementNS( \
219*7c568831SAndroid Build Coastguard Worker                            eltName,eltQName,attributesNSImpl)
220*7c568831SAndroid Build Coastguard Worker                        if reader.IsEmptyElement():
221*7c568831SAndroid Build Coastguard Worker                            self._cont_handler.endElementNS(eltName,eltQName)
222*7c568831SAndroid Build Coastguard Worker                            for newPrefix in newPrefixes:
223*7c568831SAndroid Build Coastguard Worker                                self._cont_handler.endPrefixMapping(newPrefix)
224*7c568831SAndroid Build Coastguard Worker                        else:
225*7c568831SAndroid Build Coastguard Worker                            prefixes.append(newPrefixes)
226*7c568831SAndroid Build Coastguard Worker                    else:
227*7c568831SAndroid Build Coastguard Worker                        eltName = _d(reader.Name())
228*7c568831SAndroid Build Coastguard Worker                        attributesImpl._attrs = attrs = {}
229*7c568831SAndroid Build Coastguard Worker                        while reader.MoveToNextAttribute():
230*7c568831SAndroid Build Coastguard Worker                            attName = _d(reader.Name())
231*7c568831SAndroid Build Coastguard Worker                            attrs[attName] = _d(reader.Value())
232*7c568831SAndroid Build Coastguard Worker                        reader.MoveToElement()
233*7c568831SAndroid Build Coastguard Worker                        self._cont_handler.startElement( \
234*7c568831SAndroid Build Coastguard Worker                            eltName,attributesImpl)
235*7c568831SAndroid Build Coastguard Worker                        if reader.IsEmptyElement():
236*7c568831SAndroid Build Coastguard Worker                            self._cont_handler.endElement(eltName)
237*7c568831SAndroid Build Coastguard Worker                # EndElement
238*7c568831SAndroid Build Coastguard Worker                elif nodeType == 15:
239*7c568831SAndroid Build Coastguard Worker                    if self.__ns:
240*7c568831SAndroid Build Coastguard Worker                        self._cont_handler.endElementNS( \
241*7c568831SAndroid Build Coastguard Worker                             (_d(reader.NamespaceUri()),_d(reader.LocalName())),
242*7c568831SAndroid Build Coastguard Worker                             _d(reader.Name()))
243*7c568831SAndroid Build Coastguard Worker                        for prefix in prefixes.pop():
244*7c568831SAndroid Build Coastguard Worker                            self._cont_handler.endPrefixMapping(prefix)
245*7c568831SAndroid Build Coastguard Worker                    else:
246*7c568831SAndroid Build Coastguard Worker                        self._cont_handler.endElement(_d(reader.Name()))
247*7c568831SAndroid Build Coastguard Worker                # Text
248*7c568831SAndroid Build Coastguard Worker                elif nodeType == 3:
249*7c568831SAndroid Build Coastguard Worker                    self._cont_handler.characters(_d(reader.Value()))
250*7c568831SAndroid Build Coastguard Worker                # Whitespace
251*7c568831SAndroid Build Coastguard Worker                elif nodeType == 13:
252*7c568831SAndroid Build Coastguard Worker                    self._cont_handler.ignorableWhitespace(_d(reader.Value()))
253*7c568831SAndroid Build Coastguard Worker                # SignificantWhitespace
254*7c568831SAndroid Build Coastguard Worker                elif nodeType == 14:
255*7c568831SAndroid Build Coastguard Worker                    self._cont_handler.characters(_d(reader.Value()))
256*7c568831SAndroid Build Coastguard Worker                # CDATA
257*7c568831SAndroid Build Coastguard Worker                elif nodeType == 4:
258*7c568831SAndroid Build Coastguard Worker                    if not self.__lex_handler is None:
259*7c568831SAndroid Build Coastguard Worker                        self.__lex_handler.startCDATA()
260*7c568831SAndroid Build Coastguard Worker                    self._cont_handler.characters(_d(reader.Value()))
261*7c568831SAndroid Build Coastguard Worker                    if not self.__lex_handler is None:
262*7c568831SAndroid Build Coastguard Worker                        self.__lex_handler.endCDATA()
263*7c568831SAndroid Build Coastguard Worker                # EntityReference
264*7c568831SAndroid Build Coastguard Worker                elif nodeType == 5:
265*7c568831SAndroid Build Coastguard Worker                    if not self.__lex_handler is None:
266*7c568831SAndroid Build Coastguard Worker                        self.startEntity(_d(reader.Name()))
267*7c568831SAndroid Build Coastguard Worker                    reader.ResolveEntity()
268*7c568831SAndroid Build Coastguard Worker                # EndEntity
269*7c568831SAndroid Build Coastguard Worker                elif nodeType == 16:
270*7c568831SAndroid Build Coastguard Worker                    if not self.__lex_handler is None:
271*7c568831SAndroid Build Coastguard Worker                        self.endEntity(_d(reader.Name()))
272*7c568831SAndroid Build Coastguard Worker                # ProcessingInstruction
273*7c568831SAndroid Build Coastguard Worker                elif nodeType == 7:
274*7c568831SAndroid Build Coastguard Worker                    self._cont_handler.processingInstruction( \
275*7c568831SAndroid Build Coastguard Worker                        _d(reader.Name()),_d(reader.Value()))
276*7c568831SAndroid Build Coastguard Worker                # Comment
277*7c568831SAndroid Build Coastguard Worker                elif nodeType == 8:
278*7c568831SAndroid Build Coastguard Worker                    if not self.__lex_handler is None:
279*7c568831SAndroid Build Coastguard Worker                        self.__lex_handler.comment(_d(reader.Value()))
280*7c568831SAndroid Build Coastguard Worker                # DocumentType
281*7c568831SAndroid Build Coastguard Worker                elif nodeType == 10:
282*7c568831SAndroid Build Coastguard Worker                    #if not self.__lex_handler is None:
283*7c568831SAndroid Build Coastguard Worker                    #    self.__lex_handler.startDTD()
284*7c568831SAndroid Build Coastguard Worker                    pass # TODO (how to detect endDTD? on first non-dtd event?)
285*7c568831SAndroid Build Coastguard Worker                # XmlDeclaration
286*7c568831SAndroid Build Coastguard Worker                elif nodeType == 17:
287*7c568831SAndroid Build Coastguard Worker                    pass # TODO
288*7c568831SAndroid Build Coastguard Worker                # Entity
289*7c568831SAndroid Build Coastguard Worker                elif nodeType == 6:
290*7c568831SAndroid Build Coastguard Worker                    pass # TODO (entity decl)
291*7c568831SAndroid Build Coastguard Worker                # Notation (decl)
292*7c568831SAndroid Build Coastguard Worker                elif nodeType == 12:
293*7c568831SAndroid Build Coastguard Worker                    pass # TODO
294*7c568831SAndroid Build Coastguard Worker                # Attribute (never in this loop)
295*7c568831SAndroid Build Coastguard Worker                #elif nodeType == 2:
296*7c568831SAndroid Build Coastguard Worker                #    pass
297*7c568831SAndroid Build Coastguard Worker                # Document (not exposed)
298*7c568831SAndroid Build Coastguard Worker                #elif nodeType == 9:
299*7c568831SAndroid Build Coastguard Worker                #    pass
300*7c568831SAndroid Build Coastguard Worker                # DocumentFragment (never returned by XmlReader)
301*7c568831SAndroid Build Coastguard Worker                #elif nodeType == 11:
302*7c568831SAndroid Build Coastguard Worker                #    pass
303*7c568831SAndroid Build Coastguard Worker                # None
304*7c568831SAndroid Build Coastguard Worker                #elif nodeType == 0:
305*7c568831SAndroid Build Coastguard Worker                #    pass
306*7c568831SAndroid Build Coastguard Worker                # -
307*7c568831SAndroid Build Coastguard Worker                else:
308*7c568831SAndroid Build Coastguard Worker                    raise SAXException("Unexpected node type %d" % nodeType)
309*7c568831SAndroid Build Coastguard Worker            if r == 0:
310*7c568831SAndroid Build Coastguard Worker                self._cont_handler.endDocument()
311*7c568831SAndroid Build Coastguard Worker            reader.Close()
312*7c568831SAndroid Build Coastguard Worker        finally:
313*7c568831SAndroid Build Coastguard Worker            self.__parsing = 0
314*7c568831SAndroid Build Coastguard Worker
315*7c568831SAndroid Build Coastguard Worker    def setDTDHandler(self, handler):
316*7c568831SAndroid Build Coastguard Worker        # TODO (when supported, the inherited method works just fine)
317*7c568831SAndroid Build Coastguard Worker        raise SAXNotSupportedException("DTDHandler not supported")
318*7c568831SAndroid Build Coastguard Worker
319*7c568831SAndroid Build Coastguard Worker    def setEntityResolver(self, resolver):
320*7c568831SAndroid Build Coastguard Worker        # TODO (when supported, the inherited method works just fine)
321*7c568831SAndroid Build Coastguard Worker        raise SAXNotSupportedException("EntityResolver not supported")
322*7c568831SAndroid Build Coastguard Worker
323*7c568831SAndroid Build Coastguard Worker    def getFeature(self, name):
324*7c568831SAndroid Build Coastguard Worker        if name == feature_namespaces:
325*7c568831SAndroid Build Coastguard Worker            return self.__ns
326*7c568831SAndroid Build Coastguard Worker        elif name == feature_namespace_prefixes:
327*7c568831SAndroid Build Coastguard Worker            return self.__nspfx
328*7c568831SAndroid Build Coastguard Worker        elif name == feature_validation:
329*7c568831SAndroid Build Coastguard Worker            return self.__validate
330*7c568831SAndroid Build Coastguard Worker        elif name == feature_external_ges:
331*7c568831SAndroid Build Coastguard Worker            return 1 # TODO (does that relate to PARSER_LOADDTD)?
332*7c568831SAndroid Build Coastguard Worker        elif name == feature_external_pes:
333*7c568831SAndroid Build Coastguard Worker            return self.__extparams
334*7c568831SAndroid Build Coastguard Worker        else:
335*7c568831SAndroid Build Coastguard Worker            raise SAXNotRecognizedException("Feature '%s' not recognized" % \
336*7c568831SAndroid Build Coastguard Worker                                            name)
337*7c568831SAndroid Build Coastguard Worker
338*7c568831SAndroid Build Coastguard Worker    def setFeature(self, name, state):
339*7c568831SAndroid Build Coastguard Worker        if self.__parsing:
340*7c568831SAndroid Build Coastguard Worker            raise SAXNotSupportedException("Cannot set feature %s " \
341*7c568831SAndroid Build Coastguard Worker                                           "while parsing" % name)
342*7c568831SAndroid Build Coastguard Worker        if name == feature_namespaces:
343*7c568831SAndroid Build Coastguard Worker            self.__ns = state
344*7c568831SAndroid Build Coastguard Worker        elif name == feature_namespace_prefixes:
345*7c568831SAndroid Build Coastguard Worker            self.__nspfx = state
346*7c568831SAndroid Build Coastguard Worker        elif name == feature_validation:
347*7c568831SAndroid Build Coastguard Worker            self.__validate = state
348*7c568831SAndroid Build Coastguard Worker        elif name == feature_external_ges:
349*7c568831SAndroid Build Coastguard Worker            if state == 0:
350*7c568831SAndroid Build Coastguard Worker                # TODO (does that relate to PARSER_LOADDTD)?
351*7c568831SAndroid Build Coastguard Worker                raise SAXNotSupportedException("Feature '%s' not supported" % \
352*7c568831SAndroid Build Coastguard Worker                                               name)
353*7c568831SAndroid Build Coastguard Worker        elif name == feature_external_pes:
354*7c568831SAndroid Build Coastguard Worker            self.__extparams = state
355*7c568831SAndroid Build Coastguard Worker        else:
356*7c568831SAndroid Build Coastguard Worker            raise SAXNotRecognizedException("Feature '%s' not recognized" % \
357*7c568831SAndroid Build Coastguard Worker                                            name)
358*7c568831SAndroid Build Coastguard Worker
359*7c568831SAndroid Build Coastguard Worker    def getProperty(self, name):
360*7c568831SAndroid Build Coastguard Worker        if name == property_lexical_handler:
361*7c568831SAndroid Build Coastguard Worker            return self.__lex_handler
362*7c568831SAndroid Build Coastguard Worker        elif name == property_declaration_handler:
363*7c568831SAndroid Build Coastguard Worker            return self.__decl_handler
364*7c568831SAndroid Build Coastguard Worker        else:
365*7c568831SAndroid Build Coastguard Worker            raise SAXNotRecognizedException("Property '%s' not recognized" % \
366*7c568831SAndroid Build Coastguard Worker                                            name)
367*7c568831SAndroid Build Coastguard Worker
368*7c568831SAndroid Build Coastguard Worker    def setProperty(self, name, value):
369*7c568831SAndroid Build Coastguard Worker        if name == property_lexical_handler:
370*7c568831SAndroid Build Coastguard Worker            self.__lex_handler = value
371*7c568831SAndroid Build Coastguard Worker        elif name == property_declaration_handler:
372*7c568831SAndroid Build Coastguard Worker            # TODO: remove if/when libxml2 supports dtd events
373*7c568831SAndroid Build Coastguard Worker            raise SAXNotSupportedException("Property '%s' not supported" % \
374*7c568831SAndroid Build Coastguard Worker                                           name)
375*7c568831SAndroid Build Coastguard Worker            self.__decl_handler = value
376*7c568831SAndroid Build Coastguard Worker        else:
377*7c568831SAndroid Build Coastguard Worker            raise SAXNotRecognizedException("Property '%s' not recognized" % \
378*7c568831SAndroid Build Coastguard Worker                                            name)
379*7c568831SAndroid Build Coastguard Worker
380*7c568831SAndroid Build Coastguard Workerdef create_parser():
381*7c568831SAndroid Build Coastguard Worker    return LibXml2Reader()
382*7c568831SAndroid Build Coastguard Worker
383