jpayne@68
|
1 """Registration facilities for DOM. This module should not be used
|
jpayne@68
|
2 directly. Instead, the functions getDOMImplementation and
|
jpayne@68
|
3 registerDOMImplementation should be imported from xml.dom."""
|
jpayne@68
|
4
|
jpayne@68
|
5 # This is a list of well-known implementations. Well-known names
|
jpayne@68
|
6 # should be published by posting to xml-sig@python.org, and are
|
jpayne@68
|
7 # subsequently recorded in this file.
|
jpayne@68
|
8
|
jpayne@68
|
9 import sys
|
jpayne@68
|
10
|
jpayne@68
|
11 well_known_implementations = {
|
jpayne@68
|
12 'minidom':'xml.dom.minidom',
|
jpayne@68
|
13 '4DOM': 'xml.dom.DOMImplementation',
|
jpayne@68
|
14 }
|
jpayne@68
|
15
|
jpayne@68
|
16 # DOM implementations not officially registered should register
|
jpayne@68
|
17 # themselves with their
|
jpayne@68
|
18
|
jpayne@68
|
19 registered = {}
|
jpayne@68
|
20
|
jpayne@68
|
21 def registerDOMImplementation(name, factory):
|
jpayne@68
|
22 """registerDOMImplementation(name, factory)
|
jpayne@68
|
23
|
jpayne@68
|
24 Register the factory function with the name. The factory function
|
jpayne@68
|
25 should return an object which implements the DOMImplementation
|
jpayne@68
|
26 interface. The factory function can either return the same object,
|
jpayne@68
|
27 or a new one (e.g. if that implementation supports some
|
jpayne@68
|
28 customization)."""
|
jpayne@68
|
29
|
jpayne@68
|
30 registered[name] = factory
|
jpayne@68
|
31
|
jpayne@68
|
32 def _good_enough(dom, features):
|
jpayne@68
|
33 "_good_enough(dom, features) -> Return 1 if the dom offers the features"
|
jpayne@68
|
34 for f,v in features:
|
jpayne@68
|
35 if not dom.hasFeature(f,v):
|
jpayne@68
|
36 return 0
|
jpayne@68
|
37 return 1
|
jpayne@68
|
38
|
jpayne@68
|
39 def getDOMImplementation(name=None, features=()):
|
jpayne@68
|
40 """getDOMImplementation(name = None, features = ()) -> DOM implementation.
|
jpayne@68
|
41
|
jpayne@68
|
42 Return a suitable DOM implementation. The name is either
|
jpayne@68
|
43 well-known, the module name of a DOM implementation, or None. If
|
jpayne@68
|
44 it is not None, imports the corresponding module and returns
|
jpayne@68
|
45 DOMImplementation object if the import succeeds.
|
jpayne@68
|
46
|
jpayne@68
|
47 If name is not given, consider the available implementations to
|
jpayne@68
|
48 find one with the required feature set. If no implementation can
|
jpayne@68
|
49 be found, raise an ImportError. The features list must be a sequence
|
jpayne@68
|
50 of (feature, version) pairs which are passed to hasFeature."""
|
jpayne@68
|
51
|
jpayne@68
|
52 import os
|
jpayne@68
|
53 creator = None
|
jpayne@68
|
54 mod = well_known_implementations.get(name)
|
jpayne@68
|
55 if mod:
|
jpayne@68
|
56 mod = __import__(mod, {}, {}, ['getDOMImplementation'])
|
jpayne@68
|
57 return mod.getDOMImplementation()
|
jpayne@68
|
58 elif name:
|
jpayne@68
|
59 return registered[name]()
|
jpayne@68
|
60 elif not sys.flags.ignore_environment and "PYTHON_DOM" in os.environ:
|
jpayne@68
|
61 return getDOMImplementation(name = os.environ["PYTHON_DOM"])
|
jpayne@68
|
62
|
jpayne@68
|
63 # User did not specify a name, try implementations in arbitrary
|
jpayne@68
|
64 # order, returning the one that has the required features
|
jpayne@68
|
65 if isinstance(features, str):
|
jpayne@68
|
66 features = _parse_feature_string(features)
|
jpayne@68
|
67 for creator in registered.values():
|
jpayne@68
|
68 dom = creator()
|
jpayne@68
|
69 if _good_enough(dom, features):
|
jpayne@68
|
70 return dom
|
jpayne@68
|
71
|
jpayne@68
|
72 for creator in well_known_implementations.keys():
|
jpayne@68
|
73 try:
|
jpayne@68
|
74 dom = getDOMImplementation(name = creator)
|
jpayne@68
|
75 except Exception: # typically ImportError, or AttributeError
|
jpayne@68
|
76 continue
|
jpayne@68
|
77 if _good_enough(dom, features):
|
jpayne@68
|
78 return dom
|
jpayne@68
|
79
|
jpayne@68
|
80 raise ImportError("no suitable DOM implementation found")
|
jpayne@68
|
81
|
jpayne@68
|
82 def _parse_feature_string(s):
|
jpayne@68
|
83 features = []
|
jpayne@68
|
84 parts = s.split()
|
jpayne@68
|
85 i = 0
|
jpayne@68
|
86 length = len(parts)
|
jpayne@68
|
87 while i < length:
|
jpayne@68
|
88 feature = parts[i]
|
jpayne@68
|
89 if feature[0] in "0123456789":
|
jpayne@68
|
90 raise ValueError("bad feature name: %r" % (feature,))
|
jpayne@68
|
91 i = i + 1
|
jpayne@68
|
92 version = None
|
jpayne@68
|
93 if i < length:
|
jpayne@68
|
94 v = parts[i]
|
jpayne@68
|
95 if v[0] in "0123456789":
|
jpayne@68
|
96 i = i + 1
|
jpayne@68
|
97 version = v
|
jpayne@68
|
98 features.append((feature, version))
|
jpayne@68
|
99 return tuple(features)
|