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