ยปCore Development>Code coverage>Lib/xml/dom/xmlbuilder.py

Python code coverage for Lib/xml/dom/xmlbuilder.py

#countcontent
1n/a"""Implementation of the DOM Level 3 'LS-Load' feature."""
2n/a
3n/aimport copy
4n/aimport warnings
5n/aimport xml.dom
6n/a
7n/afrom xml.dom.NodeFilter import NodeFilter
8n/a
9n/a
10n/a__all__ = ["DOMBuilder", "DOMEntityResolver", "DOMInputSource"]
11n/a
12n/a
13n/aclass Options:
14n/a """Features object that has variables set for each DOMBuilder feature.
15n/a
16n/a The DOMBuilder class uses an instance of this class to pass settings to
17n/a the ExpatBuilder class.
18n/a """
19n/a
20n/a # Note that the DOMBuilder class in LoadSave constrains which of these
21n/a # values can be set using the DOM Level 3 LoadSave feature.
22n/a
23n/a namespaces = 1
24n/a namespace_declarations = True
25n/a validation = False
26n/a external_parameter_entities = True
27n/a external_general_entities = True
28n/a external_dtd_subset = True
29n/a validate_if_schema = False
30n/a validate = False
31n/a datatype_normalization = False
32n/a create_entity_ref_nodes = True
33n/a entities = True
34n/a whitespace_in_element_content = True
35n/a cdata_sections = True
36n/a comments = True
37n/a charset_overrides_xml_encoding = True
38n/a infoset = False
39n/a supported_mediatypes_only = False
40n/a
41n/a errorHandler = None
42n/a filter = None
43n/a
44n/a
45n/aclass DOMBuilder:
46n/a entityResolver = None
47n/a errorHandler = None
48n/a filter = None
49n/a
50n/a ACTION_REPLACE = 1
51n/a ACTION_APPEND_AS_CHILDREN = 2
52n/a ACTION_INSERT_AFTER = 3
53n/a ACTION_INSERT_BEFORE = 4
54n/a
55n/a _legal_actions = (ACTION_REPLACE, ACTION_APPEND_AS_CHILDREN,
56n/a ACTION_INSERT_AFTER, ACTION_INSERT_BEFORE)
57n/a
58n/a def __init__(self):
59n/a self._options = Options()
60n/a
61n/a def _get_entityResolver(self):
62n/a return self.entityResolver
63n/a def _set_entityResolver(self, entityResolver):
64n/a self.entityResolver = entityResolver
65n/a
66n/a def _get_errorHandler(self):
67n/a return self.errorHandler
68n/a def _set_errorHandler(self, errorHandler):
69n/a self.errorHandler = errorHandler
70n/a
71n/a def _get_filter(self):
72n/a return self.filter
73n/a def _set_filter(self, filter):
74n/a self.filter = filter
75n/a
76n/a def setFeature(self, name, state):
77n/a if self.supportsFeature(name):
78n/a state = state and 1 or 0
79n/a try:
80n/a settings = self._settings[(_name_xform(name), state)]
81n/a except KeyError:
82n/a raise xml.dom.NotSupportedErr(
83n/a "unsupported feature: %r" % (name,))
84n/a else:
85n/a for name, value in settings:
86n/a setattr(self._options, name, value)
87n/a else:
88n/a raise xml.dom.NotFoundErr("unknown feature: " + repr(name))
89n/a
90n/a def supportsFeature(self, name):
91n/a return hasattr(self._options, _name_xform(name))
92n/a
93n/a def canSetFeature(self, name, state):
94n/a key = (_name_xform(name), state and 1 or 0)
95n/a return key in self._settings
96n/a
97n/a # This dictionary maps from (feature,value) to a list of
98n/a # (option,value) pairs that should be set on the Options object.
99n/a # If a (feature,value) setting is not in this dictionary, it is
100n/a # not supported by the DOMBuilder.
101n/a #
102n/a _settings = {
103n/a ("namespace_declarations", 0): [
104n/a ("namespace_declarations", 0)],
105n/a ("namespace_declarations", 1): [
106n/a ("namespace_declarations", 1)],
107n/a ("validation", 0): [
108n/a ("validation", 0)],
109n/a ("external_general_entities", 0): [
110n/a ("external_general_entities", 0)],
111n/a ("external_general_entities", 1): [
112n/a ("external_general_entities", 1)],
113n/a ("external_parameter_entities", 0): [
114n/a ("external_parameter_entities", 0)],
115n/a ("external_parameter_entities", 1): [
116n/a ("external_parameter_entities", 1)],
117n/a ("validate_if_schema", 0): [
118n/a ("validate_if_schema", 0)],
119n/a ("create_entity_ref_nodes", 0): [
120n/a ("create_entity_ref_nodes", 0)],
121n/a ("create_entity_ref_nodes", 1): [
122n/a ("create_entity_ref_nodes", 1)],
123n/a ("entities", 0): [
124n/a ("create_entity_ref_nodes", 0),
125n/a ("entities", 0)],
126n/a ("entities", 1): [
127n/a ("entities", 1)],
128n/a ("whitespace_in_element_content", 0): [
129n/a ("whitespace_in_element_content", 0)],
130n/a ("whitespace_in_element_content", 1): [
131n/a ("whitespace_in_element_content", 1)],
132n/a ("cdata_sections", 0): [
133n/a ("cdata_sections", 0)],
134n/a ("cdata_sections", 1): [
135n/a ("cdata_sections", 1)],
136n/a ("comments", 0): [
137n/a ("comments", 0)],
138n/a ("comments", 1): [
139n/a ("comments", 1)],
140n/a ("charset_overrides_xml_encoding", 0): [
141n/a ("charset_overrides_xml_encoding", 0)],
142n/a ("charset_overrides_xml_encoding", 1): [
143n/a ("charset_overrides_xml_encoding", 1)],
144n/a ("infoset", 0): [],
145n/a ("infoset", 1): [
146n/a ("namespace_declarations", 0),
147n/a ("validate_if_schema", 0),
148n/a ("create_entity_ref_nodes", 0),
149n/a ("entities", 0),
150n/a ("cdata_sections", 0),
151n/a ("datatype_normalization", 1),
152n/a ("whitespace_in_element_content", 1),
153n/a ("comments", 1),
154n/a ("charset_overrides_xml_encoding", 1)],
155n/a ("supported_mediatypes_only", 0): [
156n/a ("supported_mediatypes_only", 0)],
157n/a ("namespaces", 0): [
158n/a ("namespaces", 0)],
159n/a ("namespaces", 1): [
160n/a ("namespaces", 1)],
161n/a }
162n/a
163n/a def getFeature(self, name):
164n/a xname = _name_xform(name)
165n/a try:
166n/a return getattr(self._options, xname)
167n/a except AttributeError:
168n/a if name == "infoset":
169n/a options = self._options
170n/a return (options.datatype_normalization
171n/a and options.whitespace_in_element_content
172n/a and options.comments
173n/a and options.charset_overrides_xml_encoding
174n/a and not (options.namespace_declarations
175n/a or options.validate_if_schema
176n/a or options.create_entity_ref_nodes
177n/a or options.entities
178n/a or options.cdata_sections))
179n/a raise xml.dom.NotFoundErr("feature %s not known" % repr(name))
180n/a
181n/a def parseURI(self, uri):
182n/a if self.entityResolver:
183n/a input = self.entityResolver.resolveEntity(None, uri)
184n/a else:
185n/a input = DOMEntityResolver().resolveEntity(None, uri)
186n/a return self.parse(input)
187n/a
188n/a def parse(self, input):
189n/a options = copy.copy(self._options)
190n/a options.filter = self.filter
191n/a options.errorHandler = self.errorHandler
192n/a fp = input.byteStream
193n/a if fp is None and options.systemId:
194n/a import urllib.request
195n/a fp = urllib.request.urlopen(input.systemId)
196n/a return self._parse_bytestream(fp, options)
197n/a
198n/a def parseWithContext(self, input, cnode, action):
199n/a if action not in self._legal_actions:
200n/a raise ValueError("not a legal action")
201n/a raise NotImplementedError("Haven't written this yet...")
202n/a
203n/a def _parse_bytestream(self, stream, options):
204n/a import xml.dom.expatbuilder
205n/a builder = xml.dom.expatbuilder.makeBuilder(options)
206n/a return builder.parseFile(stream)
207n/a
208n/a
209n/adef _name_xform(name):
210n/a return name.lower().replace('-', '_')
211n/a
212n/a
213n/aclass DOMEntityResolver(object):
214n/a __slots__ = '_opener',
215n/a
216n/a def resolveEntity(self, publicId, systemId):
217n/a assert systemId is not None
218n/a source = DOMInputSource()
219n/a source.publicId = publicId
220n/a source.systemId = systemId
221n/a source.byteStream = self._get_opener().open(systemId)
222n/a
223n/a # determine the encoding if the transport provided it
224n/a source.encoding = self._guess_media_encoding(source)
225n/a
226n/a # determine the base URI is we can
227n/a import posixpath, urllib.parse
228n/a parts = urllib.parse.urlparse(systemId)
229n/a scheme, netloc, path, params, query, fragment = parts
230n/a # XXX should we check the scheme here as well?
231n/a if path and not path.endswith("/"):
232n/a path = posixpath.dirname(path) + "/"
233n/a parts = scheme, netloc, path, params, query, fragment
234n/a source.baseURI = urllib.parse.urlunparse(parts)
235n/a
236n/a return source
237n/a
238n/a def _get_opener(self):
239n/a try:
240n/a return self._opener
241n/a except AttributeError:
242n/a self._opener = self._create_opener()
243n/a return self._opener
244n/a
245n/a def _create_opener(self):
246n/a import urllib.request
247n/a return urllib.request.build_opener()
248n/a
249n/a def _guess_media_encoding(self, source):
250n/a info = source.byteStream.info()
251n/a if "Content-Type" in info:
252n/a for param in info.getplist():
253n/a if param.startswith("charset="):
254n/a return param.split("=", 1)[1].lower()
255n/a
256n/a
257n/aclass DOMInputSource(object):
258n/a __slots__ = ('byteStream', 'characterStream', 'stringData',
259n/a 'encoding', 'publicId', 'systemId', 'baseURI')
260n/a
261n/a def __init__(self):
262n/a self.byteStream = None
263n/a self.characterStream = None
264n/a self.stringData = None
265n/a self.encoding = None
266n/a self.publicId = None
267n/a self.systemId = None
268n/a self.baseURI = None
269n/a
270n/a def _get_byteStream(self):
271n/a return self.byteStream
272n/a def _set_byteStream(self, byteStream):
273n/a self.byteStream = byteStream
274n/a
275n/a def _get_characterStream(self):
276n/a return self.characterStream
277n/a def _set_characterStream(self, characterStream):
278n/a self.characterStream = characterStream
279n/a
280n/a def _get_stringData(self):
281n/a return self.stringData
282n/a def _set_stringData(self, data):
283n/a self.stringData = data
284n/a
285n/a def _get_encoding(self):
286n/a return self.encoding
287n/a def _set_encoding(self, encoding):
288n/a self.encoding = encoding
289n/a
290n/a def _get_publicId(self):
291n/a return self.publicId
292n/a def _set_publicId(self, publicId):
293n/a self.publicId = publicId
294n/a
295n/a def _get_systemId(self):
296n/a return self.systemId
297n/a def _set_systemId(self, systemId):
298n/a self.systemId = systemId
299n/a
300n/a def _get_baseURI(self):
301n/a return self.baseURI
302n/a def _set_baseURI(self, uri):
303n/a self.baseURI = uri
304n/a
305n/a
306n/aclass DOMBuilderFilter:
307n/a """Element filter which can be used to tailor construction of
308n/a a DOM instance.
309n/a """
310n/a
311n/a # There's really no need for this class; concrete implementations
312n/a # should just implement the endElement() and startElement()
313n/a # methods as appropriate. Using this makes it easy to only
314n/a # implement one of them.
315n/a
316n/a FILTER_ACCEPT = 1
317n/a FILTER_REJECT = 2
318n/a FILTER_SKIP = 3
319n/a FILTER_INTERRUPT = 4
320n/a
321n/a whatToShow = NodeFilter.SHOW_ALL
322n/a
323n/a def _get_whatToShow(self):
324n/a return self.whatToShow
325n/a
326n/a def acceptNode(self, element):
327n/a return self.FILTER_ACCEPT
328n/a
329n/a def startContainer(self, element):
330n/a return self.FILTER_ACCEPT
331n/a
332n/adel NodeFilter
333n/a
334n/a
335n/aclass _AsyncDeprecatedProperty:
336n/a def warn(self, cls):
337n/a clsname = cls.__name__
338n/a warnings.warn(
339n/a "{cls}.async is deprecated; use {cls}.async_".format(cls=clsname),
340n/a DeprecationWarning)
341n/a
342n/a def __get__(self, instance, cls):
343n/a self.warn(cls)
344n/a if instance is not None:
345n/a return instance.async_
346n/a return False
347n/a
348n/a def __set__(self, instance, value):
349n/a self.warn(type(instance))
350n/a setattr(instance, 'async_', value)
351n/a
352n/a
353n/aclass DocumentLS:
354n/a """Mixin to create documents that conform to the load/save spec."""
355n/a
356n/a async_ = False
357n/a locals()['async'] = _AsyncDeprecatedProperty() # Avoid DeprecationWarning
358n/a
359n/a def _get_async(self):
360n/a return False
361n/a
362n/a def _set_async(self, flag):
363n/a if flag:
364n/a raise xml.dom.NotSupportedErr(
365n/a "asynchronous document loading is not supported")
366n/a
367n/a def abort(self):
368n/a # What does it mean to "clear" a document? Does the
369n/a # documentElement disappear?
370n/a raise NotImplementedError(
371n/a "haven't figured out what this means yet")
372n/a
373n/a def load(self, uri):
374n/a raise NotImplementedError("haven't written this yet")
375n/a
376n/a def loadXML(self, source):
377n/a raise NotImplementedError("haven't written this yet")
378n/a
379n/a def saveXML(self, snode):
380n/a if snode is None:
381n/a snode = self
382n/a elif snode.ownerDocument is not self:
383n/a raise xml.dom.WrongDocumentErr()
384n/a return snode.toxml()
385n/a
386n/a
387n/adel _AsyncDeprecatedProperty
388n/a
389n/a
390n/aclass DOMImplementationLS:
391n/a MODE_SYNCHRONOUS = 1
392n/a MODE_ASYNCHRONOUS = 2
393n/a
394n/a def createDOMBuilder(self, mode, schemaType):
395n/a if schemaType is not None:
396n/a raise xml.dom.NotSupportedErr(
397n/a "schemaType not yet supported")
398n/a if mode == self.MODE_SYNCHRONOUS:
399n/a return DOMBuilder()
400n/a if mode == self.MODE_ASYNCHRONOUS:
401n/a raise xml.dom.NotSupportedErr(
402n/a "asynchronous builders are not supported")
403n/a raise ValueError("unknown value for mode")
404n/a
405n/a def createDOMWriter(self):
406n/a raise NotImplementedError(
407n/a "the writer interface hasn't been written yet!")
408n/a
409n/a def createDOMInputSource(self):
410n/a return DOMInputSource()