17db96d56Sopenharmony_ci"""Registration facilities for DOM. This module should not be used 27db96d56Sopenharmony_cidirectly. Instead, the functions getDOMImplementation and 37db96d56Sopenharmony_ciregisterDOMImplementation should be imported from xml.dom.""" 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci# This is a list of well-known implementations. Well-known names 67db96d56Sopenharmony_ci# should be published by posting to xml-sig@python.org, and are 77db96d56Sopenharmony_ci# subsequently recorded in this file. 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ciimport sys 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ciwell_known_implementations = { 127db96d56Sopenharmony_ci 'minidom':'xml.dom.minidom', 137db96d56Sopenharmony_ci '4DOM': 'xml.dom.DOMImplementation', 147db96d56Sopenharmony_ci } 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci# DOM implementations not officially registered should register 177db96d56Sopenharmony_ci# themselves with their 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ciregistered = {} 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_cidef registerDOMImplementation(name, factory): 227db96d56Sopenharmony_ci """registerDOMImplementation(name, factory) 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci Register the factory function with the name. The factory function 257db96d56Sopenharmony_ci should return an object which implements the DOMImplementation 267db96d56Sopenharmony_ci interface. The factory function can either return the same object, 277db96d56Sopenharmony_ci or a new one (e.g. if that implementation supports some 287db96d56Sopenharmony_ci customization).""" 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci registered[name] = factory 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_cidef _good_enough(dom, features): 337db96d56Sopenharmony_ci "_good_enough(dom, features) -> Return 1 if the dom offers the features" 347db96d56Sopenharmony_ci for f,v in features: 357db96d56Sopenharmony_ci if not dom.hasFeature(f,v): 367db96d56Sopenharmony_ci return 0 377db96d56Sopenharmony_ci return 1 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_cidef getDOMImplementation(name=None, features=()): 407db96d56Sopenharmony_ci """getDOMImplementation(name = None, features = ()) -> DOM implementation. 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci Return a suitable DOM implementation. The name is either 437db96d56Sopenharmony_ci well-known, the module name of a DOM implementation, or None. If 447db96d56Sopenharmony_ci it is not None, imports the corresponding module and returns 457db96d56Sopenharmony_ci DOMImplementation object if the import succeeds. 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci If name is not given, consider the available implementations to 487db96d56Sopenharmony_ci find one with the required feature set. If no implementation can 497db96d56Sopenharmony_ci be found, raise an ImportError. The features list must be a sequence 507db96d56Sopenharmony_ci of (feature, version) pairs which are passed to hasFeature.""" 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci import os 537db96d56Sopenharmony_ci creator = None 547db96d56Sopenharmony_ci mod = well_known_implementations.get(name) 557db96d56Sopenharmony_ci if mod: 567db96d56Sopenharmony_ci mod = __import__(mod, {}, {}, ['getDOMImplementation']) 577db96d56Sopenharmony_ci return mod.getDOMImplementation() 587db96d56Sopenharmony_ci elif name: 597db96d56Sopenharmony_ci return registered[name]() 607db96d56Sopenharmony_ci elif not sys.flags.ignore_environment and "PYTHON_DOM" in os.environ: 617db96d56Sopenharmony_ci return getDOMImplementation(name = os.environ["PYTHON_DOM"]) 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci # User did not specify a name, try implementations in arbitrary 647db96d56Sopenharmony_ci # order, returning the one that has the required features 657db96d56Sopenharmony_ci if isinstance(features, str): 667db96d56Sopenharmony_ci features = _parse_feature_string(features) 677db96d56Sopenharmony_ci for creator in registered.values(): 687db96d56Sopenharmony_ci dom = creator() 697db96d56Sopenharmony_ci if _good_enough(dom, features): 707db96d56Sopenharmony_ci return dom 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci for creator in well_known_implementations.keys(): 737db96d56Sopenharmony_ci try: 747db96d56Sopenharmony_ci dom = getDOMImplementation(name = creator) 757db96d56Sopenharmony_ci except Exception: # typically ImportError, or AttributeError 767db96d56Sopenharmony_ci continue 777db96d56Sopenharmony_ci if _good_enough(dom, features): 787db96d56Sopenharmony_ci return dom 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci raise ImportError("no suitable DOM implementation found") 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_cidef _parse_feature_string(s): 837db96d56Sopenharmony_ci features = [] 847db96d56Sopenharmony_ci parts = s.split() 857db96d56Sopenharmony_ci i = 0 867db96d56Sopenharmony_ci length = len(parts) 877db96d56Sopenharmony_ci while i < length: 887db96d56Sopenharmony_ci feature = parts[i] 897db96d56Sopenharmony_ci if feature[0] in "0123456789": 907db96d56Sopenharmony_ci raise ValueError("bad feature name: %r" % (feature,)) 917db96d56Sopenharmony_ci i = i + 1 927db96d56Sopenharmony_ci version = None 937db96d56Sopenharmony_ci if i < length: 947db96d56Sopenharmony_ci v = parts[i] 957db96d56Sopenharmony_ci if v[0] in "0123456789": 967db96d56Sopenharmony_ci i = i + 1 977db96d56Sopenharmony_ci version = v 987db96d56Sopenharmony_ci features.append((feature, version)) 997db96d56Sopenharmony_ci return tuple(features) 100