jpayne@68: """Registration facilities for DOM. This module should not be used jpayne@68: directly. Instead, the functions getDOMImplementation and jpayne@68: registerDOMImplementation should be imported from xml.dom.""" jpayne@68: jpayne@68: # This is a list of well-known implementations. Well-known names jpayne@68: # should be published by posting to xml-sig@python.org, and are jpayne@68: # subsequently recorded in this file. jpayne@68: jpayne@68: import sys jpayne@68: jpayne@68: well_known_implementations = { jpayne@68: 'minidom':'xml.dom.minidom', jpayne@68: '4DOM': 'xml.dom.DOMImplementation', jpayne@68: } jpayne@68: jpayne@68: # DOM implementations not officially registered should register jpayne@68: # themselves with their jpayne@68: jpayne@68: registered = {} jpayne@68: jpayne@68: def registerDOMImplementation(name, factory): jpayne@68: """registerDOMImplementation(name, factory) jpayne@68: jpayne@68: Register the factory function with the name. The factory function jpayne@68: should return an object which implements the DOMImplementation jpayne@68: interface. The factory function can either return the same object, jpayne@68: or a new one (e.g. if that implementation supports some jpayne@68: customization).""" jpayne@68: jpayne@68: registered[name] = factory jpayne@68: jpayne@68: def _good_enough(dom, features): jpayne@68: "_good_enough(dom, features) -> Return 1 if the dom offers the features" jpayne@68: for f,v in features: jpayne@68: if not dom.hasFeature(f,v): jpayne@68: return 0 jpayne@68: return 1 jpayne@68: jpayne@68: def getDOMImplementation(name=None, features=()): jpayne@68: """getDOMImplementation(name = None, features = ()) -> DOM implementation. jpayne@68: jpayne@68: Return a suitable DOM implementation. The name is either jpayne@68: well-known, the module name of a DOM implementation, or None. If jpayne@68: it is not None, imports the corresponding module and returns jpayne@68: DOMImplementation object if the import succeeds. jpayne@68: jpayne@68: If name is not given, consider the available implementations to jpayne@68: find one with the required feature set. If no implementation can jpayne@68: be found, raise an ImportError. The features list must be a sequence jpayne@68: of (feature, version) pairs which are passed to hasFeature.""" jpayne@68: jpayne@68: import os jpayne@68: creator = None jpayne@68: mod = well_known_implementations.get(name) jpayne@68: if mod: jpayne@68: mod = __import__(mod, {}, {}, ['getDOMImplementation']) jpayne@68: return mod.getDOMImplementation() jpayne@68: elif name: jpayne@68: return registered[name]() jpayne@68: elif not sys.flags.ignore_environment and "PYTHON_DOM" in os.environ: jpayne@68: return getDOMImplementation(name = os.environ["PYTHON_DOM"]) jpayne@68: jpayne@68: # User did not specify a name, try implementations in arbitrary jpayne@68: # order, returning the one that has the required features jpayne@68: if isinstance(features, str): jpayne@68: features = _parse_feature_string(features) jpayne@68: for creator in registered.values(): jpayne@68: dom = creator() jpayne@68: if _good_enough(dom, features): jpayne@68: return dom jpayne@68: jpayne@68: for creator in well_known_implementations.keys(): jpayne@68: try: jpayne@68: dom = getDOMImplementation(name = creator) jpayne@68: except Exception: # typically ImportError, or AttributeError jpayne@68: continue jpayne@68: if _good_enough(dom, features): jpayne@68: return dom jpayne@68: jpayne@68: raise ImportError("no suitable DOM implementation found") jpayne@68: jpayne@68: def _parse_feature_string(s): jpayne@68: features = [] jpayne@68: parts = s.split() jpayne@68: i = 0 jpayne@68: length = len(parts) jpayne@68: while i < length: jpayne@68: feature = parts[i] jpayne@68: if feature[0] in "0123456789": jpayne@68: raise ValueError("bad feature name: %r" % (feature,)) jpayne@68: i = i + 1 jpayne@68: version = None jpayne@68: if i < length: jpayne@68: v = parts[i] jpayne@68: if v[0] in "0123456789": jpayne@68: i = i + 1 jpayne@68: version = v jpayne@68: features.append((feature, version)) jpayne@68: return tuple(features)