• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/opal/ZSI/ZSI/wstools/XMLSchema.py

00001 # Copyright (c) 2003, The Regents of the University of California,
00002 # through Lawrence Berkeley National Laboratory (subject to receipt of
00003 # any required approvals from the U.S. Dept. of Energy).  All rights
00004 # reserved. 
00005 #
00006 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00007 #
00008 # This software is subject to the provisions of the Zope Public License,
00009 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
00010 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00011 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00012 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00013 # FOR A PARTICULAR PURPOSE.
00014 
00015 ident = "$Id: XMLSchema.py 1434 2007-11-01 22:42:47Z boverhof $"
00016 
00017 import types, weakref, sys, warnings
00018 from Namespaces import SCHEMA, XMLNS, SOAP
00019 from Utility import DOM, DOMException, Collection, SplitQName, basejoin
00020 from StringIO import StringIO
00021 
00022 # If we have no threading, this should be a no-op
00023 try:
00024     from threading import RLock
00025 except ImportError:
00026     class RLock:
00027         def acquire():
00028             pass
00029         def release():
00030             pass
00031 
00032 # 
00033 # Collections in XMLSchema class
00034 # 
00035 TYPES = 'types'
00036 ATTRIBUTE_GROUPS = 'attr_groups'
00037 ATTRIBUTES = 'attr_decl'
00038 ELEMENTS = 'elements'
00039 MODEL_GROUPS = 'model_groups'
00040 BUILT_IN_NAMESPACES = [SOAP.ENC,] + SCHEMA.XSD_LIST
00041 
00042 def GetSchema(component):
00043     """convience function for finding the parent XMLSchema instance.
00044     """
00045     parent = component
00046     while not isinstance(parent, XMLSchema):
00047         parent = parent._parent()
00048     return parent
00049     
00050 class SchemaReader:
00051     """A SchemaReader creates XMLSchema objects from urls and xml data.
00052     """
00053     
00054     namespaceToSchema = {}
00055     
00056     def __init__(self, domReader=None, base_url=None):
00057         """domReader -- class must implement DOMAdapterInterface
00058            base_url -- base url string
00059         """
00060         self.__base_url = base_url
00061         self.__readerClass = domReader
00062         if not self.__readerClass:
00063             self.__readerClass = DOMAdapter
00064         self._includes = {}
00065         self._imports = {}
00066 
00067     def __setImports(self, schema):
00068         """Add dictionary of imports to schema instance.
00069            schema -- XMLSchema instance
00070         """
00071         for ns,val in schema.imports.items(): 
00072             if self._imports.has_key(ns):
00073                 schema.addImportSchema(self._imports[ns])
00074 
00075     def __setIncludes(self, schema):
00076         """Add dictionary of includes to schema instance.
00077            schema -- XMLSchema instance
00078         """
00079         for schemaLocation, val in schema.includes.items(): 
00080             if self._includes.has_key(schemaLocation):
00081                 schema.addIncludeSchema(schemaLocation, self._imports[schemaLocation])
00082 
00083     def addSchemaByLocation(self, location, schema):
00084         """provide reader with schema document for a location.
00085         """
00086         self._includes[location] = schema
00087 
00088     def addSchemaByNamespace(self, schema):
00089         """provide reader with schema document for a targetNamespace.
00090         """
00091         self._imports[schema.targetNamespace] = schema
00092 
00093     def loadFromNode(self, parent, element):
00094         """element -- DOM node or document
00095            parent -- WSDLAdapter instance
00096         """
00097         reader = self.__readerClass(element)
00098         schema = XMLSchema(parent)
00099         #HACK to keep a reference
00100         schema.wsdl = parent
00101         schema.setBaseUrl(self.__base_url)
00102         schema.load(reader)
00103         return schema
00104         
00105     def loadFromStream(self, file, url=None):
00106         """Return an XMLSchema instance loaded from a file object.
00107            file -- file object
00108            url -- base location for resolving imports/includes.
00109         """
00110         reader = self.__readerClass()
00111         reader.loadDocument(file)
00112         schema = XMLSchema()
00113         if url is not None:
00114              schema.setBaseUrl(url)
00115         schema.load(reader)
00116         self.__setIncludes(schema)
00117         self.__setImports(schema)
00118         return schema
00119 
00120     def loadFromString(self, data):
00121         """Return an XMLSchema instance loaded from an XML string.
00122            data -- XML string
00123         """
00124         return self.loadFromStream(StringIO(data))
00125 
00126     def loadFromURL(self, url, schema=None):
00127         """Return an XMLSchema instance loaded from the given url.
00128            url -- URL to dereference
00129            schema -- Optional XMLSchema instance.
00130         """
00131         reader = self.__readerClass()
00132         if self.__base_url:
00133             url = basejoin(self.__base_url,url)
00134 
00135         reader.loadFromURL(url)
00136         schema = schema or XMLSchema()
00137         schema.setBaseUrl(url)
00138         schema.load(reader)
00139         self.__setIncludes(schema)
00140         self.__setImports(schema)
00141         return schema
00142 
00143     def loadFromFile(self, filename):
00144         """Return an XMLSchema instance loaded from the given file.
00145            filename -- name of file to open
00146         """
00147         if self.__base_url:
00148             filename = basejoin(self.__base_url,filename)
00149         file = open(filename, 'rb')
00150         try:
00151             schema = self.loadFromStream(file, filename)
00152         finally:
00153             file.close()
00154 
00155         return schema
00156 
00157 
00158 class SchemaError(Exception): 
00159     pass
00160 
00161 class NoSchemaLocationWarning(Exception): 
00162     pass
00163 
00164 
00165 ###########################
00166 # DOM Utility Adapters 
00167 ##########################
00168 class DOMAdapterInterface:
00169     def hasattr(self, attr, ns=None):
00170         """return true if node has attribute 
00171            attr -- attribute to check for
00172            ns -- namespace of attribute, by default None
00173         """
00174         raise NotImplementedError, 'adapter method not implemented'
00175 
00176     def getContentList(self, *contents):
00177         """returns an ordered list of child nodes
00178            *contents -- list of node names to return
00179         """
00180         raise NotImplementedError, 'adapter method not implemented'
00181 
00182     def setAttributeDictionary(self, attributes):
00183         """set attribute dictionary
00184         """
00185         raise NotImplementedError, 'adapter method not implemented'
00186 
00187     def getAttributeDictionary(self):
00188         """returns a dict of node's attributes
00189         """
00190         raise NotImplementedError, 'adapter method not implemented'
00191 
00192     def getNamespace(self, prefix):
00193         """returns namespace referenced by prefix.
00194         """
00195         raise NotImplementedError, 'adapter method not implemented'
00196 
00197     def getTagName(self):
00198         """returns tagName of node
00199         """
00200         raise NotImplementedError, 'adapter method not implemented'
00201 
00202 
00203     def getParentNode(self):
00204         """returns parent element in DOMAdapter or None
00205         """
00206         raise NotImplementedError, 'adapter method not implemented'
00207 
00208     def loadDocument(self, file):
00209         """load a Document from a file object
00210            file --
00211         """
00212         raise NotImplementedError, 'adapter method not implemented'
00213 
00214     def loadFromURL(self, url):
00215         """load a Document from an url
00216            url -- URL to dereference
00217         """
00218         raise NotImplementedError, 'adapter method not implemented'
00219 
00220 
00221 class DOMAdapter(DOMAdapterInterface):
00222     """Adapter for ZSI.Utility.DOM
00223     """
00224     def __init__(self, node=None):
00225         """Reset all instance variables.
00226            element -- DOM document, node, or None
00227         """
00228         if hasattr(node, 'documentElement'):
00229             self.__node = node.documentElement
00230         else:
00231             self.__node = node
00232         self.__attributes = None
00233 
00234     def getNode(self):
00235         return self.__node
00236     
00237     def hasattr(self, attr, ns=None):
00238         """attr -- attribute 
00239            ns -- optional namespace, None means unprefixed attribute.
00240         """
00241         if not self.__attributes:
00242             self.setAttributeDictionary()
00243         if ns:
00244             return self.__attributes.get(ns,{}).has_key(attr)
00245         return self.__attributes.has_key(attr)
00246 
00247     def getContentList(self, *contents):
00248         nodes = []
00249         ELEMENT_NODE = self.__node.ELEMENT_NODE
00250         for child in DOM.getElements(self.__node, None):
00251             if child.nodeType == ELEMENT_NODE and\
00252                SplitQName(child.tagName)[1] in contents:
00253                 nodes.append(child)
00254         return map(self.__class__, nodes)
00255 
00256     def setAttributeDictionary(self):
00257         self.__attributes = {}
00258         for v in self.__node._attrs.values():
00259             self.__attributes[v.nodeName] = v.nodeValue
00260 
00261     def getAttributeDictionary(self):
00262         if not self.__attributes:
00263             self.setAttributeDictionary()
00264         return self.__attributes
00265 
00266     def getTagName(self):
00267         return self.__node.tagName
00268 
00269     def getParentNode(self):
00270         if self.__node.parentNode.nodeType == self.__node.ELEMENT_NODE:
00271             return DOMAdapter(self.__node.parentNode)
00272         return None
00273 
00274     def getNamespace(self, prefix):
00275         """prefix -- deference namespace prefix in node's context.
00276            Ascends parent nodes until found.
00277         """
00278         namespace = None
00279         if prefix == 'xmlns':
00280             namespace = DOM.findDefaultNS(prefix, self.__node)
00281         else:
00282             try:
00283                 namespace = DOM.findNamespaceURI(prefix, self.__node)
00284             except DOMException, ex:
00285                 if prefix != 'xml':
00286                     raise SchemaError, '%s namespace not declared for %s'\
00287                         %(prefix, self.__node._get_tagName())
00288                 namespace = XMLNS.XML
00289         return namespace
00290            
00291     def loadDocument(self, file):
00292         self.__node = DOM.loadDocument(file)
00293         if hasattr(self.__node, 'documentElement'):
00294             self.__node = self.__node.documentElement
00295 
00296     def loadFromURL(self, url):
00297         self.__node = DOM.loadFromURL(url)
00298         if hasattr(self.__node, 'documentElement'):
00299             self.__node = self.__node.documentElement
00300 
00301  
00302 class XMLBase: 
00303     """ These class variables are for string indentation.
00304     """ 
00305     tag = None
00306     __indent = 0
00307     __rlock = RLock()
00308 
00309     def __str__(self):
00310         XMLBase.__rlock.acquire()
00311         XMLBase.__indent += 1
00312         tmp = "<" + str(self.__class__) + '>\n'
00313         for k,v in self.__dict__.items():
00314             tmp += "%s* %s = %s\n" %(XMLBase.__indent*'  ', k, v)
00315         XMLBase.__indent -= 1 
00316         XMLBase.__rlock.release()
00317         return tmp
00318 
00319 
00320 """Marker Interface:  can determine something about an instances properties by using 
00321         the provided convenience functions.
00322 
00323 """
00324 class DefinitionMarker: 
00325     """marker for definitions
00326     """
00327     pass
00328 
00329 class DeclarationMarker: 
00330     """marker for declarations
00331     """
00332     pass
00333 
00334 class AttributeMarker: 
00335     """marker for attributes
00336     """
00337     pass
00338 
00339 class AttributeGroupMarker: 
00340     """marker for attribute groups
00341     """
00342     pass
00343 
00344 class WildCardMarker: 
00345     """marker for wildcards
00346     """
00347     pass
00348 
00349 class ElementMarker: 
00350     """marker for wildcards
00351     """
00352     pass
00353 
00354 class ReferenceMarker: 
00355     """marker for references
00356     """
00357     pass
00358 
00359 class ModelGroupMarker: 
00360     """marker for model groups
00361     """
00362     pass
00363 
00364 class AllMarker(ModelGroupMarker): 
00365     """marker for all model group
00366     """
00367     pass
00368 
00369 class ChoiceMarker(ModelGroupMarker): 
00370     """marker for choice model group
00371     """
00372     pass
00373 
00374 class SequenceMarker(ModelGroupMarker): 
00375     """marker for sequence model group
00376     """
00377     pass
00378 
00379 class ExtensionMarker: 
00380     """marker for extensions
00381     """
00382     pass
00383 
00384 class RestrictionMarker: 
00385     """marker for restrictions
00386     """
00387     facets = ['enumeration', 'length', 'maxExclusive', 'maxInclusive',\
00388         'maxLength', 'minExclusive', 'minInclusive', 'minLength',\
00389         'pattern', 'fractionDigits', 'totalDigits', 'whiteSpace']
00390 
00391 class SimpleMarker: 
00392     """marker for simple type information
00393     """
00394     pass
00395 
00396 class ListMarker: 
00397     """marker for simple type list
00398     """
00399     pass
00400 
00401 class UnionMarker: 
00402     """marker for simple type Union
00403     """
00404     pass
00405 
00406 
00407 class ComplexMarker: 
00408     """marker for complex type information
00409     """
00410     pass
00411 
00412 class LocalMarker: 
00413     """marker for complex type information
00414     """
00415     pass
00416 
00417 
00418 class MarkerInterface:
00419     def isDefinition(self):
00420         return isinstance(self, DefinitionMarker)
00421 
00422     def isDeclaration(self):
00423         return isinstance(self, DeclarationMarker)
00424 
00425     def isAttribute(self):
00426         return isinstance(self, AttributeMarker)
00427 
00428     def isAttributeGroup(self):
00429         return isinstance(self, AttributeGroupMarker)
00430 
00431     def isElement(self):
00432         return isinstance(self, ElementMarker)
00433 
00434     def isReference(self):
00435         return isinstance(self, ReferenceMarker)
00436 
00437     def isWildCard(self):
00438         return isinstance(self, WildCardMarker)
00439 
00440     def isModelGroup(self):
00441         return isinstance(self, ModelGroupMarker)
00442 
00443     def isAll(self):
00444         return isinstance(self, AllMarker)
00445 
00446     def isChoice(self):
00447         return isinstance(self, ChoiceMarker)
00448 
00449     def isSequence(self):
00450         return isinstance(self, SequenceMarker)
00451 
00452     def isExtension(self):
00453         return isinstance(self, ExtensionMarker)
00454 
00455     def isRestriction(self):
00456         return isinstance(self, RestrictionMarker)
00457 
00458     def isSimple(self):
00459         return isinstance(self, SimpleMarker)
00460 
00461     def isComplex(self):
00462         return isinstance(self, ComplexMarker)
00463 
00464     def isLocal(self):
00465         return isinstance(self, LocalMarker)
00466 
00467     def isList(self):
00468         return isinstance(self, ListMarker)
00469 
00470     def isUnion(self):
00471         return isinstance(self, UnionMarker)
00472 
00473 
00474 ##########################################################
00475 # Schema Components
00476 #########################################################
00477 class XMLSchemaComponent(XMLBase, MarkerInterface):
00478     """
00479        class variables: 
00480            required -- list of required attributes
00481            attributes -- dict of default attribute values, including None.
00482                Value can be a function for runtime dependencies.
00483            contents -- dict of namespace keyed content lists.
00484                'xsd' content of xsd namespace.
00485            xmlns_key -- key for declared xmlns namespace.
00486            xmlns -- xmlns is special prefix for namespace dictionary
00487            xml -- special xml prefix for xml namespace.
00488     """
00489     required = []
00490     attributes = {}
00491     contents = {}
00492     xmlns_key = ''
00493     xmlns = 'xmlns'
00494     xml = 'xml'
00495 
00496     def __init__(self, parent=None):
00497         """parent -- parent instance
00498            instance variables:
00499                attributes -- dictionary of node's attributes
00500         """
00501         self.attributes = None
00502         self._parent = parent
00503         if self._parent:
00504             self._parent = weakref.ref(parent)
00505 
00506         if not self.__class__ == XMLSchemaComponent\
00507            and not (type(self.__class__.required) == type(XMLSchemaComponent.required)\
00508            and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)\
00509            and type(self.__class__.contents) == type(XMLSchemaComponent.contents)):
00510             raise RuntimeError, 'Bad type for a class variable in %s' %self.__class__
00511 
00512     def getItemTrace(self):
00513         """Returns a node trace up to the <schema> item.
00514         """
00515         item, path, name, ref = self, [], 'name', 'ref'
00516         while not isinstance(item,XMLSchema) and not isinstance(item,WSDLToolsAdapter):
00517             attr = item.getAttribute(name)
00518             if not attr:
00519                 attr = item.getAttribute(ref)
00520                 if not attr:
00521                     path.append('<%s>' %(item.tag))
00522                 else: 
00523                     path.append('<%s ref="%s">' %(item.tag, attr))
00524             else:
00525                 path.append('<%s name="%s">' %(item.tag,attr))
00526 
00527             item = item._parent()
00528         try:
00529             tns = item.getTargetNamespace()
00530         except: 
00531             tns = ''
00532         path.append('<%s targetNamespace="%s">' %(item.tag, tns))
00533         path.reverse()
00534         return ''.join(path)
00535 
00536     def getTargetNamespace(self):
00537         """return targetNamespace
00538         """
00539         parent = self
00540         targetNamespace = 'targetNamespace'
00541         tns = self.attributes.get(targetNamespace)
00542         while not tns and parent and parent._parent is not None:
00543             parent = parent._parent()
00544             tns = parent.attributes.get(targetNamespace)
00545         return tns or ''
00546 
00547     def getAttributeDeclaration(self, attribute):
00548         """attribute -- attribute with a QName value (eg. type).
00549            collection -- check types collection in parent Schema instance
00550         """
00551         return self.getQNameAttribute(ATTRIBUTES, attribute)
00552 
00553     def getAttributeGroup(self, attribute):
00554         """attribute -- attribute with a QName value (eg. type).
00555            collection -- check types collection in parent Schema instance
00556         """
00557         return self.getQNameAttribute(ATTRIBUTE_GROUPS, attribute)
00558 
00559     def getTypeDefinition(self, attribute):
00560         """attribute -- attribute with a QName value (eg. type).
00561            collection -- check types collection in parent Schema instance
00562         """
00563         return self.getQNameAttribute(TYPES, attribute)
00564 
00565     def getElementDeclaration(self, attribute):
00566         """attribute -- attribute with a QName value (eg. element).
00567            collection -- check elements collection in parent Schema instance.
00568         """
00569         return self.getQNameAttribute(ELEMENTS, attribute)
00570 
00571     def getModelGroup(self, attribute):
00572         """attribute -- attribute with a QName value (eg. ref).
00573            collection -- check model_group collection in parent Schema instance.
00574         """
00575         return self.getQNameAttribute(MODEL_GROUPS, attribute)
00576 
00577     def getQNameAttribute(self, collection, attribute):
00578         """returns object instance representing QName --> (namespace,name),
00579            or if does not exist return None.
00580            attribute -- an information item attribute, with a QName value.
00581            collection -- collection in parent Schema instance to search.
00582         """
00583         tdc = self.getAttributeQName(attribute)
00584         if not tdc:
00585             return
00586 
00587         obj = self.getSchemaItem(collection, tdc.getTargetNamespace(), tdc.getName())
00588         if obj: 
00589             return obj
00590 
00591 #        raise SchemaError, 'No schema item "%s" in collection %s' %(tdc, collection)
00592         return
00593 
00594     def getSchemaItem(self, collection, namespace, name):
00595         """returns object instance representing namespace, name,
00596            or if does not exist return None if built-in, else
00597            raise SchemaError.
00598            
00599            namespace -- namespace item defined in.
00600            name -- name of item.
00601            collection -- collection in parent Schema instance to search.
00602         """
00603         parent = GetSchema(self)
00604         if parent.targetNamespace == namespace:
00605             try:
00606                 obj = getattr(parent, collection)[name]
00607             except KeyError, ex:
00608                 raise KeyError, 'targetNamespace(%s) collection(%s) has no item(%s)'\
00609                     %(namespace, collection, name)
00610                     
00611             return obj
00612         
00613         if not parent.imports.has_key(namespace):
00614             if namespace in BUILT_IN_NAMESPACES:            
00615                 # built-in just return
00616                 # WARNING: expecting import if "redefine" or add to built-in namespace.
00617                 return
00618             
00619             raise SchemaError, 'schema "%s" does not import namespace "%s"' %(
00620                 parent.targetNamespace, namespace)
00621             
00622         # Lazy Eval
00623         schema = parent.imports[namespace]
00624         if not isinstance(schema, XMLSchema):
00625             schema = schema.getSchema()    
00626             if schema is not None:
00627                 parent.imports[namespace] = schema
00628             
00629         if schema is None:
00630             if namespace in BUILT_IN_NAMESPACES:
00631                 # built-in just return
00632                 return
00633             
00634             raise SchemaError, 'no schema instance for imported namespace (%s).'\
00635                 %(namespace)
00636                 
00637         if not isinstance(schema, XMLSchema):
00638             raise TypeError, 'expecting XMLSchema instance not "%r"' %schema
00639                 
00640         try:
00641             obj = getattr(schema, collection)[name]
00642         except KeyError, ex:
00643             raise KeyError, 'targetNamespace(%s) collection(%s) has no item(%s)'\
00644                 %(namespace, collection, name)
00645                     
00646         return obj
00647 
00648     def getXMLNS(self, prefix=None):
00649         """deference prefix or by default xmlns, returns namespace. 
00650         """
00651         if prefix == XMLSchemaComponent.xml:
00652             return XMLNS.XML
00653         parent = self
00654         ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix or\
00655                 XMLSchemaComponent.xmlns_key)
00656         while not ns:
00657             parent = parent._parent()
00658             ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or\
00659                     XMLSchemaComponent.xmlns_key)
00660             if not ns and isinstance(parent, WSDLToolsAdapter):
00661                 if prefix is None:
00662                     return ''
00663                 raise SchemaError, 'unknown prefix %s' %prefix
00664         return ns
00665 
00666     def getAttribute(self, attribute):
00667         """return requested attribute value or None
00668         """
00669         if type(attribute) in (list, tuple):
00670             if len(attribute) != 2:
00671                 raise LookupError, 'To access attributes must use name or (namespace,name)'
00672 
00673             ns_dict = self.attributes.get(attribute[0])
00674             if ns_dict is None:
00675                 return None
00676 
00677             return ns_dict.get(attribute[1])
00678 
00679         return self.attributes.get(attribute)
00680 
00681     def getAttributeQName(self, attribute):
00682         """return requested attribute value as (namespace,name) or None 
00683         """
00684         qname = self.getAttribute(attribute)
00685         if isinstance(qname, TypeDescriptionComponent) is True:
00686             return qname
00687         if qname is None:
00688             return None
00689 
00690         prefix,ncname = SplitQName(qname)
00691         namespace = self.getXMLNS(prefix)
00692         return TypeDescriptionComponent((namespace,ncname))
00693 
00694     def getAttributeName(self):
00695         """return attribute name or None
00696         """
00697         return self.getAttribute('name')
00698  
00699     def setAttributes(self, node):
00700         """Sets up attribute dictionary, checks for required attributes and 
00701            sets default attribute values. attr is for default attribute values 
00702            determined at runtime.
00703            
00704            structure of attributes dictionary
00705                ['xmlns'][xmlns_key] --  xmlns namespace
00706                ['xmlns'][prefix] --  declared namespace prefix 
00707                [namespace][prefix] -- attributes declared in a namespace
00708                [attribute] -- attributes w/o prefix, default namespaces do
00709                    not directly apply to attributes, ie Name can't collide 
00710                    with QName.
00711         """
00712         self.attributes = {XMLSchemaComponent.xmlns:{}}
00713         for k,v in node.getAttributeDictionary().items():
00714             prefix,value = SplitQName(k)
00715             if value == XMLSchemaComponent.xmlns:
00716                 self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v
00717             elif prefix:
00718                 ns = node.getNamespace(prefix)
00719                 if not ns: 
00720                     raise SchemaError, 'no namespace for attribute prefix %s'\
00721                         %prefix
00722                 if not self.attributes.has_key(ns):
00723                     self.attributes[ns] = {}
00724                 elif self.attributes[ns].has_key(value):
00725                     raise SchemaError, 'attribute %s declared multiple times in %s'\
00726                         %(value, ns)
00727                 self.attributes[ns][value] = v
00728             elif not self.attributes.has_key(value):
00729                 self.attributes[value] = v
00730             else:
00731                 raise SchemaError, 'attribute %s declared multiple times' %value
00732 
00733         if not isinstance(self, WSDLToolsAdapter):
00734             self.__checkAttributes()
00735         self.__setAttributeDefaults()
00736 
00737         #set QNames
00738         for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']:
00739             if self.attributes.has_key(k):
00740                 prefix, value = SplitQName(self.attributes.get(k))
00741                 self.attributes[k] = \
00742                     TypeDescriptionComponent((self.getXMLNS(prefix), value))
00743 
00744         #Union, memberTypes is a whitespace separated list of QNames 
00745         for k in ['memberTypes']:
00746             if self.attributes.has_key(k):
00747                 qnames = self.attributes[k]
00748                 self.attributes[k] = []
00749                 for qname in qnames.split():
00750                     prefix, value = SplitQName(qname)
00751                     self.attributes['memberTypes'].append(\
00752                         TypeDescriptionComponent(\
00753                             (self.getXMLNS(prefix), value)))
00754 
00755     def getContents(self, node):
00756         """retrieve xsd contents
00757         """
00758         return node.getContentList(*self.__class__.contents['xsd'])
00759 
00760     def __setAttributeDefaults(self):
00761         """Looks for default values for unset attributes.  If
00762            class variable representing attribute is None, then
00763            it must be defined as an instance variable.
00764         """
00765         for k,v in self.__class__.attributes.items():
00766             if v is not None and self.attributes.has_key(k) is False:
00767                 if isinstance(v, types.FunctionType):
00768                     self.attributes[k] = v(self)
00769                 else:
00770                     self.attributes[k] = v
00771 
00772     def __checkAttributes(self):
00773         """Checks that required attributes have been defined,
00774            attributes w/default cannot be required.   Checks
00775            all defined attributes are legal, attribute 
00776            references are not subject to this test.
00777         """
00778         for a in self.__class__.required:
00779             if not self.attributes.has_key(a):
00780                 raise SchemaError,\
00781                     'class instance %s, missing required attribute %s'\
00782                     %(self.__class__, a)
00783         for a,v in self.attributes.items():
00784             # attribute #other, ie. not in empty namespace
00785             if type(v) is dict:
00786                 continue
00787             
00788             # predefined prefixes xmlns, xml
00789             if a in (XMLSchemaComponent.xmlns, XMLNS.XML):
00790                 continue
00791             
00792             if (a not in self.__class__.attributes.keys()) and not\
00793                 (self.isAttribute() and self.isReference()):
00794                 raise SchemaError, '%s, unknown attribute(%s,%s)' \
00795                     %(self.getItemTrace(), a, self.attributes[a])
00796 
00797 
00798 class WSDLToolsAdapter(XMLSchemaComponent):
00799     """WSDL Adapter to grab the attributes from the wsdl document node.
00800     """
00801     attributes = {'name':None, 'targetNamespace':None}
00802     tag = 'definitions'
00803 
00804     def __init__(self, wsdl):
00805         XMLSchemaComponent.__init__(self, parent=wsdl)
00806         self.setAttributes(DOMAdapter(wsdl.document))
00807 
00808     def getImportSchemas(self):
00809         """returns WSDLTools.WSDL types Collection
00810         """
00811         return self._parent().types
00812 
00813 
00814 class Notation(XMLSchemaComponent):
00815     """<notation>
00816        parent:
00817            schema
00818        attributes:
00819            id -- ID
00820            name -- NCName, Required
00821            public -- token, Required
00822            system -- anyURI
00823        contents:
00824            annotation?
00825     """
00826     required = ['name', 'public']
00827     attributes = {'id':None, 'name':None, 'public':None, 'system':None}
00828     contents = {'xsd':('annotation')}
00829     tag = 'notation'
00830 
00831     def __init__(self, parent):
00832         XMLSchemaComponent.__init__(self, parent)
00833         self.annotation = None
00834 
00835     def fromDom(self, node):
00836         self.setAttributes(node)
00837         contents = self.getContents(node)
00838 
00839         for i in contents:
00840             component = SplitQName(i.getTagName())[1]
00841             if component == 'annotation' and not self.annotation:
00842                 self.annotation = Annotation(self)
00843                 self.annotation.fromDom(i)
00844             else:
00845                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
00846 
00847 
00848 class Annotation(XMLSchemaComponent):
00849     """<annotation>
00850        parent:
00851            all,any,anyAttribute,attribute,attributeGroup,choice,complexContent,
00852            complexType,element,extension,field,group,import,include,key,keyref,
00853            list,notation,redefine,restriction,schema,selector,simpleContent,
00854            simpleType,union,unique
00855        attributes:
00856            id -- ID
00857        contents:
00858            (documentation | appinfo)*
00859     """
00860     attributes = {'id':None}
00861     contents = {'xsd':('documentation', 'appinfo')}
00862     tag = 'annotation'
00863 
00864     def __init__(self, parent):
00865         XMLSchemaComponent.__init__(self, parent)
00866         self.content = None
00867 
00868     def fromDom(self, node):
00869         self.setAttributes(node)
00870         contents = self.getContents(node)
00871         content = []
00872 
00873         for i in contents:
00874             component = SplitQName(i.getTagName())[1]
00875             if component == 'documentation':
00876                 #print_debug('class %s, documentation skipped' %self.__class__, 5)
00877                 continue
00878             elif component == 'appinfo':
00879                 #print_debug('class %s, appinfo skipped' %self.__class__, 5)
00880                 continue
00881             else:
00882                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
00883         self.content = tuple(content)
00884 
00885 
00886     class Documentation(XMLSchemaComponent):
00887         """<documentation>
00888            parent:
00889                annotation
00890            attributes:
00891                source, anyURI
00892                xml:lang, language
00893            contents:
00894                mixed, any
00895         """
00896         attributes = {'source':None, 'xml:lang':None}
00897         contents = {'xsd':('mixed', 'any')}
00898         tag = 'documentation'
00899 
00900         def __init__(self, parent):
00901             XMLSchemaComponent.__init__(self, parent)
00902             self.content = None
00903 
00904         def fromDom(self, node):
00905             self.setAttributes(node)
00906             contents = self.getContents(node)
00907             content = []
00908 
00909             for i in contents:
00910                 component = SplitQName(i.getTagName())[1]
00911                 if component == 'mixed':
00912                     #print_debug('class %s, mixed skipped' %self.__class__, 5)
00913                     continue
00914                 elif component == 'any':
00915                     #print_debug('class %s, any skipped' %self.__class__, 5)
00916                     continue
00917                 else:
00918                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
00919             self.content = tuple(content)
00920 
00921 
00922     class Appinfo(XMLSchemaComponent):
00923         """<appinfo>
00924            parent:
00925                annotation
00926            attributes:
00927                source, anyURI
00928            contents:
00929                mixed, any
00930         """
00931         attributes = {'source':None, 'anyURI':None}
00932         contents = {'xsd':('mixed', 'any')}
00933         tag = 'appinfo'
00934 
00935         def __init__(self, parent):
00936             XMLSchemaComponent.__init__(self, parent)
00937             self.content = None
00938 
00939         def fromDom(self, node):
00940             self.setAttributes(node)
00941             contents = self.getContents(node)
00942             content = []
00943 
00944             for i in contents:
00945                 component = SplitQName(i.getTagName())[1]
00946                 if component == 'mixed':
00947                     #print_debug('class %s, mixed skipped' %self.__class__, 5)
00948                     continue
00949                 elif component == 'any':
00950                     #print_debug('class %s, any skipped' %self.__class__, 5)
00951                     continue
00952                 else:
00953                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
00954             self.content = tuple(content)
00955 
00956 
00957 class XMLSchemaFake:
00958     # This is temporary, for the benefit of WSDL until the real thing works.
00959     def __init__(self, element):
00960         self.targetNamespace = DOM.getAttr(element, 'targetNamespace')
00961         self.element = element
00962 
00963 class XMLSchema(XMLSchemaComponent):
00964     """A schema is a collection of schema components derived from one
00965        or more schema documents, that is, one or more <schema> element
00966        information items. It represents the abstract notion of a schema
00967        rather than a single schema document (or other representation).
00968 
00969        <schema>
00970        parent:
00971            ROOT
00972        attributes:
00973            id -- ID
00974            version -- token
00975            xml:lang -- language
00976            targetNamespace -- anyURI
00977            attributeFormDefault -- 'qualified' | 'unqualified', 'unqualified'
00978            elementFormDefault -- 'qualified' | 'unqualified', 'unqualified'
00979            blockDefault -- '#all' | list of 
00980                ('substitution | 'extension' | 'restriction')
00981            finalDefault -- '#all' | list of 
00982                ('extension' | 'restriction' | 'list' | 'union')
00983         
00984        contents:
00985            ((include | import | redefine | annotation)*, 
00986             (attribute, attributeGroup, complexType, element, group, 
00987              notation, simpleType)*, annotation*)*
00988 
00989 
00990         attributes -- schema attributes
00991         imports -- import statements
00992         includes -- include statements
00993         redefines -- 
00994         types    -- global simpleType, complexType definitions
00995         elements -- global element declarations
00996         attr_decl -- global attribute declarations
00997         attr_groups -- attribute Groups
00998         model_groups -- model Groups
00999         notations -- global notations
01000     """
01001     attributes = {'id':None, 
01002         'version':None, 
01003         'xml:lang':None, 
01004         'targetNamespace':None,
01005         'attributeFormDefault':'unqualified',
01006         'elementFormDefault':'unqualified',
01007         'blockDefault':None,
01008         'finalDefault':None}
01009     contents = {'xsd':('include', 'import', 'redefine', 'annotation',
01010                        'attribute', 'attributeGroup', 'complexType',
01011                        'element', 'group', 'notation', 'simpleType',
01012                        'annotation')}
01013     empty_namespace = ''
01014     tag = 'schema'
01015 
01016     def __init__(self, parent=None): 
01017         """parent -- 
01018            instance variables:
01019            targetNamespace -- schema's declared targetNamespace, or empty string.
01020            _imported_schemas -- namespace keyed dict of schema dependencies, if 
01021               a schema is provided instance will not resolve import statement.
01022            _included_schemas -- schemaLocation keyed dict of component schemas, 
01023               if schema is provided instance will not resolve include statement.
01024            _base_url -- needed for relative URLs support, only works with URLs
01025                relative to initial document.
01026            includes -- collection of include statements
01027            imports -- collection of import statements
01028            elements -- collection of global element declarations
01029            types -- collection of global type definitions
01030            attr_decl -- collection of global attribute declarations
01031            attr_groups -- collection of global attribute group definitions
01032            model_groups -- collection of model group definitions
01033            notations -- collection of notations
01034 
01035         """
01036         self.__node = None
01037         self.targetNamespace = None
01038         XMLSchemaComponent.__init__(self, parent)
01039         f = lambda k: k.attributes['name']
01040         ns = lambda k: k.attributes['namespace']
01041         sl = lambda k: k.attributes['schemaLocation']
01042         self.includes = Collection(self, key=sl)
01043         self.imports = Collection(self, key=ns)
01044         self.elements = Collection(self, key=f)
01045         self.types = Collection(self, key=f)
01046         self.attr_decl = Collection(self, key=f)
01047         self.attr_groups = Collection(self, key=f)
01048         self.model_groups = Collection(self, key=f)
01049         self.notations = Collection(self, key=f)
01050 
01051         self._imported_schemas = {}
01052         self._included_schemas = {}
01053         self._base_url = None
01054 
01055     def getNode(self):
01056         """
01057         Interacting with the underlying DOM tree.
01058         """
01059         return self.__node
01060     
01061     def addImportSchema(self, schema):
01062         """for resolving import statements in Schema instance
01063            schema -- schema instance
01064            _imported_schemas 
01065         """
01066         if not isinstance(schema, XMLSchema):
01067             raise TypeError, 'expecting a Schema instance'
01068         if schema.targetNamespace != self.targetNamespace:
01069             self._imported_schemas[schema.targetNamespace] = schema
01070         else:
01071             raise SchemaError, 'import schema bad targetNamespace'
01072 
01073     def addIncludeSchema(self, schemaLocation, schema):
01074         """for resolving include statements in Schema instance
01075            schemaLocation -- schema location
01076            schema -- schema instance
01077            _included_schemas 
01078         """
01079         if not isinstance(schema, XMLSchema):
01080             raise TypeError, 'expecting a Schema instance'
01081         if not schema.targetNamespace or\
01082              schema.targetNamespace == self.targetNamespace:
01083             self._included_schemas[schemaLocation] = schema
01084         else:
01085             raise SchemaError, 'include schema bad targetNamespace'
01086         
01087     def setImportSchemas(self, schema_dict):
01088         """set the import schema dictionary, which is used to 
01089            reference depedent schemas.
01090         """
01091         self._imported_schemas = schema_dict
01092 
01093     def getImportSchemas(self):
01094         """get the import schema dictionary, which is used to 
01095            reference depedent schemas.
01096         """
01097         return self._imported_schemas
01098 
01099     def getSchemaNamespacesToImport(self):
01100         """returns tuple of namespaces the schema instance has declared
01101            itself to be depedent upon.
01102         """
01103         return tuple(self.includes.keys())
01104 
01105     def setIncludeSchemas(self, schema_dict):
01106         """set the include schema dictionary, which is keyed with 
01107            schemaLocation (uri).  
01108            This is a means of providing 
01109            schemas to the current schema for content inclusion.
01110         """
01111         self._included_schemas = schema_dict
01112 
01113     def getIncludeSchemas(self):
01114         """get the include schema dictionary, which is keyed with 
01115            schemaLocation (uri). 
01116         """
01117         return self._included_schemas
01118 
01119     def getBaseUrl(self):
01120         """get base url, used for normalizing all relative uri's 
01121         """
01122         return self._base_url
01123 
01124     def setBaseUrl(self, url):
01125         """set base url, used for normalizing all relative uri's 
01126         """
01127         self._base_url = url
01128 
01129     def getElementFormDefault(self):
01130         """return elementFormDefault attribute
01131         """
01132         return self.attributes.get('elementFormDefault')
01133 
01134     def isElementFormDefaultQualified(self):
01135         return self.attributes.get('elementFormDefault') == 'qualified'
01136 
01137     def getAttributeFormDefault(self):
01138         """return attributeFormDefault attribute
01139         """
01140         return self.attributes.get('attributeFormDefault')
01141 
01142     def getBlockDefault(self):
01143         """return blockDefault attribute
01144         """
01145         return self.attributes.get('blockDefault')
01146 
01147     def getFinalDefault(self):
01148         """return finalDefault attribute 
01149         """
01150         return self.attributes.get('finalDefault')
01151 
01152     def load(self, node, location=None):
01153         self.__node = node
01154 
01155         pnode = node.getParentNode()
01156         if pnode:
01157             pname = SplitQName(pnode.getTagName())[1]
01158             if pname == 'types':
01159                 attributes = {}
01160                 self.setAttributes(pnode)
01161                 attributes.update(self.attributes)
01162                 self.setAttributes(node)
01163                 for k,v in attributes['xmlns'].items():
01164                     if not self.attributes['xmlns'].has_key(k):
01165                         self.attributes['xmlns'][k] = v
01166             else:
01167                 self.setAttributes(node)
01168         else:
01169             self.setAttributes(node)
01170 
01171         self.targetNamespace = self.getTargetNamespace()
01172         for childNode in self.getContents(node):
01173             component = SplitQName(childNode.getTagName())[1]
01174                 
01175             if component == 'include':
01176                 tp = self.__class__.Include(self)
01177                 tp.fromDom(childNode)
01178 
01179                 sl = tp.attributes['schemaLocation']
01180                 schema = tp.getSchema()
01181 
01182                 if not self.getIncludeSchemas().has_key(sl):
01183                     self.addIncludeSchema(sl, schema)
01184 
01185                 self.includes[sl] = tp
01186 
01187                 pn = childNode.getParentNode().getNode()
01188                 pn.removeChild(childNode.getNode())
01189                 for child in schema.getNode().getNode().childNodes:
01190                     pn.appendChild(child.cloneNode(1))
01191 
01192                 for collection in ['imports','elements','types',
01193                                    'attr_decl','attr_groups','model_groups',
01194                                    'notations']:
01195                     for k,v in getattr(schema,collection).items():
01196                         if not getattr(self,collection).has_key(k):
01197                             v._parent = weakref.ref(self)
01198                             getattr(self,collection)[k] = v
01199                         else:
01200                             warnings.warn("Not keeping schema component.")
01201       
01202             elif component == 'import':
01203                 slocd = SchemaReader.namespaceToSchema
01204                 tp = self.__class__.Import(self)
01205                 tp.fromDom(childNode)
01206                 import_ns = tp.getAttribute('namespace') or\
01207                     self.__class__.empty_namespace
01208                 schema = slocd.get(import_ns)
01209                 if schema is None:
01210                     schema = XMLSchema()
01211                     slocd[import_ns] = schema
01212                     try:
01213                         tp.loadSchema(schema)
01214                     except NoSchemaLocationWarning, ex:
01215                         # Dependency declaration, hopefully implementation
01216                         # is aware of this namespace (eg. SOAP,WSDL,?)
01217                         del slocd[import_ns]
01218                         continue
01219                     except SchemaError, ex:
01220                         warnings.warn(\
01221                             '<import namespace="%s">, %s'\
01222                             %(import_ns, 'failed to load schema instance, resort to lazy eval when necessary')
01223                         )
01224                         del slocd[import_ns]
01225                         class _LazyEvalImport(str):
01226                             '''Lazy evaluation of import, replace entry in self.imports.'''
01227                             #attributes = dict(namespace=import_ns)
01228                             def getSchema(namespace):
01229                                 schema = slocd.get(namespace)
01230                                 if schema is None:
01231                                     parent = self._parent()
01232                                     wstypes = parent
01233                                     if isinstance(parent, WSDLToolsAdapter):
01234                                         wstypes = parent.getImportSchemas()
01235                                     schema = wstypes.get(namespace)
01236                                 if isinstance(schema, XMLSchema):
01237                                     self.imports[namespace] = schema
01238                                     return schema
01239 
01240                                 return None
01241 
01242                         self.imports[import_ns] = _LazyEvalImport(import_ns)
01243                         continue
01244                 else:           
01245                     tp._schema = schema
01246             
01247                 if self.getImportSchemas().has_key(import_ns):
01248                     warnings.warn(\
01249                         'Detected multiple imports of the namespace "%s" '\
01250                         %import_ns)
01251             
01252                 self.addImportSchema(schema)
01253                 # spec says can have multiple imports of same namespace
01254                 # but purpose of import is just dependency declaration.
01255                 self.imports[import_ns] = tp
01256                 
01257             elif component == 'redefine':
01258                 warnings.warn('redefine is ignored')
01259             elif component == 'annotation':
01260                 warnings.warn('annotation is ignored')
01261             elif component == 'attribute':
01262                 tp = AttributeDeclaration(self)
01263                 tp.fromDom(childNode)
01264                 self.attr_decl[tp.getAttribute('name')] = tp
01265             elif component == 'attributeGroup':
01266                 tp = AttributeGroupDefinition(self)
01267                 tp.fromDom(childNode)
01268                 self.attr_groups[tp.getAttribute('name')] = tp
01269             elif component == 'element':
01270                 tp = ElementDeclaration(self)
01271                 tp.fromDom(childNode)
01272                 self.elements[tp.getAttribute('name')] = tp
01273             elif component == 'group':
01274                 tp = ModelGroupDefinition(self)
01275                 tp.fromDom(childNode)
01276                 self.model_groups[tp.getAttribute('name')] = tp
01277             elif component == 'notation':
01278                 tp = Notation(self)
01279                 tp.fromDom(childNode)
01280                 self.notations[tp.getAttribute('name')] = tp
01281             elif component == 'complexType':
01282                 tp = ComplexType(self)
01283                 tp.fromDom(childNode)
01284                 self.types[tp.getAttribute('name')] = tp
01285             elif component == 'simpleType':
01286                 tp = SimpleType(self)
01287                 tp.fromDom(childNode)
01288                 self.types[tp.getAttribute('name')] = tp
01289             else:
01290                 break
01291 
01292     class Import(XMLSchemaComponent):
01293         """<import> 
01294            parent:
01295                schema
01296            attributes:
01297                id -- ID
01298                namespace -- anyURI
01299                schemaLocation -- anyURI
01300            contents:
01301                annotation?
01302         """
01303         attributes = {'id':None,
01304                       'namespace':None,
01305                       'schemaLocation':None}
01306         contents = {'xsd':['annotation']}
01307         tag = 'import'
01308 
01309         def __init__(self, parent):
01310             XMLSchemaComponent.__init__(self, parent)
01311             self.annotation = None
01312             self._schema = None
01313 
01314         def fromDom(self, node):
01315             self.setAttributes(node)
01316             contents = self.getContents(node)
01317 
01318             if self.attributes['namespace'] == self.getTargetNamespace():
01319                 raise SchemaError, 'namespace of schema and import match'
01320 
01321             for i in contents:
01322                 component = SplitQName(i.getTagName())[1]
01323                 if component == 'annotation' and not self.annotation:
01324                     self.annotation = Annotation(self)
01325                     self.annotation.fromDom(i)
01326                 else:
01327                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01328 
01329         def getSchema(self):
01330             """if schema is not defined, first look for a Schema class instance
01331                in parent Schema.  Else if not defined resolve schemaLocation
01332                and create a new Schema class instance, and keep a hard reference. 
01333             """
01334             if not self._schema:
01335                 ns = self.attributes['namespace']
01336                 schema = self._parent().getImportSchemas().get(ns)
01337                 if not schema and self._parent()._parent:
01338                     schema = self._parent()._parent().getImportSchemas().get(ns)
01339 
01340                 if not schema:
01341                     url = self.attributes.get('schemaLocation')
01342                     if not url:
01343                         raise SchemaError, 'namespace(%s) is unknown' %ns
01344                     base_url = self._parent().getBaseUrl()
01345                     reader = SchemaReader(base_url=base_url)
01346                     reader._imports = self._parent().getImportSchemas()
01347                     reader._includes = self._parent().getIncludeSchemas()
01348                     self._schema = reader.loadFromURL(url)
01349             return self._schema or schema
01350             
01351         def loadSchema(self, schema):
01352             """
01353             """
01354             base_url = self._parent().getBaseUrl()
01355             reader = SchemaReader(base_url=base_url)
01356             reader._imports = self._parent().getImportSchemas()
01357             reader._includes = self._parent().getIncludeSchemas()
01358             self._schema = schema
01359 
01360             if not self.attributes.has_key('schemaLocation'):
01361                 raise NoSchemaLocationWarning('no schemaLocation attribute in import')
01362 
01363             reader.loadFromURL(self.attributes.get('schemaLocation'), schema)
01364 
01365 
01366     class Include(XMLSchemaComponent):
01367         """<include schemaLocation>
01368            parent:
01369                schema
01370            attributes:
01371                id -- ID
01372                schemaLocation -- anyURI, required
01373            contents:
01374                annotation?
01375         """
01376         required = ['schemaLocation']
01377         attributes = {'id':None,
01378             'schemaLocation':None}
01379         contents = {'xsd':['annotation']}
01380         tag = 'include'
01381 
01382         def __init__(self, parent):
01383             XMLSchemaComponent.__init__(self, parent)
01384             self.annotation = None
01385             self._schema = None
01386 
01387         def fromDom(self, node):
01388             self.setAttributes(node)
01389             contents = self.getContents(node)
01390 
01391             for i in contents:
01392                 component = SplitQName(i.getTagName())[1]
01393                 if component == 'annotation' and not self.annotation:
01394                     self.annotation = Annotation(self)
01395                     self.annotation.fromDom(i)
01396                 else:
01397                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01398 
01399         def getSchema(self):
01400             """if schema is not defined, first look for a Schema class instance
01401                in parent Schema.  Else if not defined resolve schemaLocation
01402                and create a new Schema class instance.  
01403             """
01404             if not self._schema:
01405                 schema = self._parent()
01406                 self._schema = schema.getIncludeSchemas().get(\
01407                                    self.attributes['schemaLocation']
01408                                    )
01409                 if not self._schema:
01410                     url = self.attributes['schemaLocation']
01411                     reader = SchemaReader(base_url=schema.getBaseUrl())
01412                     reader._imports = schema.getImportSchemas()
01413                     reader._includes = schema.getIncludeSchemas()
01414                     
01415                     # create schema before loading so chameleon include 
01416                     # will evalute targetNamespace correctly.
01417                     self._schema = XMLSchema(schema)
01418                     reader.loadFromURL(url, self._schema)
01419 
01420             return self._schema
01421 
01422 
01423 class AttributeDeclaration(XMLSchemaComponent,\
01424                            AttributeMarker,\
01425                            DeclarationMarker):
01426     """<attribute name>
01427        parent: 
01428            schema
01429        attributes:
01430            id -- ID
01431            name -- NCName, required
01432            type -- QName
01433            default -- string
01434            fixed -- string
01435        contents:
01436            annotation?, simpleType?
01437     """
01438     required = ['name']
01439     attributes = {'id':None,
01440         'name':None,
01441         'type':None,
01442         'default':None,
01443         'fixed':None}
01444     contents = {'xsd':['annotation','simpleType']}
01445     tag = 'attribute'
01446 
01447     def __init__(self, parent):
01448         XMLSchemaComponent.__init__(self, parent)
01449         self.annotation = None
01450         self.content = None
01451 
01452     def fromDom(self, node):
01453         """ No list or union support
01454         """
01455         self.setAttributes(node)
01456         contents = self.getContents(node)
01457 
01458         for i in contents:
01459             component = SplitQName(i.getTagName())[1]
01460             if component == 'annotation' and not self.annotation:
01461                 self.annotation = Annotation(self)
01462                 self.annotation.fromDom(i)
01463             elif component == 'simpleType':
01464                 self.content = AnonymousSimpleType(self)
01465                 self.content.fromDom(i)
01466             else:
01467                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01468 
01469 
01470 class LocalAttributeDeclaration(AttributeDeclaration,\
01471                                 AttributeMarker,\
01472                                 LocalMarker,\
01473                                 DeclarationMarker):
01474     """<attribute name>
01475        parent: 
01476            complexType, restriction, extension, attributeGroup
01477        attributes:
01478            id -- ID
01479            name -- NCName,  required
01480            type -- QName
01481            form -- ('qualified' | 'unqualified'), schema.attributeFormDefault
01482            use -- ('optional' | 'prohibited' | 'required'), optional
01483            default -- string
01484            fixed -- string
01485        contents:
01486            annotation?, simpleType?
01487     """
01488     required = ['name']
01489     attributes = {'id':None, 
01490         'name':None,
01491         'type':None,
01492         'form':lambda self: GetSchema(self).getAttributeFormDefault(),
01493         'use':'optional',
01494         'default':None,
01495         'fixed':None}
01496     contents = {'xsd':['annotation','simpleType']}
01497 
01498     def __init__(self, parent):
01499         AttributeDeclaration.__init__(self, parent)
01500         self.annotation = None
01501         self.content = None
01502 
01503     def fromDom(self, node):
01504         self.setAttributes(node)
01505         contents = self.getContents(node)
01506 
01507         for i in contents:
01508             component = SplitQName(i.getTagName())[1]
01509             if component == 'annotation' and not self.annotation:
01510                 self.annotation = Annotation(self)
01511                 self.annotation.fromDom(i)
01512             elif component == 'simpleType':
01513                 self.content = AnonymousSimpleType(self)
01514                 self.content.fromDom(i)
01515             else:
01516                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01517 
01518 
01519 class AttributeWildCard(XMLSchemaComponent,\
01520                         AttributeMarker,\
01521                         DeclarationMarker,\
01522                         WildCardMarker):
01523     """<anyAttribute>
01524        parents: 
01525            complexType, restriction, extension, attributeGroup
01526        attributes:
01527            id -- ID
01528            namespace -- '##any' | '##other' | 
01529                         (anyURI* | '##targetNamespace' | '##local'), ##any
01530            processContents -- 'lax' | 'skip' | 'strict', strict
01531        contents:
01532            annotation?
01533     """
01534     attributes = {'id':None, 
01535         'namespace':'##any',
01536         'processContents':'strict'}
01537     contents = {'xsd':['annotation']}
01538     tag = 'anyAttribute'
01539 
01540     def __init__(self, parent):
01541         XMLSchemaComponent.__init__(self, parent)
01542         self.annotation = None
01543 
01544     def fromDom(self, node):
01545         self.setAttributes(node)
01546         contents = self.getContents(node)
01547 
01548         for i in contents:
01549             component = SplitQName(i.getTagName())[1]
01550             if component == 'annotation' and not self.annotation:
01551                 self.annotation = Annotation(self)
01552                 self.annotation.fromDom(i)
01553             else:
01554                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01555 
01556 
01557 class AttributeReference(XMLSchemaComponent,\
01558                          AttributeMarker,\
01559                          ReferenceMarker):
01560     """<attribute ref>
01561        parents: 
01562            complexType, restriction, extension, attributeGroup
01563        attributes:
01564            id -- ID
01565            ref -- QName, required
01566            use -- ('optional' | 'prohibited' | 'required'), optional
01567            default -- string
01568            fixed -- string
01569        contents:
01570            annotation?
01571     """
01572     required = ['ref']
01573     attributes = {'id':None, 
01574         'ref':None,
01575         'use':'optional',
01576         'default':None,
01577         'fixed':None}
01578     contents = {'xsd':['annotation']}
01579     tag = 'attribute'
01580 
01581     def __init__(self, parent):
01582         XMLSchemaComponent.__init__(self, parent)
01583         self.annotation = None
01584 
01585     def getAttributeDeclaration(self, attribute='ref'):
01586         return XMLSchemaComponent.getAttributeDeclaration(self, attribute)
01587 
01588     def fromDom(self, node):
01589         self.setAttributes(node)
01590         contents = self.getContents(node)
01591 
01592         for i in contents:
01593             component = SplitQName(i.getTagName())[1]
01594             if component == 'annotation' and not self.annotation:
01595                 self.annotation = Annotation(self)
01596                 self.annotation.fromDom(i)
01597             else:
01598                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01599 
01600 
01601 class AttributeGroupDefinition(XMLSchemaComponent,\
01602                                AttributeGroupMarker,\
01603                                DefinitionMarker):
01604     """<attributeGroup name>
01605        parents: 
01606            schema, redefine
01607        attributes:
01608            id -- ID
01609            name -- NCName,  required
01610        contents:
01611            annotation?, (attribute | attributeGroup)*, anyAttribute?
01612     """
01613     required = ['name']
01614     attributes = {'id':None, 
01615         'name':None}
01616     contents = {'xsd':['annotation', 'attribute', 'attributeGroup', 'anyAttribute']}
01617     tag = 'attributeGroup'
01618 
01619     def __init__(self, parent):
01620         XMLSchemaComponent.__init__(self, parent)
01621         self.annotation = None
01622         self.attr_content = None
01623 
01624     def getAttributeContent(self):
01625         return self.attr_content
01626 
01627     def fromDom(self, node):
01628         self.setAttributes(node)
01629         contents = self.getContents(node)
01630         content = []
01631 
01632         for indx in range(len(contents)):
01633             component = SplitQName(contents[indx].getTagName())[1]
01634             if (component == 'annotation') and (not indx):
01635                 self.annotation = Annotation(self)
01636                 self.annotation.fromDom(contents[indx])
01637             elif component == 'attribute':
01638                 if contents[indx].hasattr('name'):
01639                     content.append(LocalAttributeDeclaration(self))
01640                 elif contents[indx].hasattr('ref'):
01641                     content.append(AttributeReference(self))
01642                 else:
01643                     raise SchemaError, 'Unknown attribute type'
01644                 content[-1].fromDom(contents[indx])
01645             elif component == 'attributeGroup':
01646                 content.append(AttributeGroupReference(self))
01647                 content[-1].fromDom(contents[indx])
01648             elif component == 'anyAttribute':
01649                 if len(contents) != indx+1: 
01650                     raise SchemaError, 'anyAttribute is out of order in %s' %self.getItemTrace()
01651                 content.append(AttributeWildCard(self))
01652                 content[-1].fromDom(contents[indx])
01653             else:
01654                 raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
01655 
01656         self.attr_content = tuple(content)
01657 
01658 class AttributeGroupReference(XMLSchemaComponent,\
01659                               AttributeGroupMarker,\
01660                               ReferenceMarker):
01661     """<attributeGroup ref>
01662        parents: 
01663            complexType, restriction, extension, attributeGroup
01664        attributes:
01665            id -- ID
01666            ref -- QName, required
01667        contents:
01668            annotation?
01669     """
01670     required = ['ref']
01671     attributes = {'id':None, 
01672         'ref':None}
01673     contents = {'xsd':['annotation']}
01674     tag = 'attributeGroup'
01675 
01676     def __init__(self, parent):
01677         XMLSchemaComponent.__init__(self, parent)
01678         self.annotation = None
01679 
01680     def getAttributeGroup(self, attribute='ref'):
01681         """attribute -- attribute with a QName value (eg. type).
01682            collection -- check types collection in parent Schema instance
01683         """
01684         return XMLSchemaComponent.getAttributeGroup(self, attribute)
01685 
01686     def fromDom(self, node):
01687         self.setAttributes(node)
01688         contents = self.getContents(node)
01689 
01690         for i in contents:
01691             component = SplitQName(i.getTagName())[1]
01692             if component == 'annotation' and not self.annotation:
01693                 self.annotation = Annotation(self)
01694                 self.annotation.fromDom(i)
01695             else:
01696                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01697 
01698 
01699 
01700 ######################################################
01701 # Elements
01702 #####################################################
01703 class IdentityConstrants(XMLSchemaComponent):
01704     """Allow one to uniquely identify nodes in a document and ensure the 
01705        integrity of references between them.
01706 
01707        attributes -- dictionary of attributes
01708        selector -- XPath to selected nodes
01709        fields -- list of XPath to key field
01710     """
01711     def __init__(self, parent):
01712         XMLSchemaComponent.__init__(self, parent)
01713         self.selector = None
01714         self.fields = None
01715         self.annotation = None
01716 
01717     def fromDom(self, node):
01718         self.setAttributes(node)
01719         contents = self.getContents(node)
01720         fields = []
01721 
01722         for i in contents:
01723             component = SplitQName(i.getTagName())[1]
01724             if component in self.__class__.contents['xsd']:
01725                 if component == 'annotation' and not self.annotation:
01726                     self.annotation = Annotation(self)
01727                     self.annotation.fromDom(i)
01728                 elif component == 'selector':
01729                     self.selector = self.Selector(self)
01730                     self.selector.fromDom(i)
01731                     continue
01732                 elif component == 'field':
01733                     fields.append(self.Field(self))
01734                     fields[-1].fromDom(i)
01735                     continue
01736                 else:
01737                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01738             else:
01739                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01740             self.fields = tuple(fields)
01741 
01742 
01743     class Constraint(XMLSchemaComponent):
01744         def __init__(self, parent):
01745             XMLSchemaComponent.__init__(self, parent)
01746             self.annotation = None
01747 
01748         def fromDom(self, node):
01749             self.setAttributes(node)
01750             contents = self.getContents(node)
01751 
01752             for i in contents:
01753                 component = SplitQName(i.getTagName())[1]
01754                 if component in self.__class__.contents['xsd']:
01755                     if component == 'annotation' and not self.annotation:
01756                         self.annotation = Annotation(self)
01757                         self.annotation.fromDom(i)
01758                     else:
01759                         raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01760                 else:
01761                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01762 
01763     class Selector(Constraint):
01764         """<selector xpath>
01765            parent: 
01766                unique, key, keyref
01767            attributes:
01768                id -- ID
01769                xpath -- XPath subset,  required
01770            contents:
01771                annotation?
01772         """
01773         required = ['xpath']
01774         attributes = {'id':None, 
01775             'xpath':None}
01776         contents = {'xsd':['annotation']}
01777         tag = 'selector'
01778 
01779     class Field(Constraint): 
01780         """<field xpath>
01781            parent: 
01782                unique, key, keyref
01783            attributes:
01784                id -- ID
01785                xpath -- XPath subset,  required
01786            contents:
01787                annotation?
01788         """
01789         required = ['xpath']
01790         attributes = {'id':None, 
01791             'xpath':None}
01792         contents = {'xsd':['annotation']}
01793         tag = 'field'
01794 
01795 
01796 class Unique(IdentityConstrants):
01797     """<unique name> Enforce fields are unique w/i a specified scope.
01798 
01799        parent: 
01800            element
01801        attributes:
01802            id -- ID
01803            name -- NCName,  required
01804        contents:
01805            annotation?, selector, field+
01806     """
01807     required = ['name']
01808     attributes = {'id':None, 
01809         'name':None}
01810     contents = {'xsd':['annotation', 'selector', 'field']}
01811     tag = 'unique'
01812 
01813 
01814 class Key(IdentityConstrants):
01815     """<key name> Enforce fields are unique w/i a specified scope, and all
01816            field values are present w/i document.  Fields cannot
01817            be nillable.
01818 
01819        parent: 
01820            element
01821        attributes:
01822            id -- ID
01823            name -- NCName,  required
01824        contents:
01825            annotation?, selector, field+
01826     """
01827     required = ['name']
01828     attributes = {'id':None, 
01829         'name':None}
01830     contents = {'xsd':['annotation', 'selector', 'field']}
01831     tag = 'key'
01832 
01833 
01834 class KeyRef(IdentityConstrants):
01835     """<keyref name refer> Ensure a match between two sets of values in an 
01836            instance.
01837        parent: 
01838            element
01839        attributes:
01840            id -- ID
01841            name -- NCName,  required
01842            refer -- QName,  required
01843        contents:
01844            annotation?, selector, field+
01845     """
01846     required = ['name', 'refer']
01847     attributes = {'id':None, 
01848         'name':None,
01849         'refer':None}
01850     contents = {'xsd':['annotation', 'selector', 'field']}
01851     tag = 'keyref'
01852 
01853 
01854 class ElementDeclaration(XMLSchemaComponent,\
01855                          ElementMarker,\
01856                          DeclarationMarker):
01857     """<element name>
01858        parents:
01859            schema
01860        attributes:
01861            id -- ID
01862            name -- NCName,  required
01863            type -- QName
01864            default -- string
01865            fixed -- string
01866            nillable -- boolean,  false
01867            abstract -- boolean,  false
01868            substitutionGroup -- QName
01869            block -- ('#all' | ('substition' | 'extension' | 'restriction')*), 
01870                schema.blockDefault 
01871            final -- ('#all' | ('extension' | 'restriction')*), 
01872                schema.finalDefault 
01873        contents:
01874            annotation?, (simpleType,complexType)?, (key | keyref | unique)*
01875            
01876     """
01877     required = ['name']
01878     attributes = {'id':None, 
01879         'name':None,
01880         'type':None,
01881         'default':None,
01882         'fixed':None,
01883         'nillable':0,
01884         'abstract':0,
01885         'substitutionGroup':None,
01886         'block':lambda self: self._parent().getBlockDefault(),
01887         'final':lambda self: self._parent().getFinalDefault()}
01888     contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
01889         'keyref', 'unique']}
01890     tag = 'element'
01891 
01892     def __init__(self, parent):
01893         XMLSchemaComponent.__init__(self, parent)
01894         self.annotation = None
01895         self.content = None
01896         self.constraints = ()
01897 
01898     def isQualified(self):
01899         """Global elements are always qualified.
01900         """
01901         return True
01902     
01903     def getAttribute(self, attribute):
01904         """return attribute.
01905         If attribute is type and it's None, and no simple or complex content, 
01906         return the default type "xsd:anyType"
01907         """
01908         value = XMLSchemaComponent.getAttribute(self, attribute)
01909         if attribute != 'type' or value is not None:
01910             return value
01911         
01912         if self.content is not None:
01913             return None
01914         
01915         parent = self
01916         while 1:
01917             nsdict = parent.attributes[XMLSchemaComponent.xmlns]
01918             for k,v in nsdict.items():
01919                 if v not in SCHEMA.XSD_LIST: continue
01920                 return TypeDescriptionComponent((v, 'anyType'))
01921             
01922             if isinstance(parent, WSDLToolsAdapter)\
01923                 or not hasattr(parent, '_parent'):
01924                 break
01925             
01926             parent = parent._parent()
01927             
01928         raise SchemaError, 'failed to locate the XSD namespace'
01929     
01930     def getElementDeclaration(self, attribute):
01931         raise Warning, 'invalid operation for <%s>' %self.tag
01932 
01933     def getTypeDefinition(self, attribute=None):
01934         """If attribute is None, "type" is assumed, return the corresponding
01935         representation of the global type definition (TypeDefinition),
01936         or the local definition if don't find "type".  To maintain backwards
01937         compat, if attribute is provided call base class method.
01938         """
01939         if attribute:
01940             return XMLSchemaComponent.getTypeDefinition(self, attribute)
01941         gt = XMLSchemaComponent.getTypeDefinition(self, 'type')
01942         if gt:
01943             return gt
01944         return self.content
01945 
01946     def getConstraints(self):
01947         return self._constraints
01948     def setConstraints(self, constraints):
01949         self._constraints = tuple(constraints)
01950     constraints = property(getConstraints, setConstraints, None, "tuple of key, keyref, unique constraints")
01951 
01952     def fromDom(self, node):
01953         self.setAttributes(node)
01954         contents = self.getContents(node)
01955         constraints = []
01956         for i in contents:
01957             component = SplitQName(i.getTagName())[1]
01958             if component in self.__class__.contents['xsd']:
01959                 if component == 'annotation' and not self.annotation:
01960                     self.annotation = Annotation(self)
01961                     self.annotation.fromDom(i)
01962                 elif component == 'simpleType' and not self.content:
01963                     self.content = AnonymousSimpleType(self)
01964                     self.content.fromDom(i)
01965                 elif component == 'complexType' and not self.content:
01966                     self.content = LocalComplexType(self)
01967                     self.content.fromDom(i)
01968                 elif component == 'key':
01969                     constraints.append(Key(self))
01970                     constraints[-1].fromDom(i)
01971                 elif component == 'keyref':
01972                     constraints.append(KeyRef(self))
01973                     constraints[-1].fromDom(i)
01974                 elif component == 'unique':
01975                     constraints.append(Unique(self))
01976                     constraints[-1].fromDom(i)
01977                 else:
01978                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01979             else:
01980                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
01981 
01982         self.constraints = constraints
01983 
01984 
01985 class LocalElementDeclaration(ElementDeclaration,\
01986                               LocalMarker):
01987     """<element>
01988        parents:
01989            all, choice, sequence
01990        attributes:
01991            id -- ID
01992            name -- NCName,  required
01993            form -- ('qualified' | 'unqualified'), schema.elementFormDefault
01994            type -- QName
01995            minOccurs -- Whole Number, 1
01996            maxOccurs -- (Whole Number | 'unbounded'), 1
01997            default -- string
01998            fixed -- string
01999            nillable -- boolean,  false
02000            block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault 
02001        contents:
02002            annotation?, (simpleType,complexType)?, (key | keyref | unique)*
02003     """
02004     required = ['name']
02005     attributes = {'id':None, 
02006         'name':None,
02007         'form':lambda self: GetSchema(self).getElementFormDefault(),
02008         'type':None,
02009         'minOccurs':'1',
02010         'maxOccurs':'1',
02011         'default':None,
02012         'fixed':None,
02013         'nillable':0,
02014         'abstract':0,
02015         'block':lambda self: GetSchema(self).getBlockDefault()}
02016     contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
02017         'keyref', 'unique']}
02018 
02019     def isQualified(self):
02020         """
02021 Local elements can be qualified or unqualifed according
02022         to the attribute form, or the elementFormDefault.  By default
02023         local elements are unqualified.
02024         """
02025         form = self.getAttribute('form')
02026         if form == 'qualified':
02027             return True
02028         if form == 'unqualified':
02029             return False
02030         raise SchemaError, 'Bad form (%s) for element: %s' %(form, self.getItemTrace())
02031 
02032 
02033 class ElementReference(XMLSchemaComponent,\
02034                        ElementMarker,\
02035                        ReferenceMarker):
02036     """<element ref>
02037        parents: 
02038            all, choice, sequence
02039        attributes:
02040            id -- ID
02041            ref -- QName, required
02042            minOccurs -- Whole Number, 1
02043            maxOccurs -- (Whole Number | 'unbounded'), 1
02044        contents:
02045            annotation?
02046     """
02047     required = ['ref']
02048     attributes = {'id':None, 
02049         'ref':None,
02050         'minOccurs':'1',
02051         'maxOccurs':'1'}
02052     contents = {'xsd':['annotation']}
02053     tag = 'element'
02054 
02055     def __init__(self, parent):
02056         XMLSchemaComponent.__init__(self, parent)
02057         self.annotation = None
02058 
02059     def getElementDeclaration(self, attribute=None):
02060         """If attribute is None, "ref" is assumed, return the corresponding
02061         representation of the global element declaration (ElementDeclaration),
02062         To maintain backwards compat, if attribute is provided call base class method.
02063         """
02064         if attribute:
02065             return XMLSchemaComponent.getElementDeclaration(self, attribute)
02066         return XMLSchemaComponent.getElementDeclaration(self, 'ref')
02067  
02068     def fromDom(self, node):
02069         self.annotation = None
02070         self.setAttributes(node)
02071         for i in self.getContents(node):
02072             component = SplitQName(i.getTagName())[1]
02073             if component in self.__class__.contents['xsd']:
02074                 if component == 'annotation' and not self.annotation:
02075                     self.annotation = Annotation(self)
02076                     self.annotation.fromDom(i)
02077                 else:
02078                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02079 
02080 
02081 class ElementWildCard(LocalElementDeclaration, WildCardMarker):
02082     """<any>
02083        parents: 
02084            choice, sequence
02085        attributes:
02086            id -- ID
02087            minOccurs -- Whole Number, 1
02088            maxOccurs -- (Whole Number | 'unbounded'), 1
02089            namespace -- '##any' | '##other' | 
02090                         (anyURI* | '##targetNamespace' | '##local'), ##any
02091            processContents -- 'lax' | 'skip' | 'strict', strict
02092        contents:
02093            annotation?
02094     """
02095     required = []
02096     attributes = {'id':None, 
02097         'minOccurs':'1',
02098         'maxOccurs':'1',
02099         'namespace':'##any',
02100         'processContents':'strict'}
02101     contents = {'xsd':['annotation']}
02102     tag = 'any'
02103 
02104     def __init__(self, parent):
02105         XMLSchemaComponent.__init__(self, parent)
02106         self.annotation = None
02107 
02108     def isQualified(self):
02109         """
02110         Global elements are always qualified, but if processContents
02111         are not strict could have dynamically generated local elements.
02112         """
02113         return GetSchema(self).isElementFormDefaultQualified()
02114 
02115     def getAttribute(self, attribute):
02116         """return attribute.
02117         """
02118         return XMLSchemaComponent.getAttribute(self, attribute)
02119 
02120     def getTypeDefinition(self, attribute):
02121         raise Warning, 'invalid operation for <%s>' % self.tag
02122 
02123     def fromDom(self, node):
02124         self.annotation = None
02125         self.setAttributes(node)
02126         for i in self.getContents(node):
02127             component = SplitQName(i.getTagName())[1]
02128             if component in self.__class__.contents['xsd']:
02129                 if component == 'annotation' and not self.annotation:
02130                     self.annotation = Annotation(self)
02131                     self.annotation.fromDom(i)
02132                 else:
02133                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02134 
02135 
02136 ######################################################
02137 # Model Groups
02138 #####################################################
02139 class Sequence(XMLSchemaComponent,\
02140                SequenceMarker):
02141     """<sequence>
02142        parents: 
02143            complexType, extension, restriction, group, choice, sequence
02144        attributes:
02145            id -- ID
02146            minOccurs -- Whole Number, 1
02147            maxOccurs -- (Whole Number | 'unbounded'), 1
02148 
02149        contents:
02150            annotation?, (element | group | choice | sequence | any)*
02151     """
02152     attributes = {'id':None, 
02153         'minOccurs':'1',
02154         'maxOccurs':'1'}
02155     contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
02156          'any']}
02157     tag = 'sequence'
02158 
02159     def __init__(self, parent):
02160         XMLSchemaComponent.__init__(self, parent)
02161         self.annotation = None
02162         self.content = None
02163 
02164     def fromDom(self, node):
02165         self.setAttributes(node)
02166         contents = self.getContents(node)
02167         content = []
02168 
02169         for i in contents:
02170             component = SplitQName(i.getTagName())[1]
02171             if component in self.__class__.contents['xsd']:
02172                 if component == 'annotation' and not self.annotation:
02173                     self.annotation = Annotation(self)
02174                     self.annotation.fromDom(i)
02175                     continue
02176                 elif component == 'element':
02177                     if i.hasattr('ref'):
02178                         content.append(ElementReference(self))
02179                     else:
02180                         content.append(LocalElementDeclaration(self))
02181                 elif component == 'group':
02182                     content.append(ModelGroupReference(self))
02183                 elif component == 'choice':
02184                     content.append(Choice(self))
02185                 elif component == 'sequence':
02186                     content.append(Sequence(self))
02187                 elif component == 'any':
02188                     content.append(ElementWildCard(self))
02189                 else:
02190                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02191                 content[-1].fromDom(i)
02192             else:
02193                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02194         self.content = tuple(content)
02195 
02196 
02197 class All(XMLSchemaComponent,\
02198           AllMarker):
02199     """<all>
02200        parents: 
02201            complexType, extension, restriction, group
02202        attributes:
02203            id -- ID
02204            minOccurs -- '0' | '1', 1
02205            maxOccurs -- '1', 1
02206 
02207        contents:
02208            annotation?, element*
02209     """
02210     attributes = {'id':None, 
02211         'minOccurs':'1',
02212         'maxOccurs':'1'}
02213     contents = {'xsd':['annotation', 'element']}
02214     tag = 'all'
02215 
02216     def __init__(self, parent):
02217         XMLSchemaComponent.__init__(self, parent)
02218         self.annotation = None
02219         self.content = None
02220 
02221     def fromDom(self, node):
02222         self.setAttributes(node)
02223         contents = self.getContents(node)
02224         content = []
02225 
02226         for i in contents:
02227             component = SplitQName(i.getTagName())[1]
02228             if component in self.__class__.contents['xsd']:
02229                 if component == 'annotation' and not self.annotation:
02230                     self.annotation = Annotation(self)
02231                     self.annotation.fromDom(i)
02232                     continue
02233                 elif component == 'element':
02234                     if i.hasattr('ref'):
02235                         content.append(ElementReference(self))
02236                     else:
02237                         content.append(LocalElementDeclaration(self))
02238                 else:
02239                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02240                 content[-1].fromDom(i)
02241             else:
02242                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02243         self.content = tuple(content)
02244 
02245 
02246 class Choice(XMLSchemaComponent,\
02247              ChoiceMarker):
02248     """<choice>
02249        parents: 
02250            complexType, extension, restriction, group, choice, sequence
02251        attributes:
02252            id -- ID
02253            minOccurs -- Whole Number, 1
02254            maxOccurs -- (Whole Number | 'unbounded'), 1
02255 
02256        contents:
02257            annotation?, (element | group | choice | sequence | any)*
02258     """
02259     attributes = {'id':None, 
02260         'minOccurs':'1',
02261         'maxOccurs':'1'}
02262     contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
02263          'any']}
02264     tag = 'choice'
02265 
02266     def __init__(self, parent):
02267         XMLSchemaComponent.__init__(self, parent)
02268         self.annotation = None
02269         self.content = None
02270 
02271     def fromDom(self, node):
02272         self.setAttributes(node)
02273         contents = self.getContents(node)
02274         content = []
02275 
02276         for i in contents:
02277             component = SplitQName(i.getTagName())[1]
02278             if component in self.__class__.contents['xsd']:
02279                 if component == 'annotation' and not self.annotation:
02280                     self.annotation = Annotation(self)
02281                     self.annotation.fromDom(i)
02282                     continue
02283                 elif component == 'element':
02284                     if i.hasattr('ref'):
02285                         content.append(ElementReference(self))
02286                     else:
02287                         content.append(LocalElementDeclaration(self))
02288                 elif component == 'group':
02289                     content.append(ModelGroupReference(self))
02290                 elif component == 'choice':
02291                     content.append(Choice(self))
02292                 elif component == 'sequence':
02293                     content.append(Sequence(self))
02294                 elif component == 'any':
02295                     content.append(ElementWildCard(self))
02296                 else:
02297                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02298                 content[-1].fromDom(i)
02299             else:
02300                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02301         self.content = tuple(content)
02302 
02303 
02304 class ModelGroupDefinition(XMLSchemaComponent,\
02305                            ModelGroupMarker,\
02306                            DefinitionMarker):
02307     """<group name>
02308        parents:
02309            redefine, schema
02310        attributes:
02311            id -- ID
02312            name -- NCName,  required
02313 
02314        contents:
02315            annotation?, (all | choice | sequence)?
02316     """
02317     required = ['name']
02318     attributes = {'id':None, 
02319         'name':None}
02320     contents = {'xsd':['annotation', 'all', 'choice', 'sequence']}
02321     tag = 'group'
02322 
02323     def __init__(self, parent):
02324         XMLSchemaComponent.__init__(self, parent)
02325         self.annotation = None
02326         self.content = None
02327 
02328     def fromDom(self, node):
02329         self.setAttributes(node)
02330         contents = self.getContents(node)
02331 
02332         for i in contents:
02333             component = SplitQName(i.getTagName())[1]
02334             if component in self.__class__.contents['xsd']:
02335                 if component == 'annotation' and not self.annotation:
02336                     self.annotation = Annotation(self)
02337                     self.annotation.fromDom(i)
02338                     continue
02339                 elif component == 'all' and not self.content:
02340                     self.content = All(self)
02341                 elif component == 'choice' and not self.content:
02342                     self.content = Choice(self)
02343                 elif component == 'sequence' and not self.content:
02344                     self.content = Sequence(self)
02345                 else:
02346                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02347                 self.content.fromDom(i)
02348             else:
02349                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02350 
02351 
02352 class ModelGroupReference(XMLSchemaComponent,\
02353                           ModelGroupMarker,\
02354                           ReferenceMarker):
02355     """<group ref>
02356        parents:
02357            choice, complexType, extension, restriction, sequence
02358        attributes:
02359            id -- ID
02360            ref -- NCName,  required
02361            minOccurs -- Whole Number, 1
02362            maxOccurs -- (Whole Number | 'unbounded'), 1
02363 
02364        contents:
02365            annotation?
02366     """
02367     required = ['ref']
02368     attributes = {'id':None, 
02369         'ref':None,
02370         'minOccurs':'1',
02371         'maxOccurs':'1'}
02372     contents = {'xsd':['annotation']}
02373     tag = 'group'
02374 
02375     def __init__(self, parent):
02376         XMLSchemaComponent.__init__(self, parent)
02377         self.annotation = None
02378 
02379     def getModelGroupReference(self):
02380         return self.getModelGroup('ref')
02381 
02382     def fromDom(self, node):
02383         self.setAttributes(node)
02384         contents = self.getContents(node)
02385 
02386         for i in contents:
02387             component = SplitQName(i.getTagName())[1]
02388             if component in self.__class__.contents['xsd']:
02389                 if component == 'annotation' and not self.annotation:
02390                     self.annotation = Annotation(self)
02391                     self.annotation.fromDom(i)
02392                 else:
02393                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02394             else:
02395                 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02396 
02397 
02398 
02399 class ComplexType(XMLSchemaComponent,\
02400                   DefinitionMarker,\
02401                   ComplexMarker):
02402     """<complexType name>
02403        parents:
02404            redefine, schema
02405        attributes:
02406            id -- ID
02407            name -- NCName,  required
02408            mixed -- boolean, false
02409            abstract -- boolean,  false
02410            block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault 
02411            final -- ('#all' | ('extension' | 'restriction')*), schema.finalDefault 
02412 
02413        contents:
02414            annotation?, (simpleContent | complexContent | 
02415            ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
02416     """
02417     required = ['name']
02418     attributes = {'id':None, 
02419         'name':None,
02420         'mixed':0,
02421         'abstract':0,
02422         'block':lambda self: self._parent().getBlockDefault(),
02423         'final':lambda self: self._parent().getFinalDefault()}
02424     contents = {'xsd':['annotation', 'simpleContent', 'complexContent',\
02425         'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\
02426         'anyAttribute', 'any']}
02427     tag = 'complexType'
02428 
02429     def __init__(self, parent):
02430         XMLSchemaComponent.__init__(self, parent)
02431         self.annotation = None
02432         self.content = None
02433         self.attr_content = None
02434 
02435     def isMixed(self):
02436         m = self.getAttribute('mixed')
02437         if m == 0 or m == False:
02438             return False
02439         if isinstance(m, basestring) is True:
02440             if m in ('false', '0'):
02441                 return False
02442             if m in ('true', '1'):
02443                 return True
02444 
02445         raise SchemaError, 'invalid value for attribute mixed(%s): %s'\
02446             %(m, self.getItemTrace())
02447 
02448     def getAttributeContent(self):
02449         return self.attr_content
02450 
02451     def getElementDeclaration(self, attribute):
02452         raise Warning, 'invalid operation for <%s>' %self.tag
02453 
02454     def getTypeDefinition(self, attribute):
02455         raise Warning, 'invalid operation for <%s>' %self.tag
02456 
02457     def fromDom(self, node):
02458         self.setAttributes(node)
02459         contents = self.getContents(node)
02460       
02461         indx = 0
02462         num = len(contents)
02463         if not num:
02464             return
02465 
02466         component = SplitQName(contents[indx].getTagName())[1]
02467         if component == 'annotation':
02468             self.annotation = Annotation(self)
02469             self.annotation.fromDom(contents[indx])
02470             indx += 1
02471             component = SplitQName(contents[indx].getTagName())[1]
02472 
02473         self.content = None
02474         if component == 'simpleContent':
02475             self.content = self.__class__.SimpleContent(self)
02476             self.content.fromDom(contents[indx])
02477         elif component == 'complexContent':
02478             self.content = self.__class__.ComplexContent(self)
02479             self.content.fromDom(contents[indx])
02480         else:
02481             if component == 'all':
02482                 self.content = All(self)
02483             elif component == 'choice':
02484                 self.content = Choice(self)
02485             elif component == 'sequence':
02486                 self.content = Sequence(self)
02487             elif component == 'group':
02488                 self.content = ModelGroupReference(self)
02489 
02490             if self.content:
02491                 self.content.fromDom(contents[indx])
02492                 indx += 1
02493 
02494             self.attr_content = []
02495             while indx < num:
02496                 component = SplitQName(contents[indx].getTagName())[1]
02497                 if component == 'attribute':
02498                     if contents[indx].hasattr('ref'):
02499                         self.attr_content.append(AttributeReference(self))
02500                     else:
02501                         self.attr_content.append(LocalAttributeDeclaration(self))
02502                 elif component == 'attributeGroup':
02503                     self.attr_content.append(AttributeGroupReference(self))
02504                 elif component == 'anyAttribute':
02505                     self.attr_content.append(AttributeWildCard(self))
02506                 else:
02507                     raise SchemaError, 'Unknown component (%s): %s' \
02508                         %(contents[indx].getTagName(),self.getItemTrace())
02509                 self.attr_content[-1].fromDom(contents[indx])
02510                 indx += 1
02511 
02512     class _DerivedType(XMLSchemaComponent):
02513         def __init__(self, parent):
02514             XMLSchemaComponent.__init__(self, parent)
02515             self.annotation = None
02516             # XXX remove attribute derivation, inconsistent
02517             self.derivation = None
02518             self.content = None
02519 
02520         def fromDom(self, node):
02521             self.setAttributes(node)
02522             contents = self.getContents(node)
02523 
02524             for i in contents:
02525                 component = SplitQName(i.getTagName())[1]
02526                 if component in self.__class__.contents['xsd']:
02527                     if component == 'annotation' and not self.annotation:
02528                         self.annotation = Annotation(self)
02529                         self.annotation.fromDom(i)
02530                         continue
02531                     elif component == 'restriction' and not self.derivation:
02532                         self.derivation = self.__class__.Restriction(self)
02533                     elif component == 'extension' and not self.derivation:
02534                         self.derivation = self.__class__.Extension(self)
02535                     else:
02536                         raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02537                 else:
02538                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02539                 self.derivation.fromDom(i)
02540             self.content = self.derivation
02541 
02542     class ComplexContent(_DerivedType,\
02543                          ComplexMarker):
02544         """<complexContent>
02545            parents:
02546                complexType
02547            attributes:
02548                id -- ID
02549                mixed -- boolean, false
02550 
02551            contents:
02552                annotation?, (restriction | extension)
02553         """
02554         attributes = {'id':None, 
02555             'mixed':0}
02556         contents = {'xsd':['annotation', 'restriction', 'extension']}
02557         tag = 'complexContent'
02558 
02559         def isMixed(self):
02560             m = self.getAttribute('mixed')
02561             if m == 0 or m == False:
02562                 return False
02563             if isinstance(m, basestring) is True:
02564                 if m in ('false', '0'):
02565                     return False
02566                 if m in ('true', '1'):
02567                     return True
02568             raise SchemaError, 'invalid value for attribute mixed(%s): %s'\
02569                 %(m, self.getItemTrace())
02570 
02571         class _DerivationBase(XMLSchemaComponent):
02572             """<extension>,<restriction>
02573                parents:
02574                    complexContent
02575                attributes:
02576                    id -- ID
02577                    base -- QName, required
02578 
02579                contents:
02580                    annotation?, (group | all | choice | sequence)?, 
02581                        (attribute | attributeGroup)*, anyAttribute?
02582             """
02583             required = ['base']
02584             attributes = {'id':None, 
02585                 'base':None }
02586             contents = {'xsd':['annotation', 'group', 'all', 'choice',\
02587                 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']}
02588 
02589             def __init__(self, parent):
02590                 XMLSchemaComponent.__init__(self, parent)
02591                 self.annotation = None
02592                 self.content = None
02593                 self.attr_content = None
02594 
02595             def getAttributeContent(self):
02596                 return self.attr_content
02597 
02598             def fromDom(self, node):
02599                 self.setAttributes(node)
02600                 contents = self.getContents(node)
02601 
02602                 indx = 0
02603                 num = len(contents)
02604                 #XXX ugly
02605                 if not num:
02606                     return
02607                 component = SplitQName(contents[indx].getTagName())[1]
02608                 if component == 'annotation':
02609                     self.annotation = Annotation(self)
02610                     self.annotation.fromDom(contents[indx])
02611                     indx += 1
02612                     component = SplitQName(contents[indx].getTagName())[1]
02613 
02614                 if component == 'all':
02615                     self.content = All(self)
02616                     self.content.fromDom(contents[indx])
02617                     indx += 1
02618                 elif component == 'choice':
02619                     self.content = Choice(self)
02620                     self.content.fromDom(contents[indx])
02621                     indx += 1
02622                 elif component == 'sequence':
02623                     self.content = Sequence(self)
02624                     self.content.fromDom(contents[indx])
02625                     indx += 1
02626                 elif component == 'group':
02627                     self.content = ModelGroupReference(self)
02628                     self.content.fromDom(contents[indx])
02629                     indx += 1
02630                 else:
02631                     self.content = None
02632 
02633                 self.attr_content = []
02634                 while indx < num:
02635                     component = SplitQName(contents[indx].getTagName())[1]
02636                     if component == 'attribute':
02637                         if contents[indx].hasattr('ref'):
02638                             self.attr_content.append(AttributeReference(self))
02639                         else:
02640                             self.attr_content.append(LocalAttributeDeclaration(self))
02641                     elif component == 'attributeGroup':
02642                         if contents[indx].hasattr('ref'):
02643                             self.attr_content.append(AttributeGroupReference(self))
02644                         else:
02645                             self.attr_content.append(AttributeGroupDefinition(self))
02646                     elif component == 'anyAttribute':
02647                         self.attr_content.append(AttributeWildCard(self))
02648                     else:
02649                         raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
02650                     self.attr_content[-1].fromDom(contents[indx])
02651                     indx += 1
02652 
02653         class Extension(_DerivationBase, 
02654                         ExtensionMarker):
02655             """<extension base>
02656                parents:
02657                    complexContent
02658                attributes:
02659                    id -- ID
02660                    base -- QName, required
02661 
02662                contents:
02663                    annotation?, (group | all | choice | sequence)?, 
02664                        (attribute | attributeGroup)*, anyAttribute?
02665             """
02666             tag = 'extension'
02667 
02668         class Restriction(_DerivationBase,\
02669                           RestrictionMarker):
02670             """<restriction base>
02671                parents:
02672                    complexContent
02673                attributes:
02674                    id -- ID
02675                    base -- QName, required
02676 
02677                contents:
02678                    annotation?, (group | all | choice | sequence)?, 
02679                        (attribute | attributeGroup)*, anyAttribute?
02680             """
02681             tag = 'restriction'
02682 
02683 
02684     class SimpleContent(_DerivedType,\
02685                         SimpleMarker):
02686         """<simpleContent>
02687            parents:
02688                complexType
02689            attributes:
02690                id -- ID
02691 
02692            contents:
02693                annotation?, (restriction | extension)
02694         """
02695         attributes = {'id':None}
02696         contents = {'xsd':['annotation', 'restriction', 'extension']}
02697         tag = 'simpleContent'
02698 
02699         class Extension(XMLSchemaComponent,\
02700                         ExtensionMarker):
02701             """<extension base>
02702                parents:
02703                    simpleContent
02704                attributes:
02705                    id -- ID
02706                    base -- QName, required
02707 
02708                contents:
02709                    annotation?, (attribute | attributeGroup)*, anyAttribute?
02710             """
02711             required = ['base']
02712             attributes = {'id':None, 
02713                 'base':None }
02714             contents = {'xsd':['annotation', 'attribute', 'attributeGroup', 
02715                 'anyAttribute']}
02716             tag = 'extension'
02717 
02718             def __init__(self, parent):
02719                 XMLSchemaComponent.__init__(self, parent)
02720                 self.annotation = None
02721                 self.attr_content = None
02722  
02723             def getAttributeContent(self):
02724                 return self.attr_content
02725 
02726             def fromDom(self, node):
02727                 self.setAttributes(node)
02728                 contents = self.getContents(node)
02729 
02730                 indx = 0
02731                 num = len(contents)
02732 
02733                 if num:
02734                     component = SplitQName(contents[indx].getTagName())[1]
02735                     if component == 'annotation':
02736                         self.annotation = Annotation(self)
02737                         self.annotation.fromDom(contents[indx])
02738                         indx += 1
02739                         component = SplitQName(contents[indx].getTagName())[1]
02740     
02741                 content = []
02742                 while indx < num:
02743                     component = SplitQName(contents[indx].getTagName())[1]
02744                     if component == 'attribute':
02745                         if contents[indx].hasattr('ref'):
02746                             content.append(AttributeReference(self))
02747                         else:
02748                             content.append(LocalAttributeDeclaration(self))
02749                     elif component == 'attributeGroup':
02750                         content.append(AttributeGroupReference(self))
02751                     elif component == 'anyAttribute':
02752                         content.append(AttributeWildCard(self))
02753                     else:
02754                         raise SchemaError, 'Unknown component (%s)'\
02755                             %(contents[indx].getTagName())
02756                     content[-1].fromDom(contents[indx])
02757                     indx += 1
02758                 self.attr_content = tuple(content)
02759 
02760 
02761         class Restriction(XMLSchemaComponent,\
02762                           RestrictionMarker):
02763             """<restriction base>
02764                parents:
02765                    simpleContent
02766                attributes:
02767                    id -- ID
02768                    base -- QName, required
02769 
02770                contents:
02771                    annotation?, simpleType?, (enumeration | length | 
02772                    maxExclusive | maxInclusive | maxLength | minExclusive | 
02773                    minInclusive | minLength | pattern | fractionDigits | 
02774                    totalDigits | whiteSpace)*, (attribute | attributeGroup)*, 
02775                    anyAttribute?
02776             """
02777             required = ['base']
02778             attributes = {'id':None, 
02779                 'base':None }
02780             contents = {'xsd':['annotation', 'simpleType', 'attribute',\
02781                 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets}
02782             tag = 'restriction'
02783 
02784             def __init__(self, parent):
02785                 XMLSchemaComponent.__init__(self, parent)
02786                 self.annotation = None
02787                 self.content = None
02788                 self.attr_content = None
02789  
02790             def getAttributeContent(self):
02791                 return self.attr_content
02792 
02793             def fromDom(self, node):
02794                 self.content = []
02795                 self.setAttributes(node)
02796                 contents = self.getContents(node)
02797 
02798                 indx = 0
02799                 num = len(contents)
02800                 component = SplitQName(contents[indx].getTagName())[1]
02801                 if component == 'annotation':
02802                     self.annotation = Annotation(self)
02803                     self.annotation.fromDom(contents[indx])
02804                     indx += 1
02805                     component = SplitQName(contents[indx].getTagName())[1]
02806 
02807                 content = []
02808                 while indx < num:
02809                     component = SplitQName(contents[indx].getTagName())[1]
02810                     if component == 'attribute':
02811                         if contents[indx].hasattr('ref'):
02812                             content.append(AttributeReference(self))
02813                         else:
02814                             content.append(LocalAttributeDeclaration(self))
02815                     elif component == 'attributeGroup':
02816                         content.append(AttributeGroupReference(self))
02817                     elif component == 'anyAttribute':
02818                         content.append(AttributeWildCard(self))
02819                     elif component == 'simpleType':
02820                         self.content.append(AnonymousSimpleType(self))
02821                         self.content[-1].fromDom(contents[indx])
02822                     else:
02823                         raise SchemaError, 'Unknown component (%s)'\
02824                             %(contents[indx].getTagName())
02825                     content[-1].fromDom(contents[indx])
02826                     indx += 1
02827                 self.attr_content = tuple(content)
02828 
02829 
02830 class LocalComplexType(ComplexType,\
02831                        LocalMarker):
02832     """<complexType>
02833        parents:
02834            element
02835        attributes:
02836            id -- ID
02837            mixed -- boolean, false
02838 
02839        contents:
02840            annotation?, (simpleContent | complexContent | 
02841            ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
02842     """
02843     required = []
02844     attributes = {'id':None, 
02845         'mixed':0}
02846     tag = 'complexType'
02847     
02848 
02849 class SimpleType(XMLSchemaComponent,\
02850                  DefinitionMarker,\
02851                  SimpleMarker):
02852     """<simpleType name>
02853        parents:
02854            redefine, schema
02855        attributes:
02856            id -- ID
02857            name -- NCName, required
02858            final -- ('#all' | ('extension' | 'restriction' | 'list' | 'union')*), 
02859                schema.finalDefault 
02860 
02861        contents:
02862            annotation?, (restriction | list | union)
02863     """
02864     required = ['name']
02865     attributes = {'id':None,
02866         'name':None,
02867         'final':lambda self: self._parent().getFinalDefault()}
02868     contents = {'xsd':['annotation', 'restriction', 'list', 'union']}
02869     tag = 'simpleType'
02870 
02871     def __init__(self, parent):
02872         XMLSchemaComponent.__init__(self, parent)
02873         self.annotation = None
02874         self.content = None
02875 
02876     def getElementDeclaration(self, attribute):
02877         raise Warning, 'invalid operation for <%s>' %self.tag
02878 
02879     def getTypeDefinition(self, attribute):
02880         raise Warning, 'invalid operation for <%s>' %self.tag
02881 
02882     def fromDom(self, node):
02883         self.setAttributes(node)
02884         contents = self.getContents(node)
02885         for child in contents:
02886             component = SplitQName(child.getTagName())[1]
02887             if component == 'annotation':
02888                 self.annotation = Annotation(self)
02889                 self.annotation.fromDom(child)
02890                 continue
02891             break
02892         else:
02893             return
02894         if component == 'restriction':
02895             self.content = self.__class__.Restriction(self)
02896         elif component == 'list':
02897             self.content = self.__class__.List(self)
02898         elif component == 'union':
02899             self.content = self.__class__.Union(self)
02900         else:
02901             raise SchemaError, 'Unknown component (%s)' %(component)
02902         self.content.fromDom(child)
02903 
02904     class Restriction(XMLSchemaComponent,\
02905                       RestrictionMarker):
02906         """<restriction base>
02907            parents:
02908                simpleType
02909            attributes:
02910                id -- ID
02911                base -- QName, required or simpleType child
02912 
02913            contents:
02914                annotation?, simpleType?, (enumeration | length | 
02915                maxExclusive | maxInclusive | maxLength | minExclusive | 
02916                minInclusive | minLength | pattern | fractionDigits | 
02917                totalDigits | whiteSpace)*
02918         """
02919         attributes = {'id':None, 
02920             'base':None }
02921         contents = {'xsd':['annotation', 'simpleType']+RestrictionMarker.facets}
02922         tag = 'restriction'
02923 
02924         def __init__(self, parent):
02925             XMLSchemaComponent.__init__(self, parent)
02926             self.annotation = None
02927             self.content = None
02928             self.facets = None
02929 
02930         def getAttributeBase(self):
02931             return XMLSchemaComponent.getAttribute(self, 'base')
02932 
02933         def getTypeDefinition(self, attribute='base'):
02934             return XMLSchemaComponent.getTypeDefinition(self, attribute)
02935 
02936         def getSimpleTypeContent(self):
02937             for el in self.content:
02938                 if el.isSimple(): return el
02939             return None
02940 
02941         def fromDom(self, node):
02942             self.facets = []
02943             self.setAttributes(node)
02944             contents = self.getContents(node)
02945             content = []
02946 
02947             for indx in range(len(contents)):
02948                 component = SplitQName(contents[indx].getTagName())[1]
02949                 if (component == 'annotation') and (not indx):
02950                     self.annotation = Annotation(self)
02951                     self.annotation.fromDom(contents[indx])
02952                     continue
02953                 elif (component == 'simpleType') and (not indx or indx == 1):
02954                     content.append(AnonymousSimpleType(self))
02955                     content[-1].fromDom(contents[indx])
02956                 elif component in RestrictionMarker.facets:
02957                     self.facets.append(contents[indx])
02958                 else:
02959                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
02960             self.content = tuple(content)
02961 
02962 
02963     class Union(XMLSchemaComponent,
02964                 UnionMarker):
02965         """<union>
02966            parents:
02967                simpleType
02968            attributes:
02969                id -- ID
02970                memberTypes -- list of QNames, required or simpleType child.
02971 
02972            contents:
02973                annotation?, simpleType*
02974         """
02975         attributes = {'id':None, 
02976             'memberTypes':None }
02977         contents = {'xsd':['annotation', 'simpleType']}
02978         tag = 'union'
02979 
02980         def __init__(self, parent):
02981             XMLSchemaComponent.__init__(self, parent)
02982             self.annotation = None
02983             self.content = None
02984 
02985         def fromDom(self, node):
02986             self.setAttributes(node)
02987             contents = self.getContents(node)
02988             content = []
02989 
02990             for indx in range(len(contents)):
02991                 component = SplitQName(contents[indx].getTagName())[1]
02992                 if (component == 'annotation') and (not indx):
02993                     self.annotation = Annotation(self)
02994                     self.annotation.fromDom(contents[indx])
02995                 elif (component == 'simpleType'):
02996                     content.append(AnonymousSimpleType(self))
02997                     content[-1].fromDom(contents[indx])
02998                 else:
02999                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
03000             self.content = tuple(content)
03001 
03002     class List(XMLSchemaComponent, 
03003                ListMarker):
03004         """<list>
03005            parents:
03006                simpleType
03007            attributes:
03008                id -- ID
03009                itemType -- QName, required or simpleType child.
03010 
03011            contents:
03012                annotation?, simpleType?
03013         """
03014         attributes = {'id':None, 
03015             'itemType':None }
03016         contents = {'xsd':['annotation', 'simpleType']}
03017         tag = 'list'
03018 
03019         def __init__(self, parent):
03020             XMLSchemaComponent.__init__(self, parent)
03021             self.annotation = None
03022             self.content = None
03023 
03024         def getItemType(self):
03025             return self.attributes.get('itemType')
03026 
03027         def getTypeDefinition(self, attribute='itemType'):
03028             """
03029             return the type refered to by itemType attribute or
03030             the simpleType content.  If returns None, then the 
03031             type refered to by itemType is primitive.
03032             """
03033             tp = XMLSchemaComponent.getTypeDefinition(self, attribute)
03034             return tp or self.content
03035 
03036         def fromDom(self, node):
03037             self.annotation = None
03038             self.content = None
03039             self.setAttributes(node)
03040             contents = self.getContents(node)
03041             for indx in range(len(contents)):
03042                 component = SplitQName(contents[indx].getTagName())[1]
03043                 if (component == 'annotation') and (not indx):
03044                     self.annotation = Annotation(self)
03045                     self.annotation.fromDom(contents[indx])
03046                 elif (component == 'simpleType'):
03047                     self.content = AnonymousSimpleType(self)
03048                     self.content.fromDom(contents[indx])
03049                     break
03050                 else:
03051                     raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
03052 
03053                  
03054 class AnonymousSimpleType(SimpleType,\
03055                           SimpleMarker,\
03056                           LocalMarker):
03057     """<simpleType>
03058        parents:
03059            attribute, element, list, restriction, union
03060        attributes:
03061            id -- ID
03062 
03063        contents:
03064            annotation?, (restriction | list | union)
03065     """
03066     required = []
03067     attributes = {'id':None}
03068     tag = 'simpleType'
03069 
03070 
03071 class Redefine:
03072     """<redefine>
03073        parents:
03074        attributes:
03075 
03076        contents:
03077     """
03078     tag = 'redefine'
03079 
03080 
03081 ###########################
03082 ###########################
03083 
03084 
03085 if sys.version_info[:2] >= (2, 2):
03086     tupleClass = tuple
03087 else:
03088     import UserTuple
03089     tupleClass = UserTuple.UserTuple
03090 
03091 class TypeDescriptionComponent(tupleClass):
03092     """Tuple of length 2, consisting of
03093        a namespace and unprefixed name.
03094     """
03095     def __init__(self, args):
03096         """args -- (namespace, name)
03097            Remove the name's prefix, irrelevant.
03098         """
03099         if len(args) != 2:
03100             raise TypeError, 'expecting tuple (namespace, name), got %s' %args
03101         elif args[1].find(':') >= 0:
03102             args = (args[0], SplitQName(args[1])[1])
03103         tuple.__init__(self, args)
03104         return
03105 
03106     def getTargetNamespace(self):
03107         return self[0]
03108 
03109     def getName(self):
03110         return self[1]
03111 
03112 

Generated on Wed Oct 20 2010 11:12:16 for APBS by  doxygen 1.7.2