xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/xml/sax/xmlreader.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""An XML Reader is the SAX 2 name for an XML parser. XML Parsers
2*cda5da8dSAndroid Build Coastguard Workershould be based on this code. """
3*cda5da8dSAndroid Build Coastguard Worker
4*cda5da8dSAndroid Build Coastguard Workerfrom . import handler
5*cda5da8dSAndroid Build Coastguard Worker
6*cda5da8dSAndroid Build Coastguard Workerfrom ._exceptions import SAXNotSupportedException, SAXNotRecognizedException
7*cda5da8dSAndroid Build Coastguard Worker
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard Worker# ===== XMLREADER =====
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Workerclass XMLReader:
12*cda5da8dSAndroid Build Coastguard Worker    """Interface for reading an XML document using callbacks.
13*cda5da8dSAndroid Build Coastguard Worker
14*cda5da8dSAndroid Build Coastguard Worker    XMLReader is the interface that an XML parser's SAX2 driver must
15*cda5da8dSAndroid Build Coastguard Worker    implement. This interface allows an application to set and query
16*cda5da8dSAndroid Build Coastguard Worker    features and properties in the parser, to register event handlers
17*cda5da8dSAndroid Build Coastguard Worker    for document processing, and to initiate a document parse.
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard Worker    All SAX interfaces are assumed to be synchronous: the parse
20*cda5da8dSAndroid Build Coastguard Worker    methods must not return until parsing is complete, and readers
21*cda5da8dSAndroid Build Coastguard Worker    must wait for an event-handler callback to return before reporting
22*cda5da8dSAndroid Build Coastguard Worker    the next event."""
23*cda5da8dSAndroid Build Coastguard Worker
24*cda5da8dSAndroid Build Coastguard Worker    def __init__(self):
25*cda5da8dSAndroid Build Coastguard Worker        self._cont_handler = handler.ContentHandler()
26*cda5da8dSAndroid Build Coastguard Worker        self._dtd_handler = handler.DTDHandler()
27*cda5da8dSAndroid Build Coastguard Worker        self._ent_handler = handler.EntityResolver()
28*cda5da8dSAndroid Build Coastguard Worker        self._err_handler = handler.ErrorHandler()
29*cda5da8dSAndroid Build Coastguard Worker
30*cda5da8dSAndroid Build Coastguard Worker    def parse(self, source):
31*cda5da8dSAndroid Build Coastguard Worker        "Parse an XML document from a system identifier or an InputSource."
32*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("This method must be implemented!")
33*cda5da8dSAndroid Build Coastguard Worker
34*cda5da8dSAndroid Build Coastguard Worker    def getContentHandler(self):
35*cda5da8dSAndroid Build Coastguard Worker        "Returns the current ContentHandler."
36*cda5da8dSAndroid Build Coastguard Worker        return self._cont_handler
37*cda5da8dSAndroid Build Coastguard Worker
38*cda5da8dSAndroid Build Coastguard Worker    def setContentHandler(self, handler):
39*cda5da8dSAndroid Build Coastguard Worker        "Registers a new object to receive document content events."
40*cda5da8dSAndroid Build Coastguard Worker        self._cont_handler = handler
41*cda5da8dSAndroid Build Coastguard Worker
42*cda5da8dSAndroid Build Coastguard Worker    def getDTDHandler(self):
43*cda5da8dSAndroid Build Coastguard Worker        "Returns the current DTD handler."
44*cda5da8dSAndroid Build Coastguard Worker        return self._dtd_handler
45*cda5da8dSAndroid Build Coastguard Worker
46*cda5da8dSAndroid Build Coastguard Worker    def setDTDHandler(self, handler):
47*cda5da8dSAndroid Build Coastguard Worker        "Register an object to receive basic DTD-related events."
48*cda5da8dSAndroid Build Coastguard Worker        self._dtd_handler = handler
49*cda5da8dSAndroid Build Coastguard Worker
50*cda5da8dSAndroid Build Coastguard Worker    def getEntityResolver(self):
51*cda5da8dSAndroid Build Coastguard Worker        "Returns the current EntityResolver."
52*cda5da8dSAndroid Build Coastguard Worker        return self._ent_handler
53*cda5da8dSAndroid Build Coastguard Worker
54*cda5da8dSAndroid Build Coastguard Worker    def setEntityResolver(self, resolver):
55*cda5da8dSAndroid Build Coastguard Worker        "Register an object to resolve external entities."
56*cda5da8dSAndroid Build Coastguard Worker        self._ent_handler = resolver
57*cda5da8dSAndroid Build Coastguard Worker
58*cda5da8dSAndroid Build Coastguard Worker    def getErrorHandler(self):
59*cda5da8dSAndroid Build Coastguard Worker        "Returns the current ErrorHandler."
60*cda5da8dSAndroid Build Coastguard Worker        return self._err_handler
61*cda5da8dSAndroid Build Coastguard Worker
62*cda5da8dSAndroid Build Coastguard Worker    def setErrorHandler(self, handler):
63*cda5da8dSAndroid Build Coastguard Worker        "Register an object to receive error-message events."
64*cda5da8dSAndroid Build Coastguard Worker        self._err_handler = handler
65*cda5da8dSAndroid Build Coastguard Worker
66*cda5da8dSAndroid Build Coastguard Worker    def setLocale(self, locale):
67*cda5da8dSAndroid Build Coastguard Worker        """Allow an application to set the locale for errors and warnings.
68*cda5da8dSAndroid Build Coastguard Worker
69*cda5da8dSAndroid Build Coastguard Worker        SAX parsers are not required to provide localization for errors
70*cda5da8dSAndroid Build Coastguard Worker        and warnings; if they cannot support the requested locale,
71*cda5da8dSAndroid Build Coastguard Worker        however, they must raise a SAX exception. Applications may
72*cda5da8dSAndroid Build Coastguard Worker        request a locale change in the middle of a parse."""
73*cda5da8dSAndroid Build Coastguard Worker        raise SAXNotSupportedException("Locale support not implemented")
74*cda5da8dSAndroid Build Coastguard Worker
75*cda5da8dSAndroid Build Coastguard Worker    def getFeature(self, name):
76*cda5da8dSAndroid Build Coastguard Worker        "Looks up and returns the state of a SAX2 feature."
77*cda5da8dSAndroid Build Coastguard Worker        raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
78*cda5da8dSAndroid Build Coastguard Worker
79*cda5da8dSAndroid Build Coastguard Worker    def setFeature(self, name, state):
80*cda5da8dSAndroid Build Coastguard Worker        "Sets the state of a SAX2 feature."
81*cda5da8dSAndroid Build Coastguard Worker        raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
82*cda5da8dSAndroid Build Coastguard Worker
83*cda5da8dSAndroid Build Coastguard Worker    def getProperty(self, name):
84*cda5da8dSAndroid Build Coastguard Worker        "Looks up and returns the value of a SAX2 property."
85*cda5da8dSAndroid Build Coastguard Worker        raise SAXNotRecognizedException("Property '%s' not recognized" % name)
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Worker    def setProperty(self, name, value):
88*cda5da8dSAndroid Build Coastguard Worker        "Sets the value of a SAX2 property."
89*cda5da8dSAndroid Build Coastguard Worker        raise SAXNotRecognizedException("Property '%s' not recognized" % name)
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Workerclass IncrementalParser(XMLReader):
92*cda5da8dSAndroid Build Coastguard Worker    """This interface adds three extra methods to the XMLReader
93*cda5da8dSAndroid Build Coastguard Worker    interface that allow XML parsers to support incremental
94*cda5da8dSAndroid Build Coastguard Worker    parsing. Support for this interface is optional, since not all
95*cda5da8dSAndroid Build Coastguard Worker    underlying XML parsers support this functionality.
96*cda5da8dSAndroid Build Coastguard Worker
97*cda5da8dSAndroid Build Coastguard Worker    When the parser is instantiated it is ready to begin accepting
98*cda5da8dSAndroid Build Coastguard Worker    data from the feed method immediately. After parsing has been
99*cda5da8dSAndroid Build Coastguard Worker    finished with a call to close the reset method must be called to
100*cda5da8dSAndroid Build Coastguard Worker    make the parser ready to accept new data, either from feed or
101*cda5da8dSAndroid Build Coastguard Worker    using the parse method.
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard Worker    Note that these methods must _not_ be called during parsing, that
104*cda5da8dSAndroid Build Coastguard Worker    is, after parse has been called and before it returns.
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker    By default, the class also implements the parse method of the XMLReader
107*cda5da8dSAndroid Build Coastguard Worker    interface using the feed, close and reset methods of the
108*cda5da8dSAndroid Build Coastguard Worker    IncrementalParser interface as a convenience to SAX 2.0 driver
109*cda5da8dSAndroid Build Coastguard Worker    writers."""
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, bufsize=2**16):
112*cda5da8dSAndroid Build Coastguard Worker        self._bufsize = bufsize
113*cda5da8dSAndroid Build Coastguard Worker        XMLReader.__init__(self)
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker    def parse(self, source):
116*cda5da8dSAndroid Build Coastguard Worker        from . import saxutils
117*cda5da8dSAndroid Build Coastguard Worker        source = saxutils.prepare_input_source(source)
118*cda5da8dSAndroid Build Coastguard Worker
119*cda5da8dSAndroid Build Coastguard Worker        self.prepareParser(source)
120*cda5da8dSAndroid Build Coastguard Worker        file = source.getCharacterStream()
121*cda5da8dSAndroid Build Coastguard Worker        if file is None:
122*cda5da8dSAndroid Build Coastguard Worker            file = source.getByteStream()
123*cda5da8dSAndroid Build Coastguard Worker        buffer = file.read(self._bufsize)
124*cda5da8dSAndroid Build Coastguard Worker        while buffer:
125*cda5da8dSAndroid Build Coastguard Worker            self.feed(buffer)
126*cda5da8dSAndroid Build Coastguard Worker            buffer = file.read(self._bufsize)
127*cda5da8dSAndroid Build Coastguard Worker        self.close()
128*cda5da8dSAndroid Build Coastguard Worker
129*cda5da8dSAndroid Build Coastguard Worker    def feed(self, data):
130*cda5da8dSAndroid Build Coastguard Worker        """This method gives the raw XML data in the data parameter to
131*cda5da8dSAndroid Build Coastguard Worker        the parser and makes it parse the data, emitting the
132*cda5da8dSAndroid Build Coastguard Worker        corresponding events. It is allowed for XML constructs to be
133*cda5da8dSAndroid Build Coastguard Worker        split across several calls to feed.
134*cda5da8dSAndroid Build Coastguard Worker
135*cda5da8dSAndroid Build Coastguard Worker        feed may raise SAXException."""
136*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("This method must be implemented!")
137*cda5da8dSAndroid Build Coastguard Worker
138*cda5da8dSAndroid Build Coastguard Worker    def prepareParser(self, source):
139*cda5da8dSAndroid Build Coastguard Worker        """This method is called by the parse implementation to allow
140*cda5da8dSAndroid Build Coastguard Worker        the SAX 2.0 driver to prepare itself for parsing."""
141*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("prepareParser must be overridden!")
142*cda5da8dSAndroid Build Coastguard Worker
143*cda5da8dSAndroid Build Coastguard Worker    def close(self):
144*cda5da8dSAndroid Build Coastguard Worker        """This method is called when the entire XML document has been
145*cda5da8dSAndroid Build Coastguard Worker        passed to the parser through the feed method, to notify the
146*cda5da8dSAndroid Build Coastguard Worker        parser that there are no more data. This allows the parser to
147*cda5da8dSAndroid Build Coastguard Worker        do the final checks on the document and empty the internal
148*cda5da8dSAndroid Build Coastguard Worker        data buffer.
149*cda5da8dSAndroid Build Coastguard Worker
150*cda5da8dSAndroid Build Coastguard Worker        The parser will not be ready to parse another document until
151*cda5da8dSAndroid Build Coastguard Worker        the reset method has been called.
152*cda5da8dSAndroid Build Coastguard Worker
153*cda5da8dSAndroid Build Coastguard Worker        close may raise SAXException."""
154*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("This method must be implemented!")
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Worker    def reset(self):
157*cda5da8dSAndroid Build Coastguard Worker        """This method is called after close has been called to reset
158*cda5da8dSAndroid Build Coastguard Worker        the parser so that it is ready to parse new documents. The
159*cda5da8dSAndroid Build Coastguard Worker        results of calling parse or feed after close without calling
160*cda5da8dSAndroid Build Coastguard Worker        reset are undefined."""
161*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError("This method must be implemented!")
162*cda5da8dSAndroid Build Coastguard Worker
163*cda5da8dSAndroid Build Coastguard Worker# ===== LOCATOR =====
164*cda5da8dSAndroid Build Coastguard Worker
165*cda5da8dSAndroid Build Coastguard Workerclass Locator:
166*cda5da8dSAndroid Build Coastguard Worker    """Interface for associating a SAX event with a document
167*cda5da8dSAndroid Build Coastguard Worker    location. A locator object will return valid results only during
168*cda5da8dSAndroid Build Coastguard Worker    calls to DocumentHandler methods; at any other time, the
169*cda5da8dSAndroid Build Coastguard Worker    results are unpredictable."""
170*cda5da8dSAndroid Build Coastguard Worker
171*cda5da8dSAndroid Build Coastguard Worker    def getColumnNumber(self):
172*cda5da8dSAndroid Build Coastguard Worker        "Return the column number where the current event ends."
173*cda5da8dSAndroid Build Coastguard Worker        return -1
174*cda5da8dSAndroid Build Coastguard Worker
175*cda5da8dSAndroid Build Coastguard Worker    def getLineNumber(self):
176*cda5da8dSAndroid Build Coastguard Worker        "Return the line number where the current event ends."
177*cda5da8dSAndroid Build Coastguard Worker        return -1
178*cda5da8dSAndroid Build Coastguard Worker
179*cda5da8dSAndroid Build Coastguard Worker    def getPublicId(self):
180*cda5da8dSAndroid Build Coastguard Worker        "Return the public identifier for the current event."
181*cda5da8dSAndroid Build Coastguard Worker        return None
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Worker    def getSystemId(self):
184*cda5da8dSAndroid Build Coastguard Worker        "Return the system identifier for the current event."
185*cda5da8dSAndroid Build Coastguard Worker        return None
186*cda5da8dSAndroid Build Coastguard Worker
187*cda5da8dSAndroid Build Coastguard Worker# ===== INPUTSOURCE =====
188*cda5da8dSAndroid Build Coastguard Worker
189*cda5da8dSAndroid Build Coastguard Workerclass InputSource:
190*cda5da8dSAndroid Build Coastguard Worker    """Encapsulation of the information needed by the XMLReader to
191*cda5da8dSAndroid Build Coastguard Worker    read entities.
192*cda5da8dSAndroid Build Coastguard Worker
193*cda5da8dSAndroid Build Coastguard Worker    This class may include information about the public identifier,
194*cda5da8dSAndroid Build Coastguard Worker    system identifier, byte stream (possibly with character encoding
195*cda5da8dSAndroid Build Coastguard Worker    information) and/or the character stream of an entity.
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker    Applications will create objects of this class for use in the
198*cda5da8dSAndroid Build Coastguard Worker    XMLReader.parse method and for returning from
199*cda5da8dSAndroid Build Coastguard Worker    EntityResolver.resolveEntity.
200*cda5da8dSAndroid Build Coastguard Worker
201*cda5da8dSAndroid Build Coastguard Worker    An InputSource belongs to the application, the XMLReader is not
202*cda5da8dSAndroid Build Coastguard Worker    allowed to modify InputSource objects passed to it from the
203*cda5da8dSAndroid Build Coastguard Worker    application, although it may make copies and modify those."""
204*cda5da8dSAndroid Build Coastguard Worker
205*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, system_id = None):
206*cda5da8dSAndroid Build Coastguard Worker        self.__system_id = system_id
207*cda5da8dSAndroid Build Coastguard Worker        self.__public_id = None
208*cda5da8dSAndroid Build Coastguard Worker        self.__encoding  = None
209*cda5da8dSAndroid Build Coastguard Worker        self.__bytefile  = None
210*cda5da8dSAndroid Build Coastguard Worker        self.__charfile  = None
211*cda5da8dSAndroid Build Coastguard Worker
212*cda5da8dSAndroid Build Coastguard Worker    def setPublicId(self, public_id):
213*cda5da8dSAndroid Build Coastguard Worker        "Sets the public identifier of this InputSource."
214*cda5da8dSAndroid Build Coastguard Worker        self.__public_id = public_id
215*cda5da8dSAndroid Build Coastguard Worker
216*cda5da8dSAndroid Build Coastguard Worker    def getPublicId(self):
217*cda5da8dSAndroid Build Coastguard Worker        "Returns the public identifier of this InputSource."
218*cda5da8dSAndroid Build Coastguard Worker        return self.__public_id
219*cda5da8dSAndroid Build Coastguard Worker
220*cda5da8dSAndroid Build Coastguard Worker    def setSystemId(self, system_id):
221*cda5da8dSAndroid Build Coastguard Worker        "Sets the system identifier of this InputSource."
222*cda5da8dSAndroid Build Coastguard Worker        self.__system_id = system_id
223*cda5da8dSAndroid Build Coastguard Worker
224*cda5da8dSAndroid Build Coastguard Worker    def getSystemId(self):
225*cda5da8dSAndroid Build Coastguard Worker        "Returns the system identifier of this InputSource."
226*cda5da8dSAndroid Build Coastguard Worker        return self.__system_id
227*cda5da8dSAndroid Build Coastguard Worker
228*cda5da8dSAndroid Build Coastguard Worker    def setEncoding(self, encoding):
229*cda5da8dSAndroid Build Coastguard Worker        """Sets the character encoding of this InputSource.
230*cda5da8dSAndroid Build Coastguard Worker
231*cda5da8dSAndroid Build Coastguard Worker        The encoding must be a string acceptable for an XML encoding
232*cda5da8dSAndroid Build Coastguard Worker        declaration (see section 4.3.3 of the XML recommendation).
233*cda5da8dSAndroid Build Coastguard Worker
234*cda5da8dSAndroid Build Coastguard Worker        The encoding attribute of the InputSource is ignored if the
235*cda5da8dSAndroid Build Coastguard Worker        InputSource also contains a character stream."""
236*cda5da8dSAndroid Build Coastguard Worker        self.__encoding = encoding
237*cda5da8dSAndroid Build Coastguard Worker
238*cda5da8dSAndroid Build Coastguard Worker    def getEncoding(self):
239*cda5da8dSAndroid Build Coastguard Worker        "Get the character encoding of this InputSource."
240*cda5da8dSAndroid Build Coastguard Worker        return self.__encoding
241*cda5da8dSAndroid Build Coastguard Worker
242*cda5da8dSAndroid Build Coastguard Worker    def setByteStream(self, bytefile):
243*cda5da8dSAndroid Build Coastguard Worker        """Set the byte stream (a Python file-like object which does
244*cda5da8dSAndroid Build Coastguard Worker        not perform byte-to-character conversion) for this input
245*cda5da8dSAndroid Build Coastguard Worker        source.
246*cda5da8dSAndroid Build Coastguard Worker
247*cda5da8dSAndroid Build Coastguard Worker        The SAX parser will ignore this if there is also a character
248*cda5da8dSAndroid Build Coastguard Worker        stream specified, but it will use a byte stream in preference
249*cda5da8dSAndroid Build Coastguard Worker        to opening a URI connection itself.
250*cda5da8dSAndroid Build Coastguard Worker
251*cda5da8dSAndroid Build Coastguard Worker        If the application knows the character encoding of the byte
252*cda5da8dSAndroid Build Coastguard Worker        stream, it should set it with the setEncoding method."""
253*cda5da8dSAndroid Build Coastguard Worker        self.__bytefile = bytefile
254*cda5da8dSAndroid Build Coastguard Worker
255*cda5da8dSAndroid Build Coastguard Worker    def getByteStream(self):
256*cda5da8dSAndroid Build Coastguard Worker        """Get the byte stream for this input source.
257*cda5da8dSAndroid Build Coastguard Worker
258*cda5da8dSAndroid Build Coastguard Worker        The getEncoding method will return the character encoding for
259*cda5da8dSAndroid Build Coastguard Worker        this byte stream, or None if unknown."""
260*cda5da8dSAndroid Build Coastguard Worker        return self.__bytefile
261*cda5da8dSAndroid Build Coastguard Worker
262*cda5da8dSAndroid Build Coastguard Worker    def setCharacterStream(self, charfile):
263*cda5da8dSAndroid Build Coastguard Worker        """Set the character stream for this input source. (The stream
264*cda5da8dSAndroid Build Coastguard Worker        must be a Python 2.0 Unicode-wrapped file-like that performs
265*cda5da8dSAndroid Build Coastguard Worker        conversion to Unicode strings.)
266*cda5da8dSAndroid Build Coastguard Worker
267*cda5da8dSAndroid Build Coastguard Worker        If there is a character stream specified, the SAX parser will
268*cda5da8dSAndroid Build Coastguard Worker        ignore any byte stream and will not attempt to open a URI
269*cda5da8dSAndroid Build Coastguard Worker        connection to the system identifier."""
270*cda5da8dSAndroid Build Coastguard Worker        self.__charfile = charfile
271*cda5da8dSAndroid Build Coastguard Worker
272*cda5da8dSAndroid Build Coastguard Worker    def getCharacterStream(self):
273*cda5da8dSAndroid Build Coastguard Worker        "Get the character stream for this input source."
274*cda5da8dSAndroid Build Coastguard Worker        return self.__charfile
275*cda5da8dSAndroid Build Coastguard Worker
276*cda5da8dSAndroid Build Coastguard Worker# ===== ATTRIBUTESIMPL =====
277*cda5da8dSAndroid Build Coastguard Worker
278*cda5da8dSAndroid Build Coastguard Workerclass AttributesImpl:
279*cda5da8dSAndroid Build Coastguard Worker
280*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, attrs):
281*cda5da8dSAndroid Build Coastguard Worker        """Non-NS-aware implementation.
282*cda5da8dSAndroid Build Coastguard Worker
283*cda5da8dSAndroid Build Coastguard Worker        attrs should be of the form {name : value}."""
284*cda5da8dSAndroid Build Coastguard Worker        self._attrs = attrs
285*cda5da8dSAndroid Build Coastguard Worker
286*cda5da8dSAndroid Build Coastguard Worker    def getLength(self):
287*cda5da8dSAndroid Build Coastguard Worker        return len(self._attrs)
288*cda5da8dSAndroid Build Coastguard Worker
289*cda5da8dSAndroid Build Coastguard Worker    def getType(self, name):
290*cda5da8dSAndroid Build Coastguard Worker        return "CDATA"
291*cda5da8dSAndroid Build Coastguard Worker
292*cda5da8dSAndroid Build Coastguard Worker    def getValue(self, name):
293*cda5da8dSAndroid Build Coastguard Worker        return self._attrs[name]
294*cda5da8dSAndroid Build Coastguard Worker
295*cda5da8dSAndroid Build Coastguard Worker    def getValueByQName(self, name):
296*cda5da8dSAndroid Build Coastguard Worker        return self._attrs[name]
297*cda5da8dSAndroid Build Coastguard Worker
298*cda5da8dSAndroid Build Coastguard Worker    def getNameByQName(self, name):
299*cda5da8dSAndroid Build Coastguard Worker        if name not in self._attrs:
300*cda5da8dSAndroid Build Coastguard Worker            raise KeyError(name)
301*cda5da8dSAndroid Build Coastguard Worker        return name
302*cda5da8dSAndroid Build Coastguard Worker
303*cda5da8dSAndroid Build Coastguard Worker    def getQNameByName(self, name):
304*cda5da8dSAndroid Build Coastguard Worker        if name not in self._attrs:
305*cda5da8dSAndroid Build Coastguard Worker            raise KeyError(name)
306*cda5da8dSAndroid Build Coastguard Worker        return name
307*cda5da8dSAndroid Build Coastguard Worker
308*cda5da8dSAndroid Build Coastguard Worker    def getNames(self):
309*cda5da8dSAndroid Build Coastguard Worker        return list(self._attrs.keys())
310*cda5da8dSAndroid Build Coastguard Worker
311*cda5da8dSAndroid Build Coastguard Worker    def getQNames(self):
312*cda5da8dSAndroid Build Coastguard Worker        return list(self._attrs.keys())
313*cda5da8dSAndroid Build Coastguard Worker
314*cda5da8dSAndroid Build Coastguard Worker    def __len__(self):
315*cda5da8dSAndroid Build Coastguard Worker        return len(self._attrs)
316*cda5da8dSAndroid Build Coastguard Worker
317*cda5da8dSAndroid Build Coastguard Worker    def __getitem__(self, name):
318*cda5da8dSAndroid Build Coastguard Worker        return self._attrs[name]
319*cda5da8dSAndroid Build Coastguard Worker
320*cda5da8dSAndroid Build Coastguard Worker    def keys(self):
321*cda5da8dSAndroid Build Coastguard Worker        return list(self._attrs.keys())
322*cda5da8dSAndroid Build Coastguard Worker
323*cda5da8dSAndroid Build Coastguard Worker    def __contains__(self, name):
324*cda5da8dSAndroid Build Coastguard Worker        return name in self._attrs
325*cda5da8dSAndroid Build Coastguard Worker
326*cda5da8dSAndroid Build Coastguard Worker    def get(self, name, alternative=None):
327*cda5da8dSAndroid Build Coastguard Worker        return self._attrs.get(name, alternative)
328*cda5da8dSAndroid Build Coastguard Worker
329*cda5da8dSAndroid Build Coastguard Worker    def copy(self):
330*cda5da8dSAndroid Build Coastguard Worker        return self.__class__(self._attrs)
331*cda5da8dSAndroid Build Coastguard Worker
332*cda5da8dSAndroid Build Coastguard Worker    def items(self):
333*cda5da8dSAndroid Build Coastguard Worker        return list(self._attrs.items())
334*cda5da8dSAndroid Build Coastguard Worker
335*cda5da8dSAndroid Build Coastguard Worker    def values(self):
336*cda5da8dSAndroid Build Coastguard Worker        return list(self._attrs.values())
337*cda5da8dSAndroid Build Coastguard Worker
338*cda5da8dSAndroid Build Coastguard Worker# ===== ATTRIBUTESNSIMPL =====
339*cda5da8dSAndroid Build Coastguard Worker
340*cda5da8dSAndroid Build Coastguard Workerclass AttributesNSImpl(AttributesImpl):
341*cda5da8dSAndroid Build Coastguard Worker
342*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, attrs, qnames):
343*cda5da8dSAndroid Build Coastguard Worker        """NS-aware implementation.
344*cda5da8dSAndroid Build Coastguard Worker
345*cda5da8dSAndroid Build Coastguard Worker        attrs should be of the form {(ns_uri, lname): value, ...}.
346*cda5da8dSAndroid Build Coastguard Worker        qnames of the form {(ns_uri, lname): qname, ...}."""
347*cda5da8dSAndroid Build Coastguard Worker        self._attrs = attrs
348*cda5da8dSAndroid Build Coastguard Worker        self._qnames = qnames
349*cda5da8dSAndroid Build Coastguard Worker
350*cda5da8dSAndroid Build Coastguard Worker    def getValueByQName(self, name):
351*cda5da8dSAndroid Build Coastguard Worker        for (nsname, qname) in self._qnames.items():
352*cda5da8dSAndroid Build Coastguard Worker            if qname == name:
353*cda5da8dSAndroid Build Coastguard Worker                return self._attrs[nsname]
354*cda5da8dSAndroid Build Coastguard Worker
355*cda5da8dSAndroid Build Coastguard Worker        raise KeyError(name)
356*cda5da8dSAndroid Build Coastguard Worker
357*cda5da8dSAndroid Build Coastguard Worker    def getNameByQName(self, name):
358*cda5da8dSAndroid Build Coastguard Worker        for (nsname, qname) in self._qnames.items():
359*cda5da8dSAndroid Build Coastguard Worker            if qname == name:
360*cda5da8dSAndroid Build Coastguard Worker                return nsname
361*cda5da8dSAndroid Build Coastguard Worker
362*cda5da8dSAndroid Build Coastguard Worker        raise KeyError(name)
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Worker    def getQNameByName(self, name):
365*cda5da8dSAndroid Build Coastguard Worker        return self._qnames[name]
366*cda5da8dSAndroid Build Coastguard Worker
367*cda5da8dSAndroid Build Coastguard Worker    def getQNames(self):
368*cda5da8dSAndroid Build Coastguard Worker        return list(self._qnames.values())
369*cda5da8dSAndroid Build Coastguard Worker
370*cda5da8dSAndroid Build Coastguard Worker    def copy(self):
371*cda5da8dSAndroid Build Coastguard Worker        return self.__class__(self._attrs, self._qnames)
372*cda5da8dSAndroid Build Coastguard Worker
373*cda5da8dSAndroid Build Coastguard Worker
374*cda5da8dSAndroid Build Coastguard Workerdef _test():
375*cda5da8dSAndroid Build Coastguard Worker    XMLReader()
376*cda5da8dSAndroid Build Coastguard Worker    IncrementalParser()
377*cda5da8dSAndroid Build Coastguard Worker    Locator()
378*cda5da8dSAndroid Build Coastguard Worker
379*cda5da8dSAndroid Build Coastguard Workerif __name__ == "__main__":
380*cda5da8dSAndroid Build Coastguard Worker    _test()
381