00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
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
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
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
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
00616
00617 return
00618
00619 raise SchemaError, 'schema "%s" does not import namespace "%s"' %(
00620 parent.targetNamespace, namespace)
00621
00622
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
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
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
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
00785 if type(v) is dict:
00786 continue
00787
00788
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
00877 continue
00878 elif component == 'appinfo':
00879
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
00913 continue
00914 elif component == 'any':
00915
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
00948 continue
00949 elif component == 'any':
00950
00951 continue
00952 else:
00953 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
00954 self.content = tuple(content)
00955
00956
00957 class XMLSchemaFake:
00958
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
01216
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
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
01254
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
01416
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
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
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
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
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