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