1 # Copyright (c) 2003, The Regents of the University of California,
2 # through Lawrence Berkeley National Laboratory (subject to receipt of
3 # any required approvals from the U.S. Dept. of Energy). All rights
6 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
8 # This software is subject to the provisions of the Zope Public License,
9 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
10 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
11 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
13 # FOR A PARTICULAR PURPOSE.
17 import types, weakref, sys, warnings
18 from Namespaces import SCHEMA, XMLNS, SOAP, APACHE
19 from Utility import DOM, DOMException, Collection, SplitQName, basejoin
20 from StringIO import StringIO
22 # If we have no threading, this should be a no-op
24 from threading import RLock
33 # Collections in XMLSchema class
36 ATTRIBUTE_GROUPS = 'attr_groups'
37 ATTRIBUTES = 'attr_decl'
39 MODEL_GROUPS = 'model_groups'
40 BUILT_IN_NAMESPACES = [SOAP.ENC,] + SCHEMA.XSD_LIST + [APACHE.AXIS_NS]
42 def GetSchema(component):
43 """convience function for finding the parent XMLSchema instance.
46 while not isinstance(parent, XMLSchema):
47 parent = parent._parent()
51 """A SchemaReader creates XMLSchema objects from urls and xml data.
54 namespaceToSchema = {}
56 def __init__(self, domReader=None, base_url=None):
57 """domReader -- class must implement DOMAdapterInterface
58 base_url -- base url string
60 self.__base_url = base_url
61 self.__readerClass = domReader
62 if not self.__readerClass:
63 self.__readerClass = DOMAdapter
67 def __setImports(self, schema):
68 """Add dictionary of imports to schema instance.
69 schema -- XMLSchema instance
71 for ns,val in schema.imports.items():
72 if self._imports.has_key(ns):
73 schema.addImportSchema(self._imports[ns])
75 def __setIncludes(self, schema):
76 """Add dictionary of includes to schema instance.
77 schema -- XMLSchema instance
79 for schemaLocation, val in schema.includes.items():
80 if self._includes.has_key(schemaLocation):
81 schema.addIncludeSchema(schemaLocation, self._imports[schemaLocation])
83 def addSchemaByLocation(self, location, schema):
84 """provide reader with schema document for a location.
86 self._includes[location] = schema
88 def addSchemaByNamespace(self, schema):
89 """provide reader with schema document for a targetNamespace.
91 self._imports[schema.targetNamespace] = schema
93 def loadFromNode(self, parent, element):
94 """element -- DOM node or document
95 parent -- WSDLAdapter instance
97 reader = self.__readerClass(element)
98 schema = XMLSchema(parent)
99 #HACK to keep a reference
101 schema.setBaseUrl(self.__base_url)
105 def loadFromStream(self, file, url=None):
106 """Return an XMLSchema instance loaded from a file object.
108 url -- base location for resolving imports/includes.
110 reader = self.__readerClass()
111 reader.loadDocument(file)
114 schema.setBaseUrl(url)
116 self.__setIncludes(schema)
117 self.__setImports(schema)
120 def loadFromString(self, data):
121 """Return an XMLSchema instance loaded from an XML string.
124 return self.loadFromStream(StringIO(data))
126 def loadFromURL(self, url, schema=None):
127 """Return an XMLSchema instance loaded from the given url.
128 url -- URL to dereference
129 schema -- Optional XMLSchema instance.
131 reader = self.__readerClass()
133 url = basejoin(self.__base_url,url)
135 reader.loadFromURL(url)
136 schema = schema or XMLSchema()
137 schema.setBaseUrl(url)
139 self.__setIncludes(schema)
140 self.__setImports(schema)
143 def loadFromFile(self, filename):
144 """Return an XMLSchema instance loaded from the given file.
145 filename -- name of file to open
148 filename = basejoin(self.__base_url,filename)
149 file = open(filename, 'rb')
151 schema = self.loadFromStream(file, filename)
158 class SchemaError(Exception):
161 class NoSchemaLocationWarning(Exception):
165 ###########################
166 # DOM Utility Adapters
167 ##########################
168 class DOMAdapterInterface:
169 def hasattr(self, attr, ns=None):
170 """return true if node has attribute
171 attr -- attribute to check for
172 ns -- namespace of attribute, by default None
174 raise NotImplementedError, 'adapter method not implemented'
176 def getContentList(self, *contents):
177 """returns an ordered list of child nodes
178 *contents -- list of node names to return
180 raise NotImplementedError, 'adapter method not implemented'
182 def setAttributeDictionary(self, attributes):
183 """set attribute dictionary
185 raise NotImplementedError, 'adapter method not implemented'
187 def getAttributeDictionary(self):
188 """returns a dict of node's attributes
190 raise NotImplementedError, 'adapter method not implemented'
192 def getNamespace(self, prefix):
193 """returns namespace referenced by prefix.
195 raise NotImplementedError, 'adapter method not implemented'
197 def getTagName(self):
198 """returns tagName of node
200 raise NotImplementedError, 'adapter method not implemented'
203 def getParentNode(self):
204 """returns parent element in DOMAdapter or None
206 raise NotImplementedError, 'adapter method not implemented'
208 def loadDocument(self, file):
209 """load a Document from a file object
212 raise NotImplementedError, 'adapter method not implemented'
214 def loadFromURL(self, url):
215 """load a Document from an url
216 url -- URL to dereference
218 raise NotImplementedError, 'adapter method not implemented'
221 class DOMAdapter(DOMAdapterInterface):
222 """Adapter for ZSI.Utility.DOM
224 def __init__(self, node=None):
225 """Reset all instance variables.
226 element -- DOM document, node, or None
228 if hasattr(node, 'documentElement'):
229 self.__node = node.documentElement
232 self.__attributes = None
237 def hasattr(self, attr, ns=None):
239 ns -- optional namespace, None means unprefixed attribute.
241 if not self.__attributes:
242 self.setAttributeDictionary()
244 return self.__attributes.get(ns,{}).has_key(attr)
245 return self.__attributes.has_key(attr)
247 def getContentList(self, *contents):
249 ELEMENT_NODE = self.__node.ELEMENT_NODE
250 for child in DOM.getElements(self.__node, None):
251 if child.nodeType == ELEMENT_NODE and\
252 SplitQName(child.tagName)[1] in contents:
254 return map(self.__class__, nodes)
256 def setAttributeDictionary(self):
257 self.__attributes = {}
258 for v in self.__node._attrs.values():
259 self.__attributes[v.nodeName] = v.nodeValue
261 def getAttributeDictionary(self):
262 if not self.__attributes:
263 self.setAttributeDictionary()
264 return self.__attributes
266 def getTagName(self):
267 return self.__node.tagName
269 def getParentNode(self):
270 if self.__node.parentNode.nodeType == self.__node.ELEMENT_NODE:
271 return DOMAdapter(self.__node.parentNode)
274 def getNamespace(self, prefix):
275 """prefix -- deference namespace prefix in node's context.
276 Ascends parent nodes until found.
279 if prefix == 'xmlns':
280 namespace = DOM.findDefaultNS(prefix, self.__node)
283 namespace = DOM.findNamespaceURI(prefix, self.__node)
284 except DOMException, ex:
286 raise SchemaError, '%s namespace not declared for %s'\
287 %(prefix, self.__node._get_tagName())
288 namespace = XMLNS.XML
291 def loadDocument(self, file):
292 self.__node = DOM.loadDocument(file)
293 if hasattr(self.__node, 'documentElement'):
294 self.__node = self.__node.documentElement
296 def loadFromURL(self, url):
297 self.__node = DOM.loadFromURL(url)
298 if hasattr(self.__node, 'documentElement'):
299 self.__node = self.__node.documentElement
303 """ These class variables are for string indentation.
310 XMLBase.__rlock.acquire()
311 XMLBase.__indent += 1
312 tmp = "<" + str(self.__class__) + '>\n'
313 for k,v in self.__dict__.items():
314 tmp += "%s* %s = %s\n" %(XMLBase.__indent*' ', k, v)
315 XMLBase.__indent -= 1
316 XMLBase.__rlock.release()
320 """Marker Interface: can determine something about an instances properties by using
321 the provided convenience functions.
324 class DefinitionMarker:
325 """marker for definitions
329 class DeclarationMarker:
330 """marker for declarations
334 class AttributeMarker:
335 """marker for attributes
339 class AttributeGroupMarker:
340 """marker for attribute groups
344 class WildCardMarker:
345 """marker for wildcards
350 """marker for wildcards
354 class ReferenceMarker:
355 """marker for references
359 class ModelGroupMarker:
360 """marker for model groups
364 class AllMarker(ModelGroupMarker):
365 """marker for all model group
369 class ChoiceMarker(ModelGroupMarker):
370 """marker for choice model group
374 class SequenceMarker(ModelGroupMarker):
375 """marker for sequence model group
379 class ExtensionMarker:
380 """marker for extensions
384 class RestrictionMarker:
385 """marker for restrictions
387 facets = ['enumeration', 'length', 'maxExclusive', 'maxInclusive',\
388 'maxLength', 'minExclusive', 'minInclusive', 'minLength',\
389 'pattern', 'fractionDigits', 'totalDigits', 'whiteSpace']
392 """marker for simple type information
397 """marker for simple type list
402 """marker for simple type Union
408 """marker for complex type information
413 """marker for complex type information
418 class MarkerInterface:
419 def isDefinition(self):
420 return isinstance(self, DefinitionMarker)
422 def isDeclaration(self):
423 return isinstance(self, DeclarationMarker)
425 def isAttribute(self):
426 return isinstance(self, AttributeMarker)
428 def isAttributeGroup(self):
429 return isinstance(self, AttributeGroupMarker)
432 return isinstance(self, ElementMarker)
434 def isReference(self):
435 return isinstance(self, ReferenceMarker)
437 def isWildCard(self):
438 return isinstance(self, WildCardMarker)
440 def isModelGroup(self):
441 return isinstance(self, ModelGroupMarker)
444 return isinstance(self, AllMarker)
447 return isinstance(self, ChoiceMarker)
449 def isSequence(self):
450 return isinstance(self, SequenceMarker)
452 def isExtension(self):
453 return isinstance(self, ExtensionMarker)
455 def isRestriction(self):
456 return isinstance(self, RestrictionMarker)
459 return isinstance(self, SimpleMarker)
462 return isinstance(self, ComplexMarker)
465 return isinstance(self, LocalMarker)
468 return isinstance(self, ListMarker)
471 return isinstance(self, UnionMarker)
474 ##########################################################
476 #########################################################
477 class XMLSchemaComponent(XMLBase, MarkerInterface):
480 required -- list of required attributes
481 attributes -- dict of default attribute values, including None.
482 Value can be a function for runtime dependencies.
483 contents -- dict of namespace keyed content lists.
484 'xsd' content of xsd namespace.
485 xmlns_key -- key for declared xmlns namespace.
486 xmlns -- xmlns is special prefix for namespace dictionary
487 xml -- special xml prefix for xml namespace.
496 def __init__(self, parent=None):
497 """parent -- parent instance
499 attributes -- dictionary of node's attributes
501 self.attributes = None
502 self._parent = parent
504 self._parent = weakref.ref(parent)
506 if not self.__class__ == XMLSchemaComponent\
507 and not (type(self.__class__.required) == type(XMLSchemaComponent.required)\
508 and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)\
509 and type(self.__class__.contents) == type(XMLSchemaComponent.contents)):
510 raise RuntimeError, 'Bad type for a class variable in %s' %self.__class__
512 def getItemTrace(self):
513 """Returns a node trace up to the <schema> item.
515 item, path, name, ref = self, [], 'name', 'ref'
516 while not isinstance(item,XMLSchema) and not isinstance(item,WSDLToolsAdapter):
517 attr = item.getAttribute(name)
519 attr = item.getAttribute(ref)
521 path.append('<%s>' %(item.tag))
523 path.append('<%s ref="%s">' %(item.tag, attr))
525 path.append('<%s name="%s">' %(item.tag,attr))
527 item = item._parent()
529 tns = item.getTargetNamespace()
532 path.append('<%s targetNamespace="%s">' %(item.tag, tns))
536 def getTargetNamespace(self):
537 """return targetNamespace
540 targetNamespace = 'targetNamespace'
541 tns = self.attributes.get(targetNamespace)
542 while not tns and parent and parent._parent is not None:
543 parent = parent._parent()
544 tns = parent.attributes.get(targetNamespace)
547 def getAttributeDeclaration(self, attribute):
548 """attribute -- attribute with a QName value (eg. type).
549 collection -- check types collection in parent Schema instance
551 return self.getQNameAttribute(ATTRIBUTES, attribute)
553 def getAttributeGroup(self, attribute):
554 """attribute -- attribute with a QName value (eg. type).
555 collection -- check types collection in parent Schema instance
557 return self.getQNameAttribute(ATTRIBUTE_GROUPS, attribute)
559 def getTypeDefinition(self, attribute):
560 """attribute -- attribute with a QName value (eg. type).
561 collection -- check types collection in parent Schema instance
563 return self.getQNameAttribute(TYPES, attribute)
565 def getElementDeclaration(self, attribute):
566 """attribute -- attribute with a QName value (eg. element).
567 collection -- check elements collection in parent Schema instance.
569 return self.getQNameAttribute(ELEMENTS, attribute)
571 def getModelGroup(self, attribute):
572 """attribute -- attribute with a QName value (eg. ref).
573 collection -- check model_group collection in parent Schema instance.
575 return self.getQNameAttribute(MODEL_GROUPS, attribute)
577 def getQNameAttribute(self, collection, attribute):
578 """returns object instance representing QName --> (namespace,name),
579 or if does not exist return None.
580 attribute -- an information item attribute, with a QName value.
581 collection -- collection in parent Schema instance to search.
583 tdc = self.getAttributeQName(attribute)
587 obj = self.getSchemaItem(collection, tdc.getTargetNamespace(), tdc.getName())
591 # raise SchemaError, 'No schema item "%s" in collection %s' %(tdc, collection)
594 def getSchemaItem(self, collection, namespace, name):
595 """returns object instance representing namespace, name,
596 or if does not exist return None if built-in, else
599 namespace -- namespace item defined in.
600 name -- name of item.
601 collection -- collection in parent Schema instance to search.
603 parent = GetSchema(self)
604 if parent.targetNamespace == namespace:
606 obj = getattr(parent, collection)[name]
608 raise KeyError, 'targetNamespace(%s) collection(%s) has no item(%s)'\
609 %(namespace, collection, name)
613 if not parent.imports.has_key(namespace):
614 if namespace in BUILT_IN_NAMESPACES:
615 # built-in just return
616 # WARNING: expecting import if "redefine" or add to built-in namespace.
619 raise SchemaError, 'schema "%s" does not import namespace "%s"' %(
620 parent.targetNamespace, namespace)
623 schema = parent.imports[namespace]
624 if not isinstance(schema, XMLSchema):
625 schema = schema.getSchema()
626 if schema is not None:
627 parent.imports[namespace] = schema
630 if namespace in BUILT_IN_NAMESPACES:
631 # built-in just return
634 raise SchemaError, 'no schema instance for imported namespace (%s).'\
637 if not isinstance(schema, XMLSchema):
638 raise TypeError, 'expecting XMLSchema instance not "%r"' %schema
641 obj = getattr(schema, collection)[name]
643 raise KeyError, 'targetNamespace(%s) collection(%s) has no item(%s)'\
644 %(namespace, collection, name)
648 def getXMLNS(self, prefix=None):
649 """deference prefix or by default xmlns, returns namespace.
651 if prefix == XMLSchemaComponent.xml:
654 ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix or\
655 XMLSchemaComponent.xmlns_key)
657 parent = parent._parent()
658 ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or\
659 XMLSchemaComponent.xmlns_key)
660 if not ns and isinstance(parent, WSDLToolsAdapter):
663 raise SchemaError, 'unknown prefix %s' %prefix
666 def getAttribute(self, attribute):
667 """return requested attribute value or None
669 if type(attribute) in (list, tuple):
670 if len(attribute) != 2:
671 raise LookupError, 'To access attributes must use name or (namespace,name)'
673 ns_dict = self.attributes.get(attribute[0])
677 return ns_dict.get(attribute[1])
679 return self.attributes.get(attribute)
681 def getAttributeQName(self, attribute):
682 """return requested attribute value as (namespace,name) or None
684 qname = self.getAttribute(attribute)
685 if isinstance(qname, TypeDescriptionComponent) is True:
690 prefix,ncname = SplitQName(qname)
691 namespace = self.getXMLNS(prefix)
692 return TypeDescriptionComponent((namespace,ncname))
694 def getAttributeName(self):
695 """return attribute name or None
697 return self.getAttribute('name')
699 def setAttributes(self, node):
700 """Sets up attribute dictionary, checks for required attributes and
701 sets default attribute values. attr is for default attribute values
702 determined at runtime.
704 structure of attributes dictionary
705 ['xmlns'][xmlns_key] -- xmlns namespace
706 ['xmlns'][prefix] -- declared namespace prefix
707 [namespace][prefix] -- attributes declared in a namespace
708 [attribute] -- attributes w/o prefix, default namespaces do
709 not directly apply to attributes, ie Name can't collide
712 self.attributes = {XMLSchemaComponent.xmlns:{}}
713 for k,v in node.getAttributeDictionary().items():
714 prefix,value = SplitQName(k)
715 if value == XMLSchemaComponent.xmlns:
716 self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v
718 ns = node.getNamespace(prefix)
720 raise SchemaError, 'no namespace for attribute prefix %s'\
722 if not self.attributes.has_key(ns):
723 self.attributes[ns] = {}
724 elif self.attributes[ns].has_key(value):
725 raise SchemaError, 'attribute %s declared multiple times in %s'\
727 self.attributes[ns][value] = v
728 elif not self.attributes.has_key(value):
729 self.attributes[value] = v
731 raise SchemaError, 'attribute %s declared multiple times' %value
733 if not isinstance(self, WSDLToolsAdapter):
734 self.__checkAttributes()
735 self.__setAttributeDefaults()
738 for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']:
739 if self.attributes.has_key(k):
740 prefix, value = SplitQName(self.attributes.get(k))
741 self.attributes[k] = \
742 TypeDescriptionComponent((self.getXMLNS(prefix), value))
744 #Union, memberTypes is a whitespace separated list of QNames
745 for k in ['memberTypes']:
746 if self.attributes.has_key(k):
747 qnames = self.attributes[k]
748 self.attributes[k] = []
749 for qname in qnames.split():
750 prefix, value = SplitQName(qname)
751 self.attributes['memberTypes'].append(\
752 TypeDescriptionComponent(\
753 (self.getXMLNS(prefix), value)))
755 def getContents(self, node):
756 """retrieve xsd contents
758 return node.getContentList(*self.__class__.contents['xsd'])
760 def __setAttributeDefaults(self):
761 """Looks for default values for unset attributes. If
762 class variable representing attribute is None, then
763 it must be defined as an instance variable.
765 for k,v in self.__class__.attributes.items():
766 if v is not None and self.attributes.has_key(k) is False:
767 if isinstance(v, types.FunctionType):
768 self.attributes[k] = v(self)
770 self.attributes[k] = v
772 def __checkAttributes(self):
773 """Checks that required attributes have been defined,
774 attributes w/default cannot be required. Checks
775 all defined attributes are legal, attribute
776 references are not subject to this test.
778 for a in self.__class__.required:
779 if not self.attributes.has_key(a):
781 'class instance %s, missing required attribute %s'\
783 for a,v in self.attributes.items():
784 # attribute #other, ie. not in empty namespace
788 # predefined prefixes xmlns, xml
789 if a in (XMLSchemaComponent.xmlns, XMLNS.XML):
792 if (a not in self.__class__.attributes.keys()) and not\
793 (self.isAttribute() and self.isReference()):
794 raise SchemaError, '%s, unknown attribute(%s,%s)' \
795 %(self.getItemTrace(), a, self.attributes[a])
798 class WSDLToolsAdapter(XMLSchemaComponent):
799 """WSDL Adapter to grab the attributes from the wsdl document node.
801 attributes = {'name':None, 'targetNamespace':None}
804 def __init__(self, wsdl):
805 XMLSchemaComponent.__init__(self, parent=wsdl)
806 self.setAttributes(DOMAdapter(wsdl.document))
808 def getImportSchemas(self):
809 """returns WSDLTools.WSDL types Collection
811 return self._parent().types
814 class Notation(XMLSchemaComponent):
820 name -- NCName, Required
821 public -- token, Required
826 required = ['name', 'public']
827 attributes = {'id':None, 'name':None, 'public':None, 'system':None}
828 contents = {'xsd':('annotation')}
831 def __init__(self, parent):
832 XMLSchemaComponent.__init__(self, parent)
833 self.annotation = None
835 def fromDom(self, node):
836 self.setAttributes(node)
837 contents = self.getContents(node)
840 component = SplitQName(i.getTagName())[1]
841 if component == 'annotation' and not self.annotation:
842 self.annotation = Annotation(self)
843 self.annotation.fromDom(i)
845 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
848 class Annotation(XMLSchemaComponent):
851 all,any,anyAttribute,attribute,attributeGroup,choice,complexContent,
852 complexType,element,extension,field,group,import,include,key,keyref,
853 list,notation,redefine,restriction,schema,selector,simpleContent,
854 simpleType,union,unique
858 (documentation | appinfo)*
860 attributes = {'id':None}
861 contents = {'xsd':('documentation', 'appinfo')}
864 def __init__(self, parent):
865 XMLSchemaComponent.__init__(self, parent)
868 def fromDom(self, node):
869 self.setAttributes(node)
870 contents = self.getContents(node)
874 component = SplitQName(i.getTagName())[1]
875 if component == 'documentation':
876 #print_debug('class %s, documentation skipped' %self.__class__, 5)
878 elif component == 'appinfo':
879 #print_debug('class %s, appinfo skipped' %self.__class__, 5)
882 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
883 self.content = tuple(content)
886 class Documentation(XMLSchemaComponent):
896 attributes = {'source':None, 'xml:lang':None}
897 contents = {'xsd':('mixed', 'any')}
898 tag = 'documentation'
900 def __init__(self, parent):
901 XMLSchemaComponent.__init__(self, parent)
904 def fromDom(self, node):
905 self.setAttributes(node)
906 contents = self.getContents(node)
910 component = SplitQName(i.getTagName())[1]
911 if component == 'mixed':
912 #print_debug('class %s, mixed skipped' %self.__class__, 5)
914 elif component == 'any':
915 #print_debug('class %s, any skipped' %self.__class__, 5)
918 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
919 self.content = tuple(content)
922 class Appinfo(XMLSchemaComponent):
931 attributes = {'source':None, 'anyURI':None}
932 contents = {'xsd':('mixed', 'any')}
935 def __init__(self, parent):
936 XMLSchemaComponent.__init__(self, parent)
939 def fromDom(self, node):
940 self.setAttributes(node)
941 contents = self.getContents(node)
945 component = SplitQName(i.getTagName())[1]
946 if component == 'mixed':
947 #print_debug('class %s, mixed skipped' %self.__class__, 5)
949 elif component == 'any':
950 #print_debug('class %s, any skipped' %self.__class__, 5)
953 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
954 self.content = tuple(content)
958 # This is temporary, for the benefit of WSDL until the real thing works.
959 def __init__(self, element):
960 self.targetNamespace = DOM.getAttr(element, 'targetNamespace')
961 self.element = element
963 class XMLSchema(XMLSchemaComponent):
964 """A schema is a collection of schema components derived from one
965 or more schema documents, that is, one or more <schema> element
966 information items. It represents the abstract notion of a schema
967 rather than a single schema document (or other representation).
976 targetNamespace -- anyURI
977 attributeFormDefault -- 'qualified' | 'unqualified', 'unqualified'
978 elementFormDefault -- 'qualified' | 'unqualified', 'unqualified'
979 blockDefault -- '#all' | list of
980 ('substitution | 'extension' | 'restriction')
981 finalDefault -- '#all' | list of
982 ('extension' | 'restriction' | 'list' | 'union')
985 ((include | import | redefine | annotation)*,
986 (attribute, attributeGroup, complexType, element, group,
987 notation, simpleType)*, annotation*)*
990 attributes -- schema attributes
991 imports -- import statements
992 includes -- include statements
994 types -- global simpleType, complexType definitions
995 elements -- global element declarations
996 attr_decl -- global attribute declarations
997 attr_groups -- attribute Groups
998 model_groups -- model Groups
999 notations -- global notations
1001 attributes = {'id':None,
1004 'targetNamespace':None,
1005 'attributeFormDefault':'unqualified',
1006 'elementFormDefault':'unqualified',
1007 'blockDefault':None,
1008 'finalDefault':None}
1009 contents = {'xsd':('include', 'import', 'redefine', 'annotation',
1010 'attribute', 'attributeGroup', 'complexType',
1011 'element', 'group', 'notation', 'simpleType',
1013 empty_namespace = ''
1016 def __init__(self, parent=None):
1019 targetNamespace -- schema's declared targetNamespace, or empty string.
1020 _imported_schemas -- namespace keyed dict of schema dependencies, if
1021 a schema is provided instance will not resolve import statement.
1022 _included_schemas -- schemaLocation keyed dict of component schemas,
1023 if schema is provided instance will not resolve include statement.
1024 _base_url -- needed for relative URLs support, only works with URLs
1025 relative to initial document.
1026 includes -- collection of include statements
1027 imports -- collection of import statements
1028 elements -- collection of global element declarations
1029 types -- collection of global type definitions
1030 attr_decl -- collection of global attribute declarations
1031 attr_groups -- collection of global attribute group definitions
1032 model_groups -- collection of model group definitions
1033 notations -- collection of notations
1037 self.targetNamespace = None
1038 XMLSchemaComponent.__init__(self, parent)
1039 f = lambda k: k.attributes['name']
1040 ns = lambda k: k.attributes['namespace']
1041 sl = lambda k: k.attributes['schemaLocation']
1042 self.includes = Collection(self, key=sl)
1043 self.imports = Collection(self, key=ns)
1044 self.elements = Collection(self, key=f)
1045 self.types = Collection(self, key=f)
1046 self.attr_decl = Collection(self, key=f)
1047 self.attr_groups = Collection(self, key=f)
1048 self.model_groups = Collection(self, key=f)
1049 self.notations = Collection(self, key=f)
1051 self._imported_schemas = {}
1052 self._included_schemas = {}
1053 self._base_url = None
1057 Interacting with the underlying DOM tree.
1061 def addImportSchema(self, schema):
1062 """for resolving import statements in Schema instance
1063 schema -- schema instance
1066 if not isinstance(schema, XMLSchema):
1067 raise TypeError, 'expecting a Schema instance'
1068 if schema.targetNamespace != self.targetNamespace:
1069 self._imported_schemas[schema.targetNamespace] = schema
1071 raise SchemaError, 'import schema bad targetNamespace'
1073 def addIncludeSchema(self, schemaLocation, schema):
1074 """for resolving include statements in Schema instance
1075 schemaLocation -- schema location
1076 schema -- schema instance
1079 if not isinstance(schema, XMLSchema):
1080 raise TypeError, 'expecting a Schema instance'
1081 if not schema.targetNamespace or\
1082 schema.targetNamespace == self.targetNamespace:
1083 self._included_schemas[schemaLocation] = schema
1085 raise SchemaError, 'include schema bad targetNamespace'
1087 def setImportSchemas(self, schema_dict):
1088 """set the import schema dictionary, which is used to
1089 reference depedent schemas.
1091 self._imported_schemas = schema_dict
1093 def getImportSchemas(self):
1094 """get the import schema dictionary, which is used to
1095 reference depedent schemas.
1097 return self._imported_schemas
1099 def getSchemaNamespacesToImport(self):
1100 """returns tuple of namespaces the schema instance has declared
1101 itself to be depedent upon.
1103 return tuple(self.includes.keys())
1105 def setIncludeSchemas(self, schema_dict):
1106 """set the include schema dictionary, which is keyed with
1107 schemaLocation (uri).
1108 This is a means of providing
1109 schemas to the current schema for content inclusion.
1111 self._included_schemas = schema_dict
1113 def getIncludeSchemas(self):
1114 """get the include schema dictionary, which is keyed with
1115 schemaLocation (uri).
1117 return self._included_schemas
1119 def getBaseUrl(self):
1120 """get base url, used for normalizing all relative uri's
1122 return self._base_url
1124 def setBaseUrl(self, url):
1125 """set base url, used for normalizing all relative uri's
1127 self._base_url = url
1129 def getElementFormDefault(self):
1130 """return elementFormDefault attribute
1132 return self.attributes.get('elementFormDefault')
1134 def isElementFormDefaultQualified(self):
1135 return self.attributes.get('elementFormDefault') == 'qualified'
1137 def getAttributeFormDefault(self):
1138 """return attributeFormDefault attribute
1140 return self.attributes.get('attributeFormDefault')
1142 def getBlockDefault(self):
1143 """return blockDefault attribute
1145 return self.attributes.get('blockDefault')
1147 def getFinalDefault(self):
1148 """return finalDefault attribute
1150 return self.attributes.get('finalDefault')
1152 def load(self, node, location=None):
1155 pnode = node.getParentNode()
1157 pname = SplitQName(pnode.getTagName())[1]
1158 if pname == 'types':
1160 self.setAttributes(pnode)
1161 attributes.update(self.attributes)
1162 self.setAttributes(node)
1163 for k,v in attributes['xmlns'].items():
1164 if not self.attributes['xmlns'].has_key(k):
1165 self.attributes['xmlns'][k] = v
1167 self.setAttributes(node)
1169 self.setAttributes(node)
1171 self.targetNamespace = self.getTargetNamespace()
1172 for childNode in self.getContents(node):
1173 component = SplitQName(childNode.getTagName())[1]
1175 if component == 'include':
1176 tp = self.__class__.Include(self)
1177 tp.fromDom(childNode)
1179 sl = tp.attributes['schemaLocation']
1180 schema = tp.getSchema()
1182 if not self.getIncludeSchemas().has_key(sl):
1183 self.addIncludeSchema(sl, schema)
1185 self.includes[sl] = tp
1187 pn = childNode.getParentNode().getNode()
1188 pn.removeChild(childNode.getNode())
1189 for child in schema.getNode().getNode().childNodes:
1190 pn.appendChild(child.cloneNode(1))
1192 for collection in ['imports','elements','types',
1193 'attr_decl','attr_groups','model_groups',
1195 for k,v in getattr(schema,collection).items():
1196 if not getattr(self,collection).has_key(k):
1197 v._parent = weakref.ref(self)
1198 getattr(self,collection)[k] = v
1200 warnings.warn("Not keeping schema component.")
1202 elif component == 'import':
1203 slocd = SchemaReader.namespaceToSchema
1204 tp = self.__class__.Import(self)
1205 tp.fromDom(childNode)
1206 import_ns = tp.getAttribute('namespace') or\
1207 self.__class__.empty_namespace
1208 schema = slocd.get(import_ns)
1210 schema = XMLSchema()
1211 slocd[import_ns] = schema
1213 tp.loadSchema(schema)
1214 except NoSchemaLocationWarning, ex:
1215 # Dependency declaration, hopefully implementation
1216 # is aware of this namespace (eg. SOAP,WSDL,?)
1217 print "IMPORT: ", import_ns
1219 del slocd[import_ns]
1221 except SchemaError, ex:
1223 # '<import namespace="%s" schemaLocation=?>, %s'\
1224 # %(import_ns, 'failed to load schema instance')
1227 del slocd[import_ns]
1228 class _LazyEvalImport(str):
1229 '''Lazy evaluation of import, replace entry in self.imports.'''
1230 #attributes = dict(namespace=import_ns)
1231 def getSchema(namespace):
1232 schema = slocd.get(namespace)
1234 parent = self._parent()
1236 if isinstance(parent, WSDLToolsAdapter):
1237 wstypes = parent.getImportSchemas()
1238 schema = wstypes.get(namespace)
1239 if isinstance(schema, XMLSchema):
1240 self.imports[namespace] = schema
1245 self.imports[import_ns] = _LazyEvalImport(import_ns)
1250 if self.getImportSchemas().has_key(import_ns):
1252 'Detected multiple imports of the namespace "%s" '\
1255 self.addImportSchema(schema)
1256 # spec says can have multiple imports of same namespace
1257 # but purpose of import is just dependency declaration.
1258 self.imports[import_ns] = tp
1260 elif component == 'redefine':
1261 warnings.warn('redefine is ignored')
1262 elif component == 'annotation':
1263 warnings.warn('annotation is ignored')
1264 elif component == 'attribute':
1265 tp = AttributeDeclaration(self)
1266 tp.fromDom(childNode)
1267 self.attr_decl[tp.getAttribute('name')] = tp
1268 elif component == 'attributeGroup':
1269 tp = AttributeGroupDefinition(self)
1270 tp.fromDom(childNode)
1271 self.attr_groups[tp.getAttribute('name')] = tp
1272 elif component == 'element':
1273 tp = ElementDeclaration(self)
1274 tp.fromDom(childNode)
1275 self.elements[tp.getAttribute('name')] = tp
1276 elif component == 'group':
1277 tp = ModelGroupDefinition(self)
1278 tp.fromDom(childNode)
1279 self.model_groups[tp.getAttribute('name')] = tp
1280 elif component == 'notation':
1282 tp.fromDom(childNode)
1283 self.notations[tp.getAttribute('name')] = tp
1284 elif component == 'complexType':
1285 tp = ComplexType(self)
1286 tp.fromDom(childNode)
1287 self.types[tp.getAttribute('name')] = tp
1288 elif component == 'simpleType':
1289 tp = SimpleType(self)
1290 tp.fromDom(childNode)
1291 self.types[tp.getAttribute('name')] = tp
1295 class Import(XMLSchemaComponent):
1302 schemaLocation -- anyURI
1306 attributes = {'id':None,
1308 'schemaLocation':None}
1309 contents = {'xsd':['annotation']}
1312 def __init__(self, parent):
1313 XMLSchemaComponent.__init__(self, parent)
1314 self.annotation = None
1317 def fromDom(self, node):
1318 self.setAttributes(node)
1319 contents = self.getContents(node)
1321 if self.attributes['namespace'] == self.getTargetNamespace():
1322 raise SchemaError, 'namespace of schema and import match'
1325 component = SplitQName(i.getTagName())[1]
1326 if component == 'annotation' and not self.annotation:
1327 self.annotation = Annotation(self)
1328 self.annotation.fromDom(i)
1330 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1332 def getSchema(self):
1333 """if schema is not defined, first look for a Schema class instance
1334 in parent Schema. Else if not defined resolve schemaLocation
1335 and create a new Schema class instance, and keep a hard reference.
1337 if not self._schema:
1338 ns = self.attributes['namespace']
1339 schema = self._parent().getImportSchemas().get(ns)
1340 if not schema and self._parent()._parent:
1341 schema = self._parent()._parent().getImportSchemas().get(ns)
1344 url = self.attributes.get('schemaLocation')
1346 raise SchemaError, 'namespace(%s) is unknown' %ns
1347 base_url = self._parent().getBaseUrl()
1348 reader = SchemaReader(base_url=base_url)
1349 reader._imports = self._parent().getImportSchemas()
1350 reader._includes = self._parent().getIncludeSchemas()
1351 self._schema = reader.loadFromURL(url)
1352 return self._schema or schema
1354 def loadSchema(self, schema):
1357 base_url = self._parent().getBaseUrl()
1358 reader = SchemaReader(base_url=base_url)
1359 reader._imports = self._parent().getImportSchemas()
1360 reader._includes = self._parent().getIncludeSchemas()
1361 self._schema = schema
1363 if not self.attributes.has_key('schemaLocation'):
1364 raise NoSchemaLocationWarning('no schemaLocation attribute in import')
1366 reader.loadFromURL(self.attributes.get('schemaLocation'), schema)
1369 class Include(XMLSchemaComponent):
1370 """<include schemaLocation>
1375 schemaLocation -- anyURI, required
1379 required = ['schemaLocation']
1380 attributes = {'id':None,
1381 'schemaLocation':None}
1382 contents = {'xsd':['annotation']}
1385 def __init__(self, parent):
1386 XMLSchemaComponent.__init__(self, parent)
1387 self.annotation = None
1390 def fromDom(self, node):
1391 self.setAttributes(node)
1392 contents = self.getContents(node)
1395 component = SplitQName(i.getTagName())[1]
1396 if component == 'annotation' and not self.annotation:
1397 self.annotation = Annotation(self)
1398 self.annotation.fromDom(i)
1400 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1402 def getSchema(self):
1403 """if schema is not defined, first look for a Schema class instance
1404 in parent Schema. Else if not defined resolve schemaLocation
1405 and create a new Schema class instance.
1407 if not self._schema:
1408 schema = self._parent()
1409 self._schema = schema.getIncludeSchemas().get(\
1410 self.attributes['schemaLocation']
1412 if not self._schema:
1413 url = self.attributes['schemaLocation']
1414 reader = SchemaReader(base_url=schema.getBaseUrl())
1415 reader._imports = schema.getImportSchemas()
1416 reader._includes = schema.getIncludeSchemas()
1418 # create schema before loading so chameleon include
1419 # will evalute targetNamespace correctly.
1420 self._schema = XMLSchema(schema)
1421 reader.loadFromURL(url, self._schema)
1426 class AttributeDeclaration(XMLSchemaComponent,\
1434 name -- NCName, required
1439 annotation?, simpleType?
1442 attributes = {'id':None,
1447 contents = {'xsd':['annotation','simpleType']}
1450 def __init__(self, parent):
1451 XMLSchemaComponent.__init__(self, parent)
1452 self.annotation = None
1455 def fromDom(self, node):
1456 """ No list or union support
1458 self.setAttributes(node)
1459 contents = self.getContents(node)
1462 component = SplitQName(i.getTagName())[1]
1463 if component == 'annotation' and not self.annotation:
1464 self.annotation = Annotation(self)
1465 self.annotation.fromDom(i)
1466 elif component == 'simpleType':
1467 self.content = AnonymousSimpleType(self)
1468 self.content.fromDom(i)
1470 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1473 class LocalAttributeDeclaration(AttributeDeclaration,\
1479 complexType, restriction, extension, attributeGroup
1482 name -- NCName, required
1484 form -- ('qualified' | 'unqualified'), schema.attributeFormDefault
1485 use -- ('optional' | 'prohibited' | 'required'), optional
1489 annotation?, simpleType?
1492 attributes = {'id':None,
1495 'form':lambda self: GetSchema(self).getAttributeFormDefault(),
1499 contents = {'xsd':['annotation','simpleType']}
1501 def __init__(self, parent):
1502 AttributeDeclaration.__init__(self, parent)
1503 self.annotation = None
1506 def fromDom(self, node):
1507 self.setAttributes(node)
1508 contents = self.getContents(node)
1511 component = SplitQName(i.getTagName())[1]
1512 if component == 'annotation' and not self.annotation:
1513 self.annotation = Annotation(self)
1514 self.annotation.fromDom(i)
1515 elif component == 'simpleType':
1516 self.content = AnonymousSimpleType(self)
1517 self.content.fromDom(i)
1519 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1522 class AttributeWildCard(XMLSchemaComponent,\
1528 complexType, restriction, extension, attributeGroup
1531 namespace -- '##any' | '##other' |
1532 (anyURI* | '##targetNamespace' | '##local'), ##any
1533 processContents -- 'lax' | 'skip' | 'strict', strict
1537 attributes = {'id':None,
1538 'namespace':'##any',
1539 'processContents':'strict'}
1540 contents = {'xsd':['annotation']}
1541 tag = 'anyAttribute'
1543 def __init__(self, parent):
1544 XMLSchemaComponent.__init__(self, parent)
1545 self.annotation = None
1547 def fromDom(self, node):
1548 self.setAttributes(node)
1549 contents = self.getContents(node)
1552 component = SplitQName(i.getTagName())[1]
1553 if component == 'annotation' and not self.annotation:
1554 self.annotation = Annotation(self)
1555 self.annotation.fromDom(i)
1557 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1560 class AttributeReference(XMLSchemaComponent,\
1565 complexType, restriction, extension, attributeGroup
1568 ref -- QName, required
1569 use -- ('optional' | 'prohibited' | 'required'), optional
1576 attributes = {'id':None,
1581 contents = {'xsd':['annotation']}
1584 def __init__(self, parent):
1585 XMLSchemaComponent.__init__(self, parent)
1586 self.annotation = None
1588 def getAttributeDeclaration(self, attribute='ref'):
1589 return XMLSchemaComponent.getAttributeDeclaration(self, attribute)
1591 def fromDom(self, node):
1592 self.setAttributes(node)
1593 contents = self.getContents(node)
1596 component = SplitQName(i.getTagName())[1]
1597 if component == 'annotation' and not self.annotation:
1598 self.annotation = Annotation(self)
1599 self.annotation.fromDom(i)
1601 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1604 class AttributeGroupDefinition(XMLSchemaComponent,\
1605 AttributeGroupMarker,\
1607 """<attributeGroup name>
1612 name -- NCName, required
1614 annotation?, (attribute | attributeGroup)*, anyAttribute?
1617 attributes = {'id':None,
1619 contents = {'xsd':['annotation', 'attribute', 'attributeGroup', 'anyAttribute']}
1620 tag = 'attributeGroup'
1622 def __init__(self, parent):
1623 XMLSchemaComponent.__init__(self, parent)
1624 self.annotation = None
1625 self.attr_content = None
1627 def getAttributeContent(self):
1628 return self.attr_content
1630 def fromDom(self, node):
1631 self.setAttributes(node)
1632 contents = self.getContents(node)
1635 for indx in range(len(contents)):
1636 component = SplitQName(contents[indx].getTagName())[1]
1637 if (component == 'annotation') and (not indx):
1638 self.annotation = Annotation(self)
1639 self.annotation.fromDom(contents[indx])
1640 elif component == 'attribute':
1641 if contents[indx].hasattr('name'):
1642 content.append(LocalAttributeDeclaration(self))
1643 elif contents[indx].hasattr('ref'):
1644 content.append(AttributeReference(self))
1646 raise SchemaError, 'Unknown attribute type'
1647 content[-1].fromDom(contents[indx])
1648 elif component == 'attributeGroup':
1649 content.append(AttributeGroupReference(self))
1650 content[-1].fromDom(contents[indx])
1651 elif component == 'anyAttribute':
1652 if len(contents) != indx+1:
1653 raise SchemaError, 'anyAttribute is out of order in %s' %self.getItemTrace()
1654 content.append(AttributeWildCard(self))
1655 content[-1].fromDom(contents[indx])
1657 raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
1659 self.attr_content = tuple(content)
1661 class AttributeGroupReference(XMLSchemaComponent,\
1662 AttributeGroupMarker,\
1664 """<attributeGroup ref>
1666 complexType, restriction, extension, attributeGroup
1669 ref -- QName, required
1674 attributes = {'id':None,
1676 contents = {'xsd':['annotation']}
1677 tag = 'attributeGroup'
1679 def __init__(self, parent):
1680 XMLSchemaComponent.__init__(self, parent)
1681 self.annotation = None
1683 def getAttributeGroup(self, attribute='ref'):
1684 """attribute -- attribute with a QName value (eg. type).
1685 collection -- check types collection in parent Schema instance
1687 return XMLSchemaComponent.getAttributeGroup(self, attribute)
1689 def fromDom(self, node):
1690 self.setAttributes(node)
1691 contents = self.getContents(node)
1694 component = SplitQName(i.getTagName())[1]
1695 if component == 'annotation' and not self.annotation:
1696 self.annotation = Annotation(self)
1697 self.annotation.fromDom(i)
1699 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1703 ######################################################
1705 #####################################################
1706 class IdentityConstrants(XMLSchemaComponent):
1707 """Allow one to uniquely identify nodes in a document and ensure the
1708 integrity of references between them.
1710 attributes -- dictionary of attributes
1711 selector -- XPath to selected nodes
1712 fields -- list of XPath to key field
1714 def __init__(self, parent):
1715 XMLSchemaComponent.__init__(self, parent)
1716 self.selector = None
1718 self.annotation = None
1720 def fromDom(self, node):
1721 self.setAttributes(node)
1722 contents = self.getContents(node)
1726 component = SplitQName(i.getTagName())[1]
1727 if component in self.__class__.contents['xsd']:
1728 if component == 'annotation' and not self.annotation:
1729 self.annotation = Annotation(self)
1730 self.annotation.fromDom(i)
1731 elif component == 'selector':
1732 self.selector = self.Selector(self)
1733 self.selector.fromDom(i)
1735 elif component == 'field':
1736 fields.append(self.Field(self))
1737 fields[-1].fromDom(i)
1740 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1742 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1743 self.fields = tuple(fields)
1746 class Constraint(XMLSchemaComponent):
1747 def __init__(self, parent):
1748 XMLSchemaComponent.__init__(self, parent)
1749 self.annotation = None
1751 def fromDom(self, node):
1752 self.setAttributes(node)
1753 contents = self.getContents(node)
1756 component = SplitQName(i.getTagName())[1]
1757 if component in self.__class__.contents['xsd']:
1758 if component == 'annotation' and not self.annotation:
1759 self.annotation = Annotation(self)
1760 self.annotation.fromDom(i)
1762 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1764 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1766 class Selector(Constraint):
1772 xpath -- XPath subset, required
1776 required = ['xpath']
1777 attributes = {'id':None,
1779 contents = {'xsd':['annotation']}
1782 class Field(Constraint):
1788 xpath -- XPath subset, required
1792 required = ['xpath']
1793 attributes = {'id':None,
1795 contents = {'xsd':['annotation']}
1799 class Unique(IdentityConstrants):
1800 """<unique name> Enforce fields are unique w/i a specified scope.
1806 name -- NCName, required
1808 annotation?, selector, field+
1811 attributes = {'id':None,
1813 contents = {'xsd':['annotation', 'selector', 'field']}
1817 class Key(IdentityConstrants):
1818 """<key name> Enforce fields are unique w/i a specified scope, and all
1819 field values are present w/i document. Fields cannot
1826 name -- NCName, required
1828 annotation?, selector, field+
1831 attributes = {'id':None,
1833 contents = {'xsd':['annotation', 'selector', 'field']}
1837 class KeyRef(IdentityConstrants):
1838 """<keyref name refer> Ensure a match between two sets of values in an
1844 name -- NCName, required
1845 refer -- QName, required
1847 annotation?, selector, field+
1849 required = ['name', 'refer']
1850 attributes = {'id':None,
1853 contents = {'xsd':['annotation', 'selector', 'field']}
1857 class ElementDeclaration(XMLSchemaComponent,\
1865 name -- NCName, required
1869 nillable -- boolean, false
1870 abstract -- boolean, false
1871 substitutionGroup -- QName
1872 block -- ('#all' | ('substition' | 'extension' | 'restriction')*),
1874 final -- ('#all' | ('extension' | 'restriction')*),
1877 annotation?, (simpleType,complexType)?, (key | keyref | unique)*
1881 attributes = {'id':None,
1888 'substitutionGroup':None,
1889 'block':lambda self: self._parent().getBlockDefault(),
1890 'final':lambda self: self._parent().getFinalDefault()}
1891 contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
1892 'keyref', 'unique']}
1895 def __init__(self, parent):
1896 XMLSchemaComponent.__init__(self, parent)
1897 self.annotation = None
1899 self.constraints = ()
1901 def isQualified(self):
1902 """Global elements are always qualified.
1906 def getAttribute(self, attribute):
1907 """return attribute.
1908 If attribute is type and it's None, and no simple or complex content,
1909 return the default type "xsd:anyType"
1911 value = XMLSchemaComponent.getAttribute(self, attribute)
1912 if attribute != 'type' or value is not None:
1915 if self.content is not None:
1920 nsdict = parent.attributes[XMLSchemaComponent.xmlns]
1921 for k,v in nsdict.items():
1922 if v not in SCHEMA.XSD_LIST: continue
1923 return TypeDescriptionComponent((v, 'anyType'))
1925 if isinstance(parent, WSDLToolsAdapter)\
1926 or not hasattr(parent, '_parent'):
1929 parent = parent._parent()
1931 raise SchemaError, 'failed to locate the XSD namespace'
1933 def getElementDeclaration(self, attribute):
1934 raise Warning, 'invalid operation for <%s>' %self.tag
1936 def getTypeDefinition(self, attribute=None):
1937 """If attribute is None, "type" is assumed, return the corresponding
1938 representation of the global type definition (TypeDefinition),
1939 or the local definition if don't find "type". To maintain backwards
1940 compat, if attribute is provided call base class method.
1943 return XMLSchemaComponent.getTypeDefinition(self, attribute)
1944 gt = XMLSchemaComponent.getTypeDefinition(self, 'type')
1949 def getConstraints(self):
1950 return self._constraints
1951 def setConstraints(self, constraints):
1952 self._constraints = tuple(constraints)
1953 constraints = property(getConstraints, setConstraints, None, "tuple of key, keyref, unique constraints")
1955 def fromDom(self, node):
1956 self.setAttributes(node)
1957 contents = self.getContents(node)
1960 component = SplitQName(i.getTagName())[1]
1961 if component in self.__class__.contents['xsd']:
1962 if component == 'annotation' and not self.annotation:
1963 self.annotation = Annotation(self)
1964 self.annotation.fromDom(i)
1965 elif component == 'simpleType' and not self.content:
1966 self.content = AnonymousSimpleType(self)
1967 self.content.fromDom(i)
1968 elif component == 'complexType' and not self.content:
1969 self.content = LocalComplexType(self)
1970 self.content.fromDom(i)
1971 elif component == 'key':
1972 constraints.append(Key(self))
1973 constraints[-1].fromDom(i)
1974 elif component == 'keyref':
1975 constraints.append(KeyRef(self))
1976 constraints[-1].fromDom(i)
1977 elif component == 'unique':
1978 constraints.append(Unique(self))
1979 constraints[-1].fromDom(i)
1981 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1983 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
1985 self.constraints = constraints
1988 class LocalElementDeclaration(ElementDeclaration,\
1992 all, choice, sequence
1995 name -- NCName, required
1996 form -- ('qualified' | 'unqualified'), schema.elementFormDefault
1998 minOccurs -- Whole Number, 1
1999 maxOccurs -- (Whole Number | 'unbounded'), 1
2002 nillable -- boolean, false
2003 block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
2005 annotation?, (simpleType,complexType)?, (key | keyref | unique)*
2008 attributes = {'id':None,
2010 'form':lambda self: GetSchema(self).getElementFormDefault(),
2018 'block':lambda self: GetSchema(self).getBlockDefault()}
2019 contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
2020 'keyref', 'unique']}
2022 def isQualified(self):
2024 Local elements can be qualified or unqualifed according
2025 to the attribute form, or the elementFormDefault. By default
2026 local elements are unqualified.
2028 form = self.getAttribute('form')
2029 if form == 'qualified':
2031 if form == 'unqualified':
2033 raise SchemaError, 'Bad form (%s) for element: %s' %(form, self.getItemTrace())
2036 class ElementReference(XMLSchemaComponent,\
2041 all, choice, sequence
2044 ref -- QName, required
2045 minOccurs -- Whole Number, 1
2046 maxOccurs -- (Whole Number | 'unbounded'), 1
2051 attributes = {'id':None,
2055 contents = {'xsd':['annotation']}
2058 def __init__(self, parent):
2059 XMLSchemaComponent.__init__(self, parent)
2060 self.annotation = None
2062 def getElementDeclaration(self, attribute=None):
2063 """If attribute is None, "ref" is assumed, return the corresponding
2064 representation of the global element declaration (ElementDeclaration),
2065 To maintain backwards compat, if attribute is provided call base class method.
2068 return XMLSchemaComponent.getElementDeclaration(self, attribute)
2069 return XMLSchemaComponent.getElementDeclaration(self, 'ref')
2071 def fromDom(self, node):
2072 self.annotation = None
2073 self.setAttributes(node)
2074 for i in self.getContents(node):
2075 component = SplitQName(i.getTagName())[1]
2076 if component in self.__class__.contents['xsd']:
2077 if component == 'annotation' and not self.annotation:
2078 self.annotation = Annotation(self)
2079 self.annotation.fromDom(i)
2081 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2084 class ElementWildCard(LocalElementDeclaration, WildCardMarker):
2090 minOccurs -- Whole Number, 1
2091 maxOccurs -- (Whole Number | 'unbounded'), 1
2092 namespace -- '##any' | '##other' |
2093 (anyURI* | '##targetNamespace' | '##local'), ##any
2094 processContents -- 'lax' | 'skip' | 'strict', strict
2099 attributes = {'id':None,
2102 'namespace':'##any',
2103 'processContents':'strict'}
2104 contents = {'xsd':['annotation']}
2107 def __init__(self, parent):
2108 XMLSchemaComponent.__init__(self, parent)
2109 self.annotation = None
2111 def isQualified(self):
2113 Global elements are always qualified, but if processContents
2114 are not strict could have dynamically generated local elements.
2116 return GetSchema(self).isElementFormDefaultQualified()
2118 def getAttribute(self, attribute):
2119 """return attribute.
2121 return XMLSchemaComponent.getAttribute(self, attribute)
2123 def getTypeDefinition(self, attribute):
2124 raise Warning, 'invalid operation for <%s>' % self.tag
2126 def fromDom(self, node):
2127 self.annotation = None
2128 self.setAttributes(node)
2129 for i in self.getContents(node):
2130 component = SplitQName(i.getTagName())[1]
2131 if component in self.__class__.contents['xsd']:
2132 if component == 'annotation' and not self.annotation:
2133 self.annotation = Annotation(self)
2134 self.annotation.fromDom(i)
2136 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2139 ######################################################
2141 #####################################################
2142 class Sequence(XMLSchemaComponent,\
2146 complexType, extension, restriction, group, choice, sequence
2149 minOccurs -- Whole Number, 1
2150 maxOccurs -- (Whole Number | 'unbounded'), 1
2153 annotation?, (element | group | choice | sequence | any)*
2155 attributes = {'id':None,
2158 contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
2162 def __init__(self, parent):
2163 XMLSchemaComponent.__init__(self, parent)
2164 self.annotation = None
2167 def fromDom(self, node):
2168 self.setAttributes(node)
2169 contents = self.getContents(node)
2173 component = SplitQName(i.getTagName())[1]
2174 if component in self.__class__.contents['xsd']:
2175 if component == 'annotation' and not self.annotation:
2176 self.annotation = Annotation(self)
2177 self.annotation.fromDom(i)
2179 elif component == 'element':
2180 if i.hasattr('ref'):
2181 content.append(ElementReference(self))
2183 content.append(LocalElementDeclaration(self))
2184 elif component == 'group':
2185 content.append(ModelGroupReference(self))
2186 elif component == 'choice':
2187 content.append(Choice(self))
2188 elif component == 'sequence':
2189 content.append(Sequence(self))
2190 elif component == 'any':
2191 content.append(ElementWildCard(self))
2193 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2194 content[-1].fromDom(i)
2196 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2197 self.content = tuple(content)
2200 class All(XMLSchemaComponent,\
2204 complexType, extension, restriction, group
2207 minOccurs -- '0' | '1', 1
2211 annotation?, element*
2213 attributes = {'id':None,
2216 contents = {'xsd':['annotation', 'element']}
2219 def __init__(self, parent):
2220 XMLSchemaComponent.__init__(self, parent)
2221 self.annotation = None
2224 def fromDom(self, node):
2225 self.setAttributes(node)
2226 contents = self.getContents(node)
2230 component = SplitQName(i.getTagName())[1]
2231 if component in self.__class__.contents['xsd']:
2232 if component == 'annotation' and not self.annotation:
2233 self.annotation = Annotation(self)
2234 self.annotation.fromDom(i)
2236 elif component == 'element':
2237 if i.hasattr('ref'):
2238 content.append(ElementReference(self))
2240 content.append(LocalElementDeclaration(self))
2242 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2243 content[-1].fromDom(i)
2245 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2246 self.content = tuple(content)
2249 class Choice(XMLSchemaComponent,\
2253 complexType, extension, restriction, group, choice, sequence
2256 minOccurs -- Whole Number, 1
2257 maxOccurs -- (Whole Number | 'unbounded'), 1
2260 annotation?, (element | group | choice | sequence | any)*
2262 attributes = {'id':None,
2265 contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
2269 def __init__(self, parent):
2270 XMLSchemaComponent.__init__(self, parent)
2271 self.annotation = None
2274 def fromDom(self, node):
2275 self.setAttributes(node)
2276 contents = self.getContents(node)
2280 component = SplitQName(i.getTagName())[1]
2281 if component in self.__class__.contents['xsd']:
2282 if component == 'annotation' and not self.annotation:
2283 self.annotation = Annotation(self)
2284 self.annotation.fromDom(i)
2286 elif component == 'element':
2287 if i.hasattr('ref'):
2288 content.append(ElementReference(self))
2290 content.append(LocalElementDeclaration(self))
2291 elif component == 'group':
2292 content.append(ModelGroupReference(self))
2293 elif component == 'choice':
2294 content.append(Choice(self))
2295 elif component == 'sequence':
2296 content.append(Sequence(self))
2297 elif component == 'any':
2298 content.append(ElementWildCard(self))
2300 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2301 content[-1].fromDom(i)
2303 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2304 self.content = tuple(content)
2307 class ModelGroupDefinition(XMLSchemaComponent,\
2315 name -- NCName, required
2318 annotation?, (all | choice | sequence)?
2321 attributes = {'id':None,
2323 contents = {'xsd':['annotation', 'all', 'choice', 'sequence']}
2326 def __init__(self, parent):
2327 XMLSchemaComponent.__init__(self, parent)
2328 self.annotation = None
2331 def fromDom(self, node):
2332 self.setAttributes(node)
2333 contents = self.getContents(node)
2336 component = SplitQName(i.getTagName())[1]
2337 if component in self.__class__.contents['xsd']:
2338 if component == 'annotation' and not self.annotation:
2339 self.annotation = Annotation(self)
2340 self.annotation.fromDom(i)
2342 elif component == 'all' and not self.content:
2343 self.content = All(self)
2344 elif component == 'choice' and not self.content:
2345 self.content = Choice(self)
2346 elif component == 'sequence' and not self.content:
2347 self.content = Sequence(self)
2349 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2350 self.content.fromDom(i)
2352 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2355 class ModelGroupReference(XMLSchemaComponent,\
2360 choice, complexType, extension, restriction, sequence
2363 ref -- NCName, required
2364 minOccurs -- Whole Number, 1
2365 maxOccurs -- (Whole Number | 'unbounded'), 1
2371 attributes = {'id':None,
2375 contents = {'xsd':['annotation']}
2378 def __init__(self, parent):
2379 XMLSchemaComponent.__init__(self, parent)
2380 self.annotation = None
2382 def getModelGroupReference(self):
2383 return self.getModelGroup('ref')
2385 def fromDom(self, node):
2386 self.setAttributes(node)
2387 contents = self.getContents(node)
2390 component = SplitQName(i.getTagName())[1]
2391 if component in self.__class__.contents['xsd']:
2392 if component == 'annotation' and not self.annotation:
2393 self.annotation = Annotation(self)
2394 self.annotation.fromDom(i)
2396 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2398 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2402 class ComplexType(XMLSchemaComponent,\
2405 """<complexType name>
2410 name -- NCName, required
2411 mixed -- boolean, false
2412 abstract -- boolean, false
2413 block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
2414 final -- ('#all' | ('extension' | 'restriction')*), schema.finalDefault
2417 annotation?, (simpleContent | complexContent |
2418 ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
2421 attributes = {'id':None,
2425 'block':lambda self: self._parent().getBlockDefault(),
2426 'final':lambda self: self._parent().getFinalDefault()}
2427 contents = {'xsd':['annotation', 'simpleContent', 'complexContent',\
2428 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\
2429 'anyAttribute', 'any']}
2432 def __init__(self, parent):
2433 XMLSchemaComponent.__init__(self, parent)
2434 self.annotation = None
2436 self.attr_content = None
2439 m = self.getAttribute('mixed')
2440 if m == 0 or m == False:
2442 if isinstance(m, basestring) is True:
2443 if m in ('false', '0'):
2445 if m in ('true', '1'):
2448 raise SchemaError, 'invalid value for attribute mixed(%s): %s'\
2449 %(m, self.getItemTrace())
2451 def getAttributeContent(self):
2452 return self.attr_content
2454 def getElementDeclaration(self, attribute):
2455 raise Warning, 'invalid operation for <%s>' %self.tag
2457 def getTypeDefinition(self, attribute):
2458 raise Warning, 'invalid operation for <%s>' %self.tag
2460 def fromDom(self, node):
2461 self.setAttributes(node)
2462 contents = self.getContents(node)
2469 component = SplitQName(contents[indx].getTagName())[1]
2470 if component == 'annotation':
2471 self.annotation = Annotation(self)
2472 self.annotation.fromDom(contents[indx])
2475 component = SplitQName(contents[indx].getTagName())[1]
2478 if component == 'simpleContent':
2479 self.content = self.__class__.SimpleContent(self)
2480 self.content.fromDom(contents[indx])
2481 elif component == 'complexContent':
2482 self.content = self.__class__.ComplexContent(self)
2483 self.content.fromDom(contents[indx])
2485 if component == 'all':
2486 self.content = All(self)
2487 elif component == 'choice':
2488 self.content = Choice(self)
2489 elif component == 'sequence':
2490 self.content = Sequence(self)
2491 elif component == 'group':
2492 self.content = ModelGroupReference(self)
2495 self.content.fromDom(contents[indx])
2498 self.attr_content = []
2500 component = SplitQName(contents[indx].getTagName())[1]
2501 if component == 'attribute':
2502 if contents[indx].hasattr('ref'):
2503 self.attr_content.append(AttributeReference(self))
2505 self.attr_content.append(LocalAttributeDeclaration(self))
2506 elif component == 'attributeGroup':
2507 self.attr_content.append(AttributeGroupReference(self))
2508 elif component == 'anyAttribute':
2509 self.attr_content.append(AttributeWildCard(self))
2511 raise SchemaError, 'Unknown component (%s): %s' \
2512 %(contents[indx].getTagName(),self.getItemTrace())
2513 self.attr_content[-1].fromDom(contents[indx])
2516 class _DerivedType(XMLSchemaComponent):
2517 def __init__(self, parent):
2518 XMLSchemaComponent.__init__(self, parent)
2519 self.annotation = None
2520 # XXX remove attribute derivation, inconsistent
2521 self.derivation = None
2524 def fromDom(self, node):
2525 self.setAttributes(node)
2526 contents = self.getContents(node)
2529 component = SplitQName(i.getTagName())[1]
2530 if component in self.__class__.contents['xsd']:
2531 if component == 'annotation' and not self.annotation:
2532 self.annotation = Annotation(self)
2533 self.annotation.fromDom(i)
2535 elif component == 'restriction' and not self.derivation:
2536 self.derivation = self.__class__.Restriction(self)
2537 elif component == 'extension' and not self.derivation:
2538 self.derivation = self.__class__.Extension(self)
2540 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2542 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2543 self.derivation.fromDom(i)
2544 self.content = self.derivation
2546 class ComplexContent(_DerivedType,\
2553 mixed -- boolean, false
2556 annotation?, (restriction | extension)
2558 attributes = {'id':None,
2560 contents = {'xsd':['annotation', 'restriction', 'extension']}
2561 tag = 'complexContent'
2564 m = self.getAttribute('mixed')
2565 if m == 0 or m == False:
2567 if isinstance(m, basestring) is True:
2568 if m in ('false', '0'):
2570 if m in ('true', '1'):
2572 raise SchemaError, 'invalid value for attribute mixed(%s): %s'\
2573 %(m, self.getItemTrace())
2575 class _DerivationBase(XMLSchemaComponent):
2576 """<extension>,<restriction>
2581 base -- QName, required
2584 annotation?, (group | all | choice | sequence)?,
2585 (attribute | attributeGroup)*, anyAttribute?
2588 attributes = {'id':None,
2590 contents = {'xsd':['annotation', 'group', 'all', 'choice',\
2591 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']}
2593 def __init__(self, parent):
2594 XMLSchemaComponent.__init__(self, parent)
2595 self.annotation = None
2597 self.attr_content = None
2599 def getAttributeContent(self):
2600 return self.attr_content
2602 def fromDom(self, node):
2603 self.setAttributes(node)
2604 contents = self.getContents(node)
2611 component = SplitQName(contents[indx].getTagName())[1]
2612 if component == 'annotation':
2613 self.annotation = Annotation(self)
2614 self.annotation.fromDom(contents[indx])
2616 component = SplitQName(contents[indx].getTagName())[1]
2618 if component == 'all':
2619 self.content = All(self)
2620 self.content.fromDom(contents[indx])
2622 elif component == 'choice':
2623 self.content = Choice(self)
2624 self.content.fromDom(contents[indx])
2626 elif component == 'sequence':
2627 self.content = Sequence(self)
2628 self.content.fromDom(contents[indx])
2630 elif component == 'group':
2631 self.content = ModelGroupReference(self)
2632 self.content.fromDom(contents[indx])
2637 self.attr_content = []
2639 component = SplitQName(contents[indx].getTagName())[1]
2640 if component == 'attribute':
2641 if contents[indx].hasattr('ref'):
2642 self.attr_content.append(AttributeReference(self))
2644 self.attr_content.append(LocalAttributeDeclaration(self))
2645 elif component == 'attributeGroup':
2646 if contents[indx].hasattr('ref'):
2647 self.attr_content.append(AttributeGroupReference(self))
2649 self.attr_content.append(AttributeGroupDefinition(self))
2650 elif component == 'anyAttribute':
2651 self.attr_content.append(AttributeWildCard(self))
2653 raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
2654 self.attr_content[-1].fromDom(contents[indx])
2657 class Extension(_DerivationBase,
2664 base -- QName, required
2667 annotation?, (group | all | choice | sequence)?,
2668 (attribute | attributeGroup)*, anyAttribute?
2672 class Restriction(_DerivationBase,\
2674 """<restriction base>
2679 base -- QName, required
2682 annotation?, (group | all | choice | sequence)?,
2683 (attribute | attributeGroup)*, anyAttribute?
2688 class SimpleContent(_DerivedType,\
2697 annotation?, (restriction | extension)
2699 attributes = {'id':None}
2700 contents = {'xsd':['annotation', 'restriction', 'extension']}
2701 tag = 'simpleContent'
2703 class Extension(XMLSchemaComponent,\
2710 base -- QName, required
2713 annotation?, (attribute | attributeGroup)*, anyAttribute?
2716 attributes = {'id':None,
2718 contents = {'xsd':['annotation', 'attribute', 'attributeGroup',
2722 def __init__(self, parent):
2723 XMLSchemaComponent.__init__(self, parent)
2724 self.annotation = None
2725 self.attr_content = None
2727 def getAttributeContent(self):
2728 return self.attr_content
2730 def fromDom(self, node):
2731 self.setAttributes(node)
2732 contents = self.getContents(node)
2738 component = SplitQName(contents[indx].getTagName())[1]
2739 if component == 'annotation':
2740 self.annotation = Annotation(self)
2741 self.annotation.fromDom(contents[indx])
2743 component = SplitQName(contents[indx].getTagName())[1]
2747 component = SplitQName(contents[indx].getTagName())[1]
2748 if component == 'attribute':
2749 if contents[indx].hasattr('ref'):
2750 content.append(AttributeReference(self))
2752 content.append(LocalAttributeDeclaration(self))
2753 elif component == 'attributeGroup':
2754 content.append(AttributeGroupReference(self))
2755 elif component == 'anyAttribute':
2756 content.append(AttributeWildCard(self))
2758 raise SchemaError, 'Unknown component (%s)'\
2759 %(contents[indx].getTagName())
2760 content[-1].fromDom(contents[indx])
2762 self.attr_content = tuple(content)
2765 class Restriction(XMLSchemaComponent,\
2767 """<restriction base>
2772 base -- QName, required
2775 annotation?, simpleType?, (enumeration | length |
2776 maxExclusive | maxInclusive | maxLength | minExclusive |
2777 minInclusive | minLength | pattern | fractionDigits |
2778 totalDigits | whiteSpace)*, (attribute | attributeGroup)*,
2782 attributes = {'id':None,
2784 contents = {'xsd':['annotation', 'simpleType', 'attribute',\
2785 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets}
2788 def __init__(self, parent):
2789 XMLSchemaComponent.__init__(self, parent)
2790 self.annotation = None
2792 self.attr_content = None
2794 def getAttributeContent(self):
2795 return self.attr_content
2797 def fromDom(self, node):
2799 self.setAttributes(node)
2800 contents = self.getContents(node)
2804 component = SplitQName(contents[indx].getTagName())[1]
2805 if component == 'annotation':
2806 self.annotation = Annotation(self)
2807 self.annotation.fromDom(contents[indx])
2809 component = SplitQName(contents[indx].getTagName())[1]
2813 component = SplitQName(contents[indx].getTagName())[1]
2814 if component == 'attribute':
2815 if contents[indx].hasattr('ref'):
2816 content.append(AttributeReference(self))
2818 content.append(LocalAttributeDeclaration(self))
2819 elif component == 'attributeGroup':
2820 content.append(AttributeGroupReference(self))
2821 elif component == 'anyAttribute':
2822 content.append(AttributeWildCard(self))
2823 elif component == 'simpleType':
2824 self.content.append(AnonymousSimpleType(self))
2825 self.content[-1].fromDom(contents[indx])
2827 raise SchemaError, 'Unknown component (%s)'\
2828 %(contents[indx].getTagName())
2829 content[-1].fromDom(contents[indx])
2831 self.attr_content = tuple(content)
2834 class LocalComplexType(ComplexType,\
2841 mixed -- boolean, false
2844 annotation?, (simpleContent | complexContent |
2845 ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
2848 attributes = {'id':None,
2853 class SimpleType(XMLSchemaComponent,\
2856 """<simpleType name>
2861 name -- NCName, required
2862 final -- ('#all' | ('extension' | 'restriction' | 'list' | 'union')*),
2866 annotation?, (restriction | list | union)
2869 attributes = {'id':None,
2871 'final':lambda self: self._parent().getFinalDefault()}
2872 contents = {'xsd':['annotation', 'restriction', 'list', 'union']}
2875 def __init__(self, parent):
2876 XMLSchemaComponent.__init__(self, parent)
2877 self.annotation = None
2880 def getElementDeclaration(self, attribute):
2881 raise Warning, 'invalid operation for <%s>' %self.tag
2883 def getTypeDefinition(self, attribute):
2884 raise Warning, 'invalid operation for <%s>' %self.tag
2886 def fromDom(self, node):
2887 self.setAttributes(node)
2888 contents = self.getContents(node)
2889 for child in contents:
2890 component = SplitQName(child.getTagName())[1]
2891 if component == 'annotation':
2892 self.annotation = Annotation(self)
2893 self.annotation.fromDom(child)
2898 if component == 'restriction':
2899 self.content = self.__class__.Restriction(self)
2900 elif component == 'list':
2901 self.content = self.__class__.List(self)
2902 elif component == 'union':
2903 self.content = self.__class__.Union(self)
2905 raise SchemaError, 'Unknown component (%s)' %(component)
2906 self.content.fromDom(child)
2908 class Restriction(XMLSchemaComponent,\
2910 """<restriction base>
2915 base -- QName, required or simpleType child
2918 annotation?, simpleType?, (enumeration | length |
2919 maxExclusive | maxInclusive | maxLength | minExclusive |
2920 minInclusive | minLength | pattern | fractionDigits |
2921 totalDigits | whiteSpace)*
2923 attributes = {'id':None,
2925 contents = {'xsd':['annotation', 'simpleType']+RestrictionMarker.facets}
2928 def __init__(self, parent):
2929 XMLSchemaComponent.__init__(self, parent)
2930 self.annotation = None
2934 def getAttributeBase(self):
2935 return XMLSchemaComponent.getAttribute(self, 'base')
2937 def getTypeDefinition(self, attribute='base'):
2938 return XMLSchemaComponent.getTypeDefinition(self, attribute)
2940 def getSimpleTypeContent(self):
2941 for el in self.content:
2942 if el.isSimple(): return el
2945 def fromDom(self, node):
2947 self.setAttributes(node)
2948 contents = self.getContents(node)
2951 for indx in range(len(contents)):
2952 component = SplitQName(contents[indx].getTagName())[1]
2953 if (component == 'annotation') and (not indx):
2954 self.annotation = Annotation(self)
2955 self.annotation.fromDom(contents[indx])
2957 elif (component == 'simpleType') and (not indx or indx == 1):
2958 content.append(AnonymousSimpleType(self))
2959 content[-1].fromDom(contents[indx])
2960 elif component in RestrictionMarker.facets:
2961 self.facets.append(contents[indx])
2963 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
2964 self.content = tuple(content)
2967 class Union(XMLSchemaComponent,
2974 memberTypes -- list of QNames, required or simpleType child.
2977 annotation?, simpleType*
2979 attributes = {'id':None,
2980 'memberTypes':None }
2981 contents = {'xsd':['annotation', 'simpleType']}
2984 def __init__(self, parent):
2985 XMLSchemaComponent.__init__(self, parent)
2986 self.annotation = None
2989 def fromDom(self, node):
2990 self.setAttributes(node)
2991 contents = self.getContents(node)
2994 for indx in range(len(contents)):
2995 component = SplitQName(contents[indx].getTagName())[1]
2996 if (component == 'annotation') and (not indx):
2997 self.annotation = Annotation(self)
2998 self.annotation.fromDom(contents[indx])
2999 elif (component == 'simpleType'):
3000 content.append(AnonymousSimpleType(self))
3001 content[-1].fromDom(contents[indx])
3003 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
3004 self.content = tuple(content)
3006 class List(XMLSchemaComponent,
3013 itemType -- QName, required or simpleType child.
3016 annotation?, simpleType?
3018 attributes = {'id':None,
3020 contents = {'xsd':['annotation', 'simpleType']}
3023 def __init__(self, parent):
3024 XMLSchemaComponent.__init__(self, parent)
3025 self.annotation = None
3028 def getItemType(self):
3029 return self.attributes.get('itemType')
3031 def getTypeDefinition(self, attribute='itemType'):
3033 return the type refered to by itemType attribute or
3034 the simpleType content. If returns None, then the
3035 type refered to by itemType is primitive.
3037 tp = XMLSchemaComponent.getTypeDefinition(self, attribute)
3038 return tp or self.content
3040 def fromDom(self, node):
3041 self.annotation = None
3043 self.setAttributes(node)
3044 contents = self.getContents(node)
3045 for indx in range(len(contents)):
3046 component = SplitQName(contents[indx].getTagName())[1]
3047 if (component == 'annotation') and (not indx):
3048 self.annotation = Annotation(self)
3049 self.annotation.fromDom(contents[indx])
3050 elif (component == 'simpleType'):
3051 self.content = AnonymousSimpleType(self)
3052 self.content.fromDom(contents[indx])
3055 raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
3058 class AnonymousSimpleType(SimpleType,\
3063 attribute, element, list, restriction, union
3068 annotation?, (restriction | list | union)
3071 attributes = {'id':None}
3085 ###########################
3086 ###########################
3089 if sys.version_info[:2] >= (2, 2):
3093 tupleClass = UserTuple.UserTuple
3095 class TypeDescriptionComponent(tupleClass):
3096 """Tuple of length 2, consisting of
3097 a namespace and unprefixed name.
3099 def __init__(self, args):
3100 """args -- (namespace, name)
3101 Remove the name's prefix, irrelevant.
3104 raise TypeError, 'expecting tuple (namespace, name), got %s' %args
3105 elif args[1].find(':') >= 0:
3106 args = (args[0], SplitQName(args[1])[1])
3107 tuple.__init__(self, args)
3110 def getTargetNamespace(self):