1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Classes corresponding to W3C XML Schema components.
17
18 Class names and behavior should conform to the schema components described in
19 U{XML Schema Part 1: Structures<http://www.w3.org/TR/xmlschema-1/>}.
20 References to sections in the documentation of this module generally refers to
21 that document.
22
23 Each class has a C{CreateFromDOM} class method that creates an instance and
24 initializes it from a DOM node. Only the L{Wildcard}, L{Particle}, and
25 L{ModelGroup} components are created from non-DOM sources. However, the
26 requirements on DOM interface are restricted to attributes, child nodes, and
27 basic fields, though all these must support namespaces.
28
29 @group Mixins: *_mixin
30 @group Ur Type Specializations: *UrType*
31 @group Utilities: _ImportElementInformationItem
32
33 """
34
35 import pyxb
36 import pyxb.xmlschema
37 from xml.dom import Node
38 import types
39 import re
40 import logging
41
42 import pyxb.namespace.archive
43 import pyxb.namespace.resolution
44
45 from pyxb.binding import basis
46 from pyxb.binding import datatypes
47 from pyxb.binding import facets
48 from pyxb.utils import domutils
49 import pyxb.utils.utility
50 import copy
51 import urlparse
52 import os.path
53
54 _log = logging.getLogger(__name__)
55
56
57 _PastAddBuiltInTypes = False
58
59
60 from pyxb.namespace import XMLSchema as xsd
61
62 -class _SchemaComponent_mixin (pyxb.namespace._ComponentDependency_mixin,
63 pyxb.namespace.archive._ArchivableObject_mixin,
64 pyxb.utils.utility.PrivateTransient_mixin,
65 pyxb.utils.utility.Locatable_mixin):
66 """A mix-in that marks the class as representing a schema component.
67
68 This exists so that we can determine the owning schema for any
69 component we encounter. This is normally done at construction
70 time by passing a C{schema=val} parameter to the constructor.
71 """
72
73
74
75 __PrivateTransient = set()
76
78 """The namespace context for this schema.
79
80 This defines where it looks things up, where it puts things it
81 creates, the in-scope namespace declarations, etc. Must be defined
82 for anything that does any sort of QName interpretation. The value is
83 generally a reference to a namespace context associated with the DOM
84 element node corresponding to this component."""
85 if self.__namespaceContext is None:
86 raise pyxb.LogicError('Attempt to access missing namespace context for %s' % (self,))
87 return self.__namespaceContext
89
90
91 self.bindingSortKey()
92 self.__namespaceContext = None
93 return self
94 __namespaceContext = None
95 __PrivateTransient.add('namespaceContext')
96
97
98
99
100
101 __nameInBinding = None
102
103
104
105 __owner = None
106 __PrivateTransient.add('owner')
107
108
109 __ownedComponents = None
110 __PrivateTransient.add('ownedComponent')
111
113 """The context into which declarations in or subordinate to this nodeare placed."""
114 return self.__scope
115 __scope = None
116
120
124
126 """Set the scope of this instance after construction.
127
128 This should only be invoked on cloned declarations being incorporated
129 into a complex type definition. Note that the source of the clone may
130 be any scope: indeterminate if from a model (attribute) group
131 definition; global if a reference to a global component; or ctd if
132 inherited from a complex base type."""
133 assert self.__cloneSource is not None
134 assert isinstance(self, _ScopedDeclaration_mixin)
135 assert isinstance(ctd, ComplexTypeDefinition)
136 self.__scope = ctd
137 return self
138
140 """Initialize portions of a component.
141
142 @keyword scope: The scope in which the component is defined
143
144 @keyword namespace_context: The NamespaceContext to use within this component
145
146 @keyword node: If no C{namespace_context} is provided, a DOM node must
147 be provided from which a namespace context can be identified.
148
149 @keyword owner: Reference to the component that owns this one (the
150 immediately enclosing component). Is C{None} in the case of top-level
151 components.
152
153 @keyword schema: Reference to the L{Schema} component to which the
154 component belongs. Required for every component except L{Schema},
155 L{Annotation}, and L{Wildcard}.
156 """
157
158 self.__ownedComponents = set()
159 self.__scope = kw.get('scope')
160 self.__namespaceContext = kw.get('namespace_context')
161 node = kw.get('node')
162 owner = kw.get('owner')
163 if self.__namespaceContext is None:
164 if node is None:
165 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node')
166 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
167 if self.__namespaceContext is None:
168 raise pyxb.LogicError('No namespace_context for schema component')
169
170 super(_SchemaComponent_mixin, self).__init__(*args, **kw)
171
172 self._namespaceContext().targetNamespace()._associateComponent(self)
173
174 self._setOwner(owner)
175 if isinstance(node, pyxb.utils.utility.Locatable_mixin):
176 self._setLocation(node._location())
177 elif isinstance(owner, pyxb.utils.utility.Locatable_mixin):
178 self._setLocation(owner._location())
179
180 schema = kw.get('schema')
181 if schema is not None:
182 self._setObjectOrigin(schema.originRecord())
183 else:
184 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),)
185
186 if isinstance(self, ComplexTypeDefinition):
187 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
188
190 """Dissociate this component from its owning namespace.
191
192 This should only be done whwen there are no other references to the
193 component, and you want to ensure it does not appear in the model."""
194 self._namespaceContext().targetNamespace()._replaceComponent(self, None)
195 return self
196
198 """Set the owner of this component.
199
200 If C{owner} is C{None}, this has no effect. Otherwise, the
201 component's current owner must be either C{None} or the same as the
202 input C{owner}."""
203
204 if owner is not None:
205 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner)
206 self.__owner = owner
207 owner.__ownedComponents.add(self)
208 return self
209
212
213
214 __cloneSource = None
215 __PrivateTransient.add('cloneSource')
216
218 """The source component from which this is a clone.
219
220 Returns C{None} if this is not a clone."""
221 return self.__cloneSource
222
223
224 __clones = None
225 __PrivateTransient.add('clones')
226
228 """The set of instances cloned from this component.
229
230 Returns None if no instances have been cloned from this."""
231 return self.__clones
232
259
260 - def _clone (self, owner, origin):
284
289
294
296 """Return the name of this component, as best it can be determined.
297
298 For example, ModelGroup instances will be named by their
299 ModelGroupDefinition, if available. Returns None if no name can be
300 inferred."""
301 if isinstance(self, _NamedComponent_mixin):
302 return self.name()
303 if isinstance(self, ModelGroup):
304 agd = self.modelGroupDefinition()
305 if agd is not None:
306 return agd.name()
307 return None
308
310 """Return the name by which this component is known in the generated
311 binding.
312
313 @note: To support builtin datatypes, type definitions with an
314 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class
315 initialize their binding name from the class name when the support
316 association is created. As long as no built-in datatype conflicts
317 with a language keyword, this should be fine."""
318 return self.__nameInBinding
319
321 """Return C{True} iff this is a component which has a user-visible
322 Python construct which serves as its binding.
323
324 Type definitions have classes as their bindings. Global element
325 declarations have instances of L{pyxb.binding.basis.element} as their
326 bindings."""
327 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
328
330 """Set the name by which this component shall be known in the XSD binding."""
331 self.__nameInBinding = name_in_binding
332 return self
333
335 """Override fields in this instance with those from the other.
336
337 Post-extended; description in leaf implementation in
338 ComplexTypeDefinition and SimpleTypeDefinition."""
339 assert self != other
340 self_fn = lambda *_args, **_kw: self
341 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', self_fn)(other)
342
343 if self.__nameInBinding is None:
344 self.__nameInBinding = other.__nameInBinding
345 return self
346
372 __bindingSortKey = None
373
374
375 -class _ParticleTree_mixin (pyxb.cscRoot):
376 - def _walkParticleTree (self, visit, arg):
377 """Mix-in supporting walks of L{Particle} trees.
378
379 This invokes a provided function on each node in a tree defining the
380 content model of a particle, both on the way down the tree and on the
381 way back up. A standard implementation would be::
382
383 def _walkParticleTree (self, visit, arg):
384 visit(self, True, arg)
385 self.__term.walkParticleTree(visit, arg)
386 visit(self, False, arg)
387
388 @param visit: A callable with parameters C{node, entering, arg} where
389 C{node} is an instance of a class inheriting L{_ParticleTree_mixin},
390 C{entering} indicates tree transition status, and C{arg} is a
391 caller-provided state parameter. C{entering} is C{True} if C{node}
392 has particle children and the call is before they are visited;
393 C{None} if the C{node} has no particle children; and C{False} if
394 C{node} has particle children and they have been visited.
395
396 @param arg: The caller-provided state parameter to be passed along
397 with the node and entry/exit status in the invocation of C{visit}.
398 """
399 raise NotImplementedError('%s._walkParticleTree' % (self.__class__.__name__,))
400
402 """This class is a mix-in which guarantees that only one instance
403 of the class will be created. It is used to ensure that the
404 ur-type instances are pointer-equivalent even when unpickling.
405 See ComplexTypeDefinition.UrTypeDefinition()."""
407 singleton_property = '_%s__singleton' % (cls.__name__,)
408 if not (singleton_property in cls.__dict__):
409 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
410 return cls.__dict__[singleton_property]
411
413 """Mix-in that supports an optional single annotation that describes the component.
414
415 Most schema components have annotations. The ones that don't are
416 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
417 and L{Schema} support multiple annotations, so do not mix-in this
418 class."""
419
420
421 __annotation = None
422
426
434
436 """Override fields in this instance with those from the other.
437
438 Post-extended; description in leaf implementation in
439 ComplexTypeDefinition and SimpleTypeDefinition."""
440 assert self != other
441 self_fn = lambda *_args, **_kw: self
442 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', self_fn)(other)
443
444 self.__annotation = other.__annotation
445 return self
446
449
451 """A helper that encapsulates a reference to an anonymous type in a different namespace.
452
453 Normally references to components in other namespaces can be made using
454 the component's name. This is not the case when a namespace derives from
455 a base type in another namespace and needs to reference the attribute or
456 element declarations held in that type. If these declarations are local
457 to the base complex type, they cannot be identified by name. This class
458 provides a pickleable representation for them that behaves rather like an
459 L{pyxb.namespace.ExpandedName} instance in that it can be used to
460 dereference various component types."""
461
462 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
463
464 __namespace = None
465 __anonymousName = None
466 - def __init__ (self, namespace, anonymous_name):
467 """Create a new anonymous reference.
468
469 @param namespace: The namespace in which the component is declared.
470 @type namespace: L{pyxb.namespace.Namespace}
471 @param anonymous_name: A generated name guaranteed to be unique within
472 the namespace. See L{_NamedComponent_mixin._anonymousName}.
473 @type anonymous_name: C{basestring}.
474 """
475 self.__namespace = namespace
476 self.__anonymousName = anonymous_name
477 assert self.__anonymousName is not None
478
479 @classmethod
481 """Return the component referred to by the provided reference,
482 regardless of whether it is a normal or anonymous reference."""
483 if not isinstance(object_reference, _PickledAnonymousReference):
484 assert isinstance(object_reference, tuple)
485 object_reference = pyxb.namespace.ExpandedName(object_reference)
486 return object_reference
487
490
493
497
500
501 typeDefinition = __lookupObject
502 attributeGroupDefinition = __lookupObject
503 modelGroupDefinition = __lookupObject
504 attributeDeclaration = __lookupObject
505 elementDeclaration = __lookupObject
506 identityConstraintDefinition = __lookupObject
507 notationDeclaration = __lookupObject
508
512
514 """Mix-in to hold the name and targetNamespace of a component.
515
516 The name may be None, indicating an anonymous component. The
517 targetNamespace is never None, though it could be an empty namespace. The
518 name and targetNamespace values are immutable after creation.
519
520 This class overrides the pickling behavior: when pickling a Namespace,
521 objects that do not belong to that namespace are pickled as references,
522 not as values. This ensures the uniqueness of objects when multiple
523 namespace definitions are pre-loaded.
524
525 This class must follow L{_SchemaComponent_mixin} in the MRO.
526 """
527
528 __PrivateTransient = set()
529
531 """Name of the component within its scope or namespace.
532
533 This is an NCName. The value isNone if the component is
534 anonymous. The attribute is immutable after the component is
535 created creation."""
536 return self.__name
537 __name = None
538
540 """Return true iff this instance is locally scoped (has no name)."""
541 return self.__name is None
542
567 __anonymousName = None
568
570 """The targetNamespace of a component.
571
572 This is None, or a reference to a Namespace in which the
573 component is declared (either as a global or local to one of
574 the namespace's complex type definitions). This is immutable
575 after creation.
576 """
577 return self.__targetNamespace
578 __targetNamespace = None
579
581 """The namespace in which this component's binding is placed."""
582 return self.__bindingNamespace
585 __bindingNamespace = None
586
588 """A map from template keys to component-specific values.
589
590 This is used in code generation to maintain unique names for accessor
591 methods, identifiers, keys, and other characteristics associated with
592 the code generated in support of the binding for this component."""
593 return self.__templateMap
594 __templateMap = None
595
596 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
597
603
605 """Return the schema component from which this component was defined.
606
607 Needed so we can distinguish components that came from different
608 locations, since that imposes an external order dependency on them and
609 on cross-namespace inclusions.
610
611 @note: This characteristic is removed when the component is stored in
612 a namespace archive."""
613 return self.__schema
614 __schema = None
615 __PrivateTransient.add('schema')
616
622
624 """Return C{True} if this component should be pickled by value in the
625 given namespace.
626
627 When pickling, a declaration component is considered to belong to the
628 namespace if it has a local scope which belongs to the namespace. In
629 that case, the declaration is a clone of something that does not
630 belong to the namespace; but the clone does.
631
632 @see: L{_bindsInNamespace}
633
634 @return: C{False} if the component should be pickled by reference.
635 """
636 if isinstance(self._scope(), ComplexTypeDefinition):
637 return self._scope()._picklesInArchive(archive)
638 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
639 assert not (self._objectOrigin() is None)
640 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
641 return new_flag
642
644 """Return C{True} if the binding for this component should be
645 generated in the given namespace.
646
647 This is the case when the component is in the given namespace. It's
648 also the case when the component has no associated namespace (but not
649 an absent namespace). Be aware that cross-namespace inheritance means
650 you will get references to elements in another namespace when
651 generating code for a subclass; that's fine, and those references
652 should not be generated locally.
653 """
654 return self.targetNamespace() in (ns, None)
655
661
663 """Pickling support.
664
665 Normally, we just create a new instance of this class.
666 However, if we're unpickling a reference in a loadable schema,
667 we need to return the existing component instance by looking
668 up the name in the component map of the desired namespace. We
669 can tell the difference because no normal constructors that
670 inherit from this have positional arguments; only invocations
671 by unpickling with a value returned in __getnewargs__ do.
672
673 This does require that the dependent namespace already have
674 been validated (or that it be validated here). That shouldn't
675 be a problem, except for the dependency loop resulting from
676 use of xml:lang in the XMLSchema namespace. For that issue,
677 see pyxb.namespace._XMLSchema.
678 """
679
680 if 0 == len(args):
681 rv = super(_NamedComponent_mixin, cls).__new__(cls)
682 return rv
683 ( object_reference, scope, icls ) = args
684
685 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
686
687
688
689 object_reference.validateComponentModel()
690 rv = None
691 if isinstance(scope, (tuple, _PickledAnonymousReference)):
692
693
694 scope_ref = _PickledAnonymousReference.FromPickled(scope)
695 if object_reference.namespace() != scope_ref.namespace():
696 scope_ref.validateComponentModel()
697 assert 'typeDefinition' in scope_ref.namespace().categories()
698 scope_ctd = scope_ref.typeDefinition()
699 if scope_ctd is None:
700 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
701 if issubclass(icls, AttributeDeclaration):
702 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
703 elif issubclass(icls, ElementDeclaration):
704 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
705 if rv is None:
706 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
707 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
708 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
709 rv = object_reference.typeDefinition()
710 elif issubclass(icls, AttributeGroupDefinition):
711 rv = object_reference.attributeGroupDefinition()
712 elif issubclass(icls, ModelGroupDefinition):
713 rv = object_reference.modelGroupDefinition()
714 elif issubclass(icls, AttributeDeclaration):
715 rv = object_reference.attributeDeclaration()
716 elif issubclass(icls, ElementDeclaration):
717 rv = object_reference.elementDeclaration()
718 elif issubclass(icls, IdentityConstraintDefinition):
719 rv = object_reference.identityConstraintDefinition()
720 if rv is None:
721 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
722 if rv is None:
723 raise pyxb.SchemaValidationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, scope.targetNamespace(), type(scope), icls))
724 return rv
725
746
748 """Return true iff this and the other component share the same name and target namespace.
749
750 Anonymous components are inherently name inequivalent, except to
751 themselves. This relies on equivalence as defined for
752 pyxb.namespace.ExpandedName, for which None is not equivalent to any
753 non-anonymous name."""
754
755 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
756
758 """Return True iff this and the other component have matching types.
759
760 It appears that name equivalence is used; two complex type definitions
761 with identical structures are not considered equivalent (at least, per
762 XMLSpy).
763 """
764 return (type(self) == type(other)) and self.isNameEquivalent(other)
765
767 """Return True iff this type can serve as a restriction of the other
768 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
769
770 It appears that name equivalence is normally used; two complex type
771 definitions with identical structures are not considered equivalent
772 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
773 that derivation by restriction from the other type is also acceptable.
774 That opens a whole can of worms; see
775 L{ElementDeclaration.isAdaptable}.
776 """
777 this = self
778
779 while this is not None:
780 if this.isTypeEquivalent(other):
781 return True
782
783 assert this.isResolved() and other.isResolved()
784 if isinstance(self, ComplexTypeDefinition):
785 if self.DM_restriction != this.derivationMethod():
786 return False
787 else:
788 assert isinstance(self, SimpleTypeDefinition)
789 if self._DA_restriction != this._derivationAlternative():
790 return False
791 this = this.baseTypeDefinition()
792 if this.isUrTypeDefinition():
793
794
795 break
796 return False
797
803
821
846
848 """Pickling support.
849
850 If this instance is being pickled as a reference, provide the
851 arguments that are necessary so that the unpickler can locate
852 the appropriate component rather than create a duplicate
853 instance."""
854
855 if self.__pickleAsReference():
856 scope = self._scope()
857 if isinstance(self, _ScopedDeclaration_mixin):
858
859
860
861
862
863 if self.SCOPE_global == self.scope():
864 pass
865 elif isinstance(self.scope(), ComplexTypeDefinition):
866 scope = self.scope()._picklingReference()
867 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
868 else:
869 assert self._scopeIsIndeterminate()
870
871
872 else:
873 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
874 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
875
876 rv = ( self._picklingReference(), scope, self.__class__ )
877 return rv
878 return ()
879
896
906
908 """Mix-in indicating that the component contains a simple-type
909 value that may be constrained."""
910
911 VC_na = 0
912 VC_default = 1
913 VC_fixed = 2
914
915
916
917 __valueConstraint = None
919 """A constraint on the value of the attribute or element.
920
921 Either None, or a pair consisting of a string in the lexical
922 space of the typeDefinition and one of VC_default and
923 VC_fixed."""
924 return self.__valueConstraint
925
934
943
960
962 """Mix-in class for named components that have a scope.
963
964 Scope is important when doing cross-namespace inheritance,
965 e.g. extending or restricting a complex type definition that is
966 from a different namespace. In this case, we will need to retain
967 a reference to the external component when the schema is
968 serialized.
969
970 This is done in the pickling process by including the scope when
971 pickling a component as a reference. The scope is the
972 SCOPE_global if global; otherwise, it is a tuple containing the
973 external namespace URI and the NCName of the complex type
974 definition in that namespace. We assume that the complex type
975 definition has global scope; otherwise, it should not have been
976 possible to extend or restrict it. (Should this be untrue, there
977 are comments in the code about a possible solution.)
978
979 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
980 """
981
982 SCOPE_global = 'global'
983 XSCOPE_indeterminate = 'indeterminate'
984
985 @classmethod
988
989 @classmethod
992
993 @classmethod
996
998 """Return True if this scope currently assigned to this instance is compatible with the given scope.
999
1000 If either scope is indeterminate, presume they will ultimately be
1001 compatible. Scopes that are equal are compatible, as is a local scope
1002 if this already has a global scope."""
1003 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
1004 return True
1005 if self.scope() == scope:
1006 return True
1007 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
1008
1009
1010
1011
1013 """The scope for the declaration.
1014
1015 Valid values are SCOPE_global, or a complex type definition.
1016 A value of None means a non-global declaration that is not
1017 owned by a complex type definition. These can only appear in
1018 attribute group definitions or model group definitions.
1019
1020 @todo: For declarations in named model groups (viz., local
1021 elements that aren't references), the scope needs to be set by
1022 the owning complex type.
1023 """
1024 return self._scope()
1025
1026
1027
1028
1029
1030 __baseDeclaration = None
1036
1038 """Support for components that accept attribute wildcards.
1039
1040 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1041 calculations of the appropriate wildcard are sufficiently complex that
1042 they need to be abstracted out to a mix-in class."""
1043
1044
1045 __attributeWildcard = None
1046
1048 """Return the L{Wildcard} component associated with attributes of this
1049 instance, or C{None} if attribute wildcards are not present in the
1050 instance."""
1051 return self.__attributeWildcard
1052
1054 """Set the attribute wildcard property for this instance."""
1055 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1056 self.__attributeWildcard = attribute_wildcard
1057 return self
1058
1060 """Return the nodes that are relevant for attribute processing.
1061
1062 @param node_list: A sequence of nodes found in a definition content
1063 information item.
1064
1065 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1066 where C{attributes} is the subsequence of C{node_list} that are
1067 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1068 C{attributeWildcard} is a single DOM node with XMLSchema name
1069 C{anyAttribute} (or C{None}, if no such node is present in the list).
1070
1071 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1072 present but does not have the required C{ref} attribute.
1073 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1074 identified.
1075 """
1076
1077 attributes = []
1078 attribute_groups = []
1079 any_attribute = None
1080
1081 for node in node_list:
1082 if Node.ELEMENT_NODE != node.nodeType:
1083 continue
1084 if xsd.nodeIsNamed(node, 'attribute'):
1085
1086 attributes.append(node)
1087 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1088
1089 agd_attr = domutils.NodeAttribute(node, 'ref')
1090 if agd_attr is None:
1091 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1092 attribute_groups.append(agd_attr)
1093 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1094 if any_attribute is not None:
1095 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1096 any_attribute = node
1097
1098 return (attributes, attribute_groups, any_attribute)
1099
1100 @classmethod
1101 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1102 """Implement the algorithm as described the
1103 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1104
1105 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1106 associated with any created L{Wildcard} instance
1107 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1108 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1109 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1110 is relevant
1111 """
1112
1113
1114 agd_wildcards = []
1115 for agd in attribute_groups:
1116 assert isinstance(agd, AttributeGroupDefinition)
1117 if agd.attributeWildcard() is not None:
1118 agd_wildcards.append(agd.attributeWildcard())
1119 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1120
1121
1122 if 0 == len(agd_wildcards):
1123 return local_wildcard
1124
1125 if local_wildcard is not None:
1126
1127 return Wildcard(process_contents=local_wildcard.processContents(),
1128 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1129 annotation=local_wildcard.annotation(),
1130 namespace_context=namespace_context)
1131
1132 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1133 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1134 namespace_context=namespace_context)
1135
1136 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1137 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1138 """
1139
1140
1141 __typeDefinition = None
1143 """The simple type definition to which an attribute value must
1144 conform."""
1145 return self.__typeDefinition
1146
1147
1148 __typeAttribute = None
1149
1153
1158
1159 @classmethod
1172
1173
1174 @classmethod
1176 """Create an attribute declaration from the given DOM node.
1177
1178 wxs is a Schema instance within which the attribute is being
1179 declared.
1180
1181 node is a DOM element. The name must be one of ( 'all',
1182 'choice', 'sequence' ), and the node must be in the XMLSchema
1183 namespace.
1184
1185 scope is the _ScopeDeclaration_mxin context into which the
1186 attribute declaration is placed. It can be SCOPE_global, a
1187 complex type definition, or XSCOPE_indeterminate if this is an
1188 anonymous declaration within an attribute group. It is a
1189 required parameter for this function.
1190 """
1191
1192 scope = kw['scope']
1193 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1194
1195
1196 assert xsd.nodeIsNamed(node, 'attribute')
1197
1198 name = domutils.NodeAttribute(node, 'name')
1199
1200
1201 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1202 assert cls.SCOPE_global == scope
1203 elif domutils.NodeAttribute(node, 'ref') is None:
1204
1205 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1206 else:
1207 raise pyxb.SchemaValidationError('Internal attribute declaration by reference')
1208
1209 rv = cls(name=name, node=node, **kw)
1210 rv._annotationFromDOM(node)
1211 rv._valueConstraintFromDOM(node)
1212
1213 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1214
1215 kw.pop('node', None)
1216 kw['owner'] = rv
1217
1218 st_node = domutils.LocateUniqueChild(node, 'simpleType')
1219 if st_node is not None:
1220 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw)
1221 elif rv.__typeAttribute is None:
1222 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition()
1223
1224 if rv.__typeDefinition is None:
1225 rv._queueForResolution('creation')
1226 return rv
1227
1230
1231
1247
1249 """Override fields in this instance with those from the other.
1250
1251 This method is invoked only by Schema._addNamedComponent, and
1252 then only when a built-in type collides with a schema-defined
1253 type. Material like facets is not (currently) held in the
1254 built-in copy, so the DOM information is copied over to the
1255 built-in STD, which is subsequently re-resolved.
1256
1257 Returns self.
1258 """
1259 assert self != other
1260 assert self.name() is not None
1261 assert self.isNameEquivalent(other)
1262 super(AttributeDeclaration, self)._updateFromOther_csc(other)
1263
1264
1265
1266 if not other.isResolved():
1267 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID():
1268
1269 _log.warning('Not destroying builtin %s: %s', self.expandedName(), self.__typeDefinition)
1270 else:
1271 self.__typeDefinition = None
1272 return self
1273
1274
1276 """Attribute declarations require their type."""
1277 return frozenset([ self.__typeDefinition ])
1278
1279 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1280 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component."""
1281
1282
1283
1284 __use = None
1285
1286 USE_required = 0x01
1287 USE_optional = 0x02
1288 USE_prohibited = 0x04
1289
1292
1295
1296
1297 __refAttribute = None
1298
1299 __restrictionOf = None
1307
1308
1310 """The attribute declaration for this use.
1311
1312 When the use scope is assigned, the declaration is cloned (if
1313 necessary) so that each declaration corresponds to only one use. We
1314 rely on this in code generation, because the template map for the use
1315 is stored in its declaration."""
1316 return self.__attributeDeclaration
1317 __attributeDeclaration = None
1318
1319
1322
1337
1338 @classmethod
1347
1348
1349 @classmethod
1351 """Create an Attribute Use from the given DOM node.
1352
1353 wxs is a Schema instance within which the attribute use is
1354 being defined.
1355
1356 node is a DOM element. The name must be 'attribute', and the
1357 node must be in the XMLSchema namespace.
1358
1359 scope is the _ScopeDeclaration_mixin context into which any
1360 required anonymous attribute declaration is put. This must be
1361 a complex type definition, or None if this use is in an
1362 attribute group.
1363 """
1364
1365 scope = kw['scope']
1366 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1367 assert xsd.nodeIsNamed(node, 'attribute')
1368 schema = kw['schema']
1369 rv = cls(node=node, **kw)
1370
1371 rv.__use = cls.USE_optional
1372 use = domutils.NodeAttribute(node, 'use')
1373 if use is not None:
1374 if 'required' == use:
1375 rv.__use = cls.USE_required
1376 elif 'optional' == use:
1377 rv.__use = cls.USE_optional
1378 elif 'prohibited' == use:
1379 rv.__use = cls.USE_prohibited
1380 else:
1381 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1382
1383 rv._valueConstraintFromDOM(node)
1384
1385 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
1386 if rv.__refAttribute is None:
1387
1388 kw.pop('node', None)
1389 kw['owner'] = rv
1390 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1391 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1392
1393 if not rv.isResolved():
1394 rv._queueForResolution('creation')
1395
1396 return rv
1397
1400
1412
1413
1415 """Attribute uses require their declarations, but only if lax."""
1416 if not include_lax:
1417 return frozenset()
1418 return frozenset([ self.attributeDeclaration() ])
1419
1420
1440
1443
1444
1445 -class ElementDeclaration (_ParticleTree_mixin, _SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1446 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1447
1448
1449 __typeDefinition = None
1451 """The simple or complex type to which the element value conforms."""
1452 return self.__typeDefinition
1456
1457 __substitutionGroupAttribute = None
1458
1459 __typeAttribute = None
1460
1461 __nillable = False
1464
1465 __identityConstraintDefinitions = None
1469
1470 __substitutionGroupAffiliation = None
1474
1475 SGE_none = 0
1476 SGE_extension = 0x01
1477 SGE_restriction = 0x02
1478 SGE_substitution = 0x04
1479
1480 _SGE_Map = { 'extension' : SGE_extension
1481 , 'restriction' : SGE_restriction }
1482 _DS_Map = _SGE_Map.copy()
1483 _DS_Map.update( { 'substitution' : SGE_substitution } )
1484
1485
1486 __substitutionGroupExclusions = SGE_none
1487
1488
1489 __disallowedSubstitutions = SGE_none
1490
1491 __abstract = False
1494
1496 """Return False, since element declarations are not wildcards."""
1497 return False
1498
1499
1501 """Element declarations depend on the type definition of their
1502 content."""
1503 return frozenset([self.__typeDefinition])
1504
1507
1508
1509 @classmethod
1511 """Create an element declaration from the given DOM node.
1512
1513 wxs is a Schema instance within which the element is being
1514 declared.
1515
1516 scope is the _ScopeDeclaration_mixin context into which the
1517 element declaration is recorded. It can be SCOPE_global, a
1518 complex type definition, or None in the case of elements
1519 declared in a named model group.
1520
1521 node is a DOM element. The name must be 'element', and the
1522 node must be in the XMLSchema namespace."""
1523
1524 scope = kw['scope']
1525 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1526
1527
1528 assert xsd.nodeIsNamed(node, 'element')
1529
1530
1531 name = domutils.NodeAttribute(node, 'name')
1532 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1533 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1534 elif domutils.NodeAttribute(node, 'ref') is None:
1535
1536 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1537 else:
1538 raise pyxb.SchemaValidationError('Created reference as element declaration')
1539
1540 rv = cls(name=name, node=node, **kw)
1541 rv._annotationFromDOM(node)
1542 rv._valueConstraintFromDOM(node)
1543
1544 rv.__substitutionGroupAttribute = domutils.NodeAttribute(node, 'substitutionGroup')
1545
1546 kw.pop('node', None)
1547 kw['owner'] = rv
1548
1549 identity_constraints = []
1550 for cn in node.childNodes:
1551 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1552 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1553 rv.__identityConstraintDefinitions = identity_constraints
1554
1555 rv.__typeDefinition = None
1556 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1557 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1558 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1559 if rv.__typeAttribute is not None:
1560 if (simpleType_node is not None) and (complexType_node is not None):
1561 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1562 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1563 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw)
1564 if (rv.__typeDefinition is None) and (complexType_node is not None):
1565 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw)
1566 if rv.__typeDefinition is None:
1567 if rv.__typeAttribute is None:
1568
1569 for cn in node.childNodes:
1570 if Particle.IsParticleNode(cn):
1571 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1572 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition()
1573 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1574 if not rv.__isResolved:
1575 rv._queueForResolution('creation')
1576
1577 attr_val = domutils.NodeAttribute(node, 'nillable')
1578 if attr_val is not None:
1579 rv.__nillable = datatypes.boolean(attr_val)
1580
1581 attr_val = domutils.NodeAttribute(node, 'abstract')
1582 if attr_val is not None:
1583 rv.__abstract = datatypes.boolean(attr_val)
1584
1585 schema = kw['schema']
1586 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1587 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1588
1589 return rv
1590
1592 """Determine whether this element declaration is adaptable.
1593
1594 OK, this gets ugly. First, if this declaration isn't resolved, it's
1595 clearly not adaptable.
1596
1597 Now: For it to be adaptable, we must know enough about its type to
1598 verify that it is derivation-consistent with any other uses of the
1599 same name in the same complex type. If the element's type is
1600 resolved, that's good enough.
1601
1602 If the element's type isn't resolved, we're golden as long as
1603 type-equivalent types were used. But it's also allowed for the
1604 derived ctd to use the element name constraining it to a derivation of
1605 the element base type. (Go see namespace
1606 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1607 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1608 have to have the element's type resolved.
1609
1610 Except that if a CTD's content incorporates an element with the same
1611 type as the CTD (i.e., nested), this will never happen, because the
1612 CTD can't get resolved until after it has been resolved.
1613 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1614 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1615 an example).
1616
1617 So, we give the world a break and assume that if the type we're trying
1618 to resolve is the same as the type of an element in that type, then
1619 the element type will be resolved by the point it's needed. In point
1620 of fact, it won't, but we'll only notice that if a CTD contains an
1621 element whose type is a restriction of the CTD. In that case,
1622 isDerivationConsistent will blow chunks and somebody'll have to come
1623 back and finish up this mess.
1624 """
1625
1626 if not self.isResolved():
1627 return False
1628 if self.typeDefinition().isResolved():
1629 return True
1630
1631
1632 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1633 if existing_decl is None:
1634
1635
1636 return True
1637
1638 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1639
1640 return True
1641
1642
1643 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1644 return False
1645
1646
1656
1657 __isResolved = False
1660
1661
1684
1685 - def _walkParticleTree (self, visit, arg):
1686 visit(self, None, arg)
1687
1692
1693
1694 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1695 __PrivateTransient = set()
1696
1697
1698 __baseTypeDefinition = None
1702
1703 DM_empty = 0
1704 DM_extension = 0x01
1705 DM_restriction = 0x02
1706
1707 _DM_Map = { 'extension' : DM_extension
1708 , 'restriction' : DM_restriction }
1709
1710
1711
1712 __derivationMethod = None
1716
1717
1718 __final = DM_empty
1719
1720
1721 __abstract = False
1724
1725
1726 __attributeUses = None
1728 """A frozenset() of AttributeUse instances."""
1729 return self.__attributeUses
1730
1731
1732
1733 __scopedAttributeDeclarations = None
1741
1742
1743
1744 __scopedElementDeclarations = None
1752
1753 __localScopedDeclarations = None
1755 """Return a list of element and attribute declarations that were
1756 introduced in this definition (i.e., their scope is this CTD).
1757
1758 @note: This specifically returns a list, with element declarations
1759 first, because name binding should privilege the elements over the
1760 attributes. Within elements and attributes, the components are sorted
1761 by expanded name, to ensure consistency across a series of binding
1762 generations.
1763
1764 @keyword reset: If C{False} (default), a cached previous value (if it
1765 exists) will be returned.
1766 """
1767 if reset or (self.__localScopedDeclarations is None):
1768 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1769 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1770 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1771 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1772 self.__localScopedDeclarations = rve
1773 self.__localScopedDeclarations.extend(rva)
1774 return self.__localScopedDeclarations
1775
1777 """Record the given declaration as being locally scoped in
1778 this type."""
1779 assert isinstance(decl, _ScopedDeclaration_mixin)
1780 if isinstance(decl, ElementDeclaration):
1781 scope_map = self.__scopedElementDeclarations
1782 elif isinstance(decl, AttributeDeclaration):
1783 scope_map = self.__scopedAttributeDeclarations
1784 else:
1785 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1786 decl_en = decl.expandedName()
1787 existing_decl = scope_map.setdefault(decl_en, decl)
1788 if decl != existing_decl:
1789 if isinstance(decl, ElementDeclaration):
1790
1791 existing_type = existing_decl.typeDefinition()
1792 pending_type = decl.typeDefinition()
1793 if not pending_type.isDerivationConsistent(existing_type):
1794 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1795 elif isinstance(decl, AttributeDeclaration):
1796 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1797 else:
1798 assert False, 'Unrecognized type %s' % (type(decl),)
1799 decl._baseDeclaration(existing_decl)
1800 return self
1801
1807
1808 CT_EMPTY = 'EMPTY'
1809 CT_SIMPLE = 'SIMPLE'
1810 CT_MIXED = 'MIXED'
1811 CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1812
1813 - def _contentTypeTag (self):
1814 """Return the value of the content type identifier, i.e. one of the
1815 CT_ constants. Return value is None if no content type has been
1816 defined."""
1817 if isinstance(self.__contentType, tuple):
1818 return self.__contentType[0]
1819 return self.__contentType
1820
1822 if isinstance(self.__contentType, tuple):
1823 return self.__contentType[1]
1824 return None
1825
1826
1827 __contentType = None
1828 - def contentType (self):
1829 """Identify the sort of content in this type.
1830
1831 Valid values are:
1832 - C{CT_EMPTY}
1833 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1834 - ( C{CT_MIXED}, a L{Particle} instance )
1835 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1836 """
1837 return self.__contentType
1838
1840 if self.CT_EMPTY == self.contentType():
1841 return 'EMPTY'
1842 ( tag, particle ) = self.contentType()
1843 if self.CT_SIMPLE == tag:
1844 return 'Simple [%s]' % (particle,)
1845 if self.CT_MIXED == tag:
1846 return 'Mixed [%s]' % (particle,)
1847 if self.CT_ELEMENT_ONLY == tag:
1848 return 'Element [%s]' % (particle,)
1849 raise pyxb.LogicError('Unhandled content type')
1850
1851
1852 __prohibitedSubstitutions = DM_empty
1853
1854
1855 __annotations = None
1856
1862
1872
1874 """Override fields in this instance with those from the other.
1875
1876 This method is invoked only by Schema._addNamedComponent, and
1877 then only when a built-in type collides with a schema-defined
1878 type. Material like facets is not (currently) held in the
1879 built-in copy, so the DOM information is copied over to the
1880 built-in STD, which is subsequently re-resolved.
1881
1882 Returns self.
1883 """
1884 assert self != other
1885 assert self.isNameEquivalent(other)
1886 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1887
1888 if not other.isResolved():
1889 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1890 self.__derivationMethod = None
1891
1892 return self
1893
1894 __UrTypeDefinition = None
1895 @classmethod
1897 """Create the ComplexTypeDefinition instance that approximates
1898 the ur-type.
1899
1900 See section 3.4.7.
1901 """
1902
1903
1904
1905
1906
1907
1908
1909 if cls.__UrTypeDefinition is None:
1910
1911 assert schema is not None
1912
1913 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1914
1915 kw = { 'name' : 'anyType',
1916 'schema' : schema,
1917 'namespace_context' : ns_ctx,
1918 'binding_namespace' : schema.targetNamespace(),
1919 'derivation_method' : cls.DM_restriction,
1920 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1921 bi = _UrTypeDefinition(**kw)
1922
1923
1924 bi.__baseTypeDefinition = bi
1925
1926
1927 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1928
1929
1930
1931
1932
1933
1934 kw = { 'namespace_context' : ns_ctx
1935 , 'schema' : schema
1936 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
1937 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
1938 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
1939 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
1940 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
1941
1942
1943 bi.__attributeUses = set()
1944
1945
1946 bi.__final = cls.DM_empty
1947 bi.__prohibitedSubstitutions = cls.DM_empty
1948
1949 bi.__abstract = False
1950
1951
1952 bi.setNameInBinding(bi.name())
1953
1954
1955 bi.__derivationMethod = cls.DM_restriction
1956
1957 cls.__UrTypeDefinition = bi
1958 return cls.__UrTypeDefinition
1959
1961 """Indicate whether this simple type is a built-in type."""
1962 return (self.UrTypeDefinition() == self)
1963
1964
1980
1981
1982 @classmethod
2006
2007 __baseAttribute = None
2008
2009
2010 __ckw = None
2011 __anyAttribute = None
2012 __attributeGroupAttributes = None
2013 __usesC1 = None
2014 __usesC1C2 = None
2015 __attributeGroups = None
2016 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2017
2018
2020
2021 if self.__usesC1C2 is None:
2022
2023 uses_c1 = self.__usesC1
2024 uses_c2 = set()
2025 self.__attributeGroups = []
2026 for ag_attr in self.__attributeGroupAttributes:
2027 ag_en = self._namespaceContext().interpretQName(ag_attr)
2028 agd = ag_en.attributeGroupDefinition()
2029 if agd is None:
2030 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2031 if not agd.isResolved():
2032 self._queueForResolution('unresolved attribute group', depends_on=agd)
2033 return self
2034 self.__attributeGroups.append(agd)
2035 uses_c2.update(agd.attributeUses())
2036
2037 uses_c1c2 = uses_c1.union(uses_c2)
2038 for au in uses_c1c2:
2039 if not au.isResolved():
2040 self._queueForResolution('attribute use not resolved')
2041 return self
2042 ad = au.attributeDeclaration()
2043 if not ad.isResolved():
2044 ad_en = ad.expandedName()
2045 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2046 return self
2047
2048 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2049
2050
2051
2052
2053
2054
2055 uses_c3 = set()
2056 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2057
2058
2059 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2060 assert self.__baseTypeDefinition.isResolved()
2061 for au in uses_c3:
2062 if not au.isResolved():
2063 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2064 return self
2065 ad = au.attributeDeclaration()
2066 if not ad.isResolved():
2067 ad_en = ad.expandedName()
2068 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2069 return self
2070 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2071
2072 if self.DM_restriction == method:
2073
2074
2075
2076 for au in self.__usesC1C2:
2077 matching_uses = au.matchingQNameMembers(uses_c3)
2078 assert matching_uses is not None
2079 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2080 for au2 in matching_uses:
2081 assert au2.isResolved()
2082 uses_c3.remove(au2)
2083 au._setRestrictionOf(au2)
2084 else:
2085
2086
2087
2088 assert self.DM_extension == method
2089
2090 use_map = { }
2091 for au in self.__usesC1C2.union(uses_c3):
2092 assert au.isResolved()
2093 ad_en = au.attributeDeclaration().expandedName()
2094 if ad_en in use_map:
2095 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2096 use_map[ad_en] = au
2097
2098
2099
2100 self.__attributeUses = frozenset(use_map.values())
2101 if not self._scopeIsIndeterminate():
2102 for au in self.__attributeUses:
2103 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2104
2105
2106
2107 local_wildcard = None
2108 if self.__anyAttribute is not None:
2109 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2110
2111
2112 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2113
2114
2115 if self.DM_restriction == method:
2116
2117 self._setAttributeWildcard(complete_wildcard)
2118 else:
2119 assert (self.DM_extension == method)
2120 assert self.baseTypeDefinition().isResolved()
2121
2122 base_wildcard = None
2123 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2124 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2125
2126 if base_wildcard is not None:
2127 if complete_wildcard is None:
2128
2129 self._setAttributeWildcard(base_wildcard)
2130 else:
2131
2132 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2133 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2134 base_wildcard.namespaceConstraint()]),
2135 annotation=complete_wildcard.annotation(),
2136 namespace_context=self._namespaceContext()))
2137 else:
2138
2139 self._setAttributeWildcard(complete_wildcard)
2140
2141
2142
2143
2144 del self.__usesC1
2145 del self.__usesC1C2
2146 del self.__attributeGroups
2147 self.__ckw = None
2148
2149
2150
2151
2152 self.__derivationMethod = method
2153 return self
2154
2155 - def __simpleContent (self, method, **kw):
2156
2157 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2158
2159 parent_content_type = self.__baseTypeDefinition.__contentType
2160 if ((type(parent_content_type) == tuple) \
2161 and (self.CT_SIMPLE == parent_content_type[0]) \
2162 and (self.DM_restriction == method)):
2163
2164 assert self.__ctscRestrictionNode is not None
2165 std = self.__ctscClause2STD
2166 if std is None:
2167 std = parent_content_type[1]
2168 assert isinstance(std, SimpleTypeDefinition)
2169 if not std.isResolved():
2170 return None
2171 restriction_node = self.__ctscRestrictionNode
2172 self.__ctscClause2STD = None
2173 self.__ctscRestrictionNode = None
2174 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2175 if ((type(parent_content_type) == tuple) \
2176 and (self.CT_MIXED == parent_content_type[0]) \
2177 and parent_content_type[1].isEmptiable()):
2178
2179 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2180 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2181
2182 return parent_content_type
2183
2184 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2185
2186 __ctscClause2STD = None
2187 __ctscRestrictionNode = None
2188 __effectiveMixed = None
2189 __effectiveContent = None
2190 __pendingDerivationMethod = None
2191 __isComplexContent = None
2192 __ctscRestrictionMode = None
2193 __contentStyle = None
2194
2195 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2196
2197
2198 ckw = kw.copy()
2199 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2200
2201
2202 mixed_attr = None
2203 if content_node is not None:
2204 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2205 if mixed_attr is None:
2206 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2207 if mixed_attr is not None:
2208 effective_mixed = datatypes.boolean(mixed_attr)
2209 else:
2210 effective_mixed = False
2211
2212
2213 test_2_1_1 = True
2214 test_2_1_2 = False
2215 test_2_1_3 = False
2216 typedef_node = None
2217 for cn in definition_node_list:
2218 if Node.ELEMENT_NODE != cn.nodeType:
2219 continue
2220 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2221
2222 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2223 if Particle.IsTypedefNode(cn):
2224 typedef_node = cn
2225 test_2_1_1 = False
2226 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2227 and (not domutils.HasNonAnnotationChild(cn)):
2228 test_2_1_2 = True
2229 if xsd.nodeIsNamed(cn, 'choice') \
2230 and (not domutils.HasNonAnnotationChild(cn)):
2231 mo_attr = domutils.NodeAttribute(cn, 'minOccurs')
2232 if ((mo_attr is not None) \
2233 and (0 == datatypes.integer(mo_attr))):
2234 test_2_1_3 = True
2235 satisfied_predicates = 0
2236 if test_2_1_1:
2237 satisfied_predicates += 1
2238 if test_2_1_2:
2239 satisfied_predicates += 1
2240 if test_2_1_3:
2241 satisfied_predicates += 1
2242 if 1 == satisfied_predicates:
2243 if effective_mixed:
2244
2245 assert (typedef_node is None) or test_2_1_2
2246 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2247 effective_content = Particle(m, **ckw)
2248 else:
2249
2250 effective_content = self.CT_EMPTY
2251 else:
2252
2253 assert typedef_node is not None
2254 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2255
2256
2257
2258
2259
2260
2261
2262 self.__effectiveMixed = effective_mixed
2263 self.__effectiveContent = effective_content
2264 self.__ckw = ckw
2265
2266 - def __complexContent (self, method):
2267 ckw = self.__ckw
2268
2269
2270 if self.__effectiveMixed:
2271 ct = self.CT_MIXED
2272 else:
2273 ct = self.CT_ELEMENT_ONLY
2274
2275 if self.DM_restriction == method:
2276
2277 if self.CT_EMPTY == self.__effectiveContent:
2278
2279 content_type = self.CT_EMPTY
2280 else:
2281
2282 content_type = ( ct, self.__effectiveContent )
2283 assert 0 == len(self.__scopedElementDeclarations)
2284
2285
2286
2287
2288 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2289 else:
2290
2291 assert self.DM_extension == method
2292 assert self.__baseTypeDefinition.isResolved()
2293 parent_content_type = self.__baseTypeDefinition.contentType()
2294 if self.CT_EMPTY == self.__effectiveContent:
2295 content_type = parent_content_type
2296 elif self.CT_EMPTY == parent_content_type:
2297
2298 content_type = ( ct, self.__effectiveContent )
2299 else:
2300 assert type(parent_content_type) == tuple
2301 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2302 content_type = ( ct, Particle(m, **ckw) )
2303
2304 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2305 return content_type
2306
2308 """Indicate whether this complex type is fully defined.
2309
2310 All built-in type definitions are resolved upon creation.
2311 Schema-defined type definitionss are held unresolved until the
2312 schema has been completely read, so that references to later
2313 schema-defined types can be resolved. Resolution is performed
2314 after the entire schema has been scanned and type-definition
2315 instances created for all topLevel{Simple,Complex}Types.
2316
2317 If a built-in type definition is also defined in a schema
2318 (which it should be), the built-in definition is kept, with
2319 the schema-related information copied over from the matching
2320 schema-defined type definition. The former then replaces the
2321 latter in the list of type definitions to be resolved. See
2322 Schema._addNamedComponent.
2323 """
2324
2325 return (self.__derivationMethod is not None)
2326
2327
2328
2332
2333 - def __setContentFromDOM (self, node, **kw):
2334 schema = kw.get('schema')
2335 assert schema is not None
2336 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2337 self.__final = schema.finalForNode(node, self._DM_Map)
2338
2339 attr_val = domutils.NodeAttribute(node, 'abstract')
2340 if attr_val is not None:
2341 self.__abstract = datatypes.boolean(attr_val)
2342
2343
2344
2345 definition_node_list = node.childNodes
2346 is_complex_content = True
2347 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2348 method = self.DM_restriction
2349
2350
2351
2352
2353 first_elt = domutils.LocateFirstChildElement(node)
2354 content_node = None
2355 clause2_std = None
2356 ctsc_restriction_node = None
2357 if first_elt:
2358 have_content = False
2359 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2360 have_content = True
2361 is_complex_content = False
2362 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2363 have_content = True
2364 else:
2365
2366
2367 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2368 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2369 if have_content:
2370
2371 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2372 assert content_node == first_elt
2373
2374
2375
2376 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2377 if xsd.nodeIsNamed(ions, 'restriction'):
2378 method = self.DM_restriction
2379 if not is_complex_content:
2380
2381 ctsc_restriction_node = ions
2382 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2383 if ions_st is not None:
2384 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2385 elif xsd.nodeIsNamed(ions, 'extension'):
2386 method = self.DM_extension
2387 else:
2388 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2389 self.__baseAttribute = domutils.NodeAttribute(ions, 'base')
2390 if self.__baseAttribute is None:
2391 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2392 self.__baseTypeDefinition = None
2393
2394 definition_node_list = ions.childNodes
2395
2396 self.__pendingDerivationMethod = method
2397 self.__isComplexContent = is_complex_content
2398 self.__ctscRestrictionNode = ctsc_restriction_node
2399 self.__ctscClause2STD = clause2_std
2400
2401 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2402 self.__usesC1 = set()
2403 for cn in attributes:
2404 au = AttributeUse.CreateFromDOM(cn, **kw)
2405 self.__usesC1.add(au)
2406 self.__attributeGroupAttributes = attribute_group_attrs
2407 self.__anyAttribute = any_attribute
2408
2409 if self.__isComplexContent:
2410 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2411
2412
2413
2414 self._annotationFromDOM(node)
2415
2416 if not self.isResolved():
2417 self._queueForResolution('creation')
2418
2419 return self
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2485
2487 """Complex type definitions have no built-in type support."""
2488 return None
2489
2494
2496 """Subclass ensures there is only one ur-type."""
2498 """The ur-type does have a Python class backing it up."""
2499 return datatypes.anyType
2500
2505
2506
2507 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2618
2620 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2621
2622 __modelGroup = None
2623
2625 """The model group for which this definition provides a name."""
2626 return self.__modelGroup
2627
2628
2629 @classmethod
2631 """Create a Model Group Definition from a DOM element node.
2632
2633 wxs is a Schema instance within which the model group is being
2634 defined.
2635
2636 node is a DOM element. The name must be 'group', and the node
2637 must be in the XMLSchema namespace. The node must have a
2638 'name' attribute, and must not have a 'ref' attribute.
2639 """
2640 assert xsd.nodeIsNamed(node, 'group')
2641
2642 assert domutils.NodeAttribute(node, 'ref') is None
2643
2644 name = domutils.NodeAttribute(node, 'name')
2645 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2646 rv = cls(name=name, node=node, **kw)
2647 rv._annotationFromDOM(node)
2648
2649 kw.pop('node', None)
2650 kw['owner'] = rv
2651
2652 for cn in node.childNodes:
2653 if Node.ELEMENT_NODE != cn.nodeType:
2654 continue
2655 if ModelGroup.IsGroupMemberNode(cn):
2656 assert not rv.__modelGroup
2657
2658
2659
2660 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2661 assert rv.__modelGroup is not None
2662 return rv
2663
2664
2666 """Model group definitions depend on the contained model group."""
2667 if not include_lax:
2668 return frozenset()
2669 return frozenset([self.__modelGroup])
2670
2673
2674
2675 -class ModelGroup (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
2676 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2677 C_INVALID = 0
2678 C_ALL = 0x01
2679 C_CHOICE = 0x02
2680 C_SEQUENCE = 0x03
2681
2682
2683
2684 __compositor = C_INVALID
2687
2688 @classmethod
2698
2702
2703
2704
2705 __particles = None
2706 - def particles (self):
2707 return self.__particles
2708
2710 """A model group has an unresolvable particle if any of its
2711 particles is unresolvable. Duh."""
2712 for p in self.particles():
2713 if not p.isAdaptable(ctd):
2714 return False
2715 return True
2716
2718 """Return the minimum and maximum of the number of elements that can
2719 appear in a sequence matched by this particle.
2720
2721 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2722 """
2723 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2724 sum_minoccurs = 0
2725 sum_maxoccurs = 0
2726 for prt in self.__particles:
2727 (prt_min, prt_max) = prt.effectiveTotalRange()
2728 sum_minoccurs += prt_min
2729 if sum_maxoccurs is not None:
2730 if prt_max is None:
2731 sum_maxoccurs = None
2732 else:
2733 sum_maxoccurs += prt_max
2734 prod_maxoccurs = particle.maxOccurs()
2735 if prod_maxoccurs is not None:
2736 if sum_maxoccurs is None:
2737 prod_maxoccurs = None
2738 else:
2739 prod_maxoccurs *= sum_maxoccurs
2740 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2741 assert self.__compositor == self.C_CHOICE
2742 if 0 == len(self.__particles):
2743 min_minoccurs = 0
2744 max_maxoccurs = 0
2745 else:
2746 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2747 for prt in self.__particles[1:]:
2748 (prt_min, prt_max) = prt.effectiveTotalRange()
2749 if prt_min < min_minoccurs:
2750 min_minoccurs = prt_min
2751 if prt_max is None:
2752 max_maxoccurs = None
2753 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2754 max_maxoccurs = prt_max
2755 min_minoccurs *= particle.minOccurs()
2756 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2757 max_maxoccurs *= particle.maxOccurs()
2758 return (min_minoccurs, max_maxoccurs)
2759
2760
2761
2762
2763 __modelGroupDefinition = None
2765 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2766 return self.__modelGroupDefinition
2767
2768 - def __init__ (self, compositor, particles, *args, **kw):
2769 """Create a new model group.
2770
2771 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2772
2773 particles must be a list of zero or more Particle instances.
2774
2775 scope is the _ScopeDeclaration_mixin context into which new
2776 declarations are recorded. It can be SCOPE_global, a complex
2777 type definition, or None if this is (or is within) a named
2778 model group.
2779
2780 model_group_definition is an instance of ModelGroupDefinition
2781 if this is a named model group. It defaults to None
2782 indicating a local group.
2783 """
2784
2785 super(ModelGroup, self).__init__(*args, **kw)
2786 assert 'scope' in kw
2787 self.__compositor = compositor
2788 self.__particles = particles
2789 self.__modelGroupDefinition = kw.get('model_group_definition')
2790
2792 """Return True if the model includes a wildcard amongst its particles."""
2793 for p in self.particles():
2794 if p.hasWildcardElement():
2795 return True
2796 return False
2797
2798
2800 if not include_lax:
2801 return frozenset()
2802 return frozenset(self.__particles)
2803
2804
2805 @classmethod
2807 """Create a model group from the given DOM node.
2808
2809 wxs is a Schema instance within which the model group is being
2810 defined.
2811
2812 node is a DOM element. The name must be one of ( 'all',
2813 'choice', 'sequence' ), and the node must be in the XMLSchema
2814 namespace.
2815
2816 scope is the _ScopeDeclaration_mxin context that is assigned
2817 to declarations that appear within the model group. It can be
2818 None, indicating no scope defined, or a complex type
2819 definition.
2820 """
2821
2822 scope = kw['scope']
2823 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2824
2825 if xsd.nodeIsNamed(node, 'all'):
2826 compositor = cls.C_ALL
2827 elif xsd.nodeIsNamed(node, 'choice'):
2828 compositor = cls.C_CHOICE
2829 else:
2830 assert xsd.nodeIsNamed(node, 'sequence')
2831 compositor = cls.C_SEQUENCE
2832 particles = []
2833
2834 kw.pop('owner', None)
2835 for cn in node.childNodes:
2836 if Node.ELEMENT_NODE != cn.nodeType:
2837 continue
2838 if Particle.IsParticleNode(cn):
2839
2840 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2841 elif not xsd.nodeIsNamed(cn, 'annotation'):
2842 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2843 rv = cls(compositor, particles, node=node, **kw)
2844 for p in particles:
2845 p._setOwner(rv)
2846 rv._annotationFromDOM(node)
2847 return rv
2848
2849 @classmethod
2852
2853
2864
2865 - def _walkParticleTree (self, visit, arg):
2866 visit(self, True, arg)
2867 for p in self.particles():
2868 p._walkParticleTree(visit, arg)
2869 visit(self, False, arg)
2870
2880
2881 -class Particle (_ParticleTree_mixin, _SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2882 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2883
2884
2885 __minOccurs = 1
2886 - def minOccurs (self):
2887 """The minimum number of times the term may appear.
2888
2889 Defaults to 1."""
2890 return self.__minOccurs
2891
2892
2893 __maxOccurs = 1
2894 - def maxOccurs (self):
2895 """Upper limit on number of times the term may appear.
2896
2897 If None, the term may appear any number of times; otherwise,
2898 this is an integral value indicating the maximum number of times
2899 the term may appear. The default value is 1; the value, unless
2900 None, must always be at least minOccurs().
2901 """
2902 return self.__maxOccurs
2903
2904
2905 __term = None
2907 """A reference to a ModelGroup, Wildcard, or ElementDeclaration."""
2908 return self.__term
2909 __pendingTerm = None
2910
2911 __refAttribute = None
2912 __resolvableType = None
2913
2915 """Extend the concept of effective total range to all particles.
2916
2917 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
2918 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
2919 """
2920 if isinstance(self.__term, ModelGroup):
2921 return self.__term.effectiveTotalRange(self)
2922 return (self.minOccurs(), self.maxOccurs())
2923
2924 - def isEmptiable (self):
2925 """Return C{True} iff this particle can legitimately match an empty
2926 sequence (no content).
2927
2928 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
2929 """
2930 return 0 == self.effectiveTotalRange()[0]
2931
2933 """Return True iff this particle has a wildcard in its term.
2934
2935 Note that the wildcard may be in a nested model group."""
2936 return self.term().hasWildcardElement()
2937
2938 - def __init__ (self, term, *args, **kw):
2939 """Create a particle from the given DOM node.
2940
2941 term is a XML Schema Component: one of ModelGroup,
2942 ElementDeclaration, and Wildcard.
2943
2944 The following keyword arguments are processed:
2945
2946 min_occurs is a non-negative integer value with default 1,
2947 denoting the minimum number of terms required by the content
2948 model.
2949
2950 max_occurs is a positive integer value with default 1, or None
2951 indicating unbounded, denoting the maximum number of terms
2952 allowed by the content model.
2953
2954 scope is the _ScopeDeclaration_mxin context that is assigned
2955 to declarations that appear within the particle. It can be
2956 None, indicating no scope defined, or a complex type
2957 definition.
2958 """
2959
2960 super(Particle, self).__init__(*args, **kw)
2961
2962 min_occurs = kw.get('min_occurs', 1)
2963 max_occurs = kw.get('max_occurs', 1)
2964
2965 assert 'scope' in kw
2966 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
2967
2968 if term is not None:
2969 self.__term = term
2970
2971 assert isinstance(min_occurs, (types.IntType, types.LongType))
2972 self.__minOccurs = min_occurs
2973 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
2974 self.__maxOccurs = max_occurs
2975 if self.__maxOccurs is not None:
2976 if self.__minOccurs > self.__maxOccurs:
2977 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
2978
2979
2980 - def _resolve (self):
2981 if self.isResolved():
2982 return self
2983
2984
2985 if ModelGroup == self.__resolvableType:
2986 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
2987 group_decl = ref_en.modelGroupDefinition()
2988 if group_decl is None:
2989 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
2990
2991 self.__pendingTerm = group_decl.modelGroup()
2992 assert self.__pendingTerm is not None
2993 elif ElementDeclaration == self.__resolvableType:
2994
2995
2996
2997 if self.__refAttribute is not None:
2998 assert self.__pendingTerm is None
2999 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3000 self.__pendingTerm = ref_en.elementDeclaration()
3001 if self.__pendingTerm is None:
3002 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3003 assert self.__pendingTerm is not None
3004
3005
3006
3007
3008 assert self.__pendingTerm is not None
3009 else:
3010 assert False
3011
3012 self.__term = self.__pendingTerm
3013 assert self.__term is not None
3014 return self
3015
3016 - def isResolved (self):
3017 return self.__term is not None
3018
3019
3020 @classmethod
3021 - def CreateFromDOM (cls, node, **kw):
3022 """Create a particle from the given DOM node.
3023
3024 wxs is a Schema instance within which the model group is being
3025 defined.
3026
3027 node is a DOM element. The name must be one of ( 'group',
3028 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3029 must be in the XMLSchema namespace.
3030
3031 scope is the _ScopeDeclaration_mxin context that is assigned
3032 to declarations that appear within the model group. It can be
3033 None, indicating no scope defined, or a complex type
3034 definition.
3035 """
3036 scope = kw['scope']
3037 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3038
3039 kw.update({ 'min_occurs' : 1
3040 , 'max_occurs' : 1
3041 , 'node' : node })
3042
3043 if not Particle.IsParticleNode(node):
3044 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3045 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3046 if attr_val is not None:
3047 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3048 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3049 if attr_val is not None:
3050 if 'unbounded' == attr_val:
3051 kw['max_occurs'] = None
3052 else:
3053 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3054
3055 rv = cls(None, **kw)
3056
3057 kw.pop('node', None)
3058 kw['owner'] = rv
3059
3060 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
3061 rv.__pendingTerm = None
3062 rv.__resolvableType = None
3063 if xsd.nodeIsNamed(node, 'group'):
3064
3065
3066
3067 if rv.__refAttribute is None:
3068 raise pyxb.SchemaValidationError('group particle without reference')
3069 rv.__resolvableType = ModelGroup
3070 elif xsd.nodeIsNamed(node, 'element'):
3071 if rv.__refAttribute is None:
3072 schema = kw.get('schema')
3073 assert schema is not None
3074 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3075 incoming_tns = kw.get('target_namespace')
3076 if incoming_tns is not None:
3077 assert incoming_tns == target_namespace
3078 else:
3079 kw['target_namespace'] = target_namespace
3080 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3081 else:
3082
3083
3084
3085 rv.__resolvableType = ElementDeclaration
3086 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3087 elif xsd.nodeIsNamed(node, 'any'):
3088
3089 rv.__term = Wildcard.CreateFromDOM(node=node)
3090 elif ModelGroup.IsGroupMemberNode(node):
3091
3092
3093
3094 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3095 else:
3096 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3097
3098 if not rv.isResolved():
3099 rv._queueForResolution('creation')
3100 return rv
3101
3102
3103 - def _bindingRequires_vx (self, include_lax):
3104 if not include_lax:
3105 return frozenset()
3106 return frozenset([ self.__term ])
3107
3108
3109 - def _adaptForScope (self, owner, ctd):
3110 rv = self
3111 assert isinstance(ctd, ComplexTypeDefinition)
3112 maybe_rv = self._clone(owner, ctd._objectOrigin())
3113 term = rv.__term._adaptForScope(maybe_rv, ctd)
3114 do_clone = (self._scope() != ctd) or (rv.__term != term)
3115 if do_clone:
3116 rv = maybe_rv
3117 rv.__term = term
3118 return rv
3119
3120 - def isAdaptable (self, ctd):
3121 """A particle has an unresolvable particle if it cannot be
3122 resolved, or if it has resolved to a term which is a model
3123 group that has an unresolvable particle.
3124 """
3125 if not self.isResolved():
3126 return False
3127 return self.term().isAdaptable(ctd)
3128
3129 - def walkParticleTree (self, visit, arg):
3130 """The entry-point to walk a particle tree defining a content model.
3131
3132 See L{_ParticleTree_mixin._walkParticleTree}."""
3133 self._walkParticleTree(visit, arg)
3134
3135 - def _walkParticleTree (self, visit, arg):
3136 visit(self, True, arg)
3137 self.__term._walkParticleTree(visit, arg)
3138 visit(self, False, arg)
3139
3140 @classmethod
3141 - def IsTypedefNode (cls, node):
3142 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3143
3144 @classmethod
3145 - def IsParticleNode (cls, node, *others):
3146 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3147
3148 - def __str__ (self):
3149
3150 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3151
3152
3153
3154 -class Wildcard (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
3155 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3156
3157 NC_any = '##any'
3158 NC_not = '##other'
3159 NC_targetNamespace = '##targetNamespace'
3160 NC_local = '##local'
3161
3162 __namespaceConstraint = None
3164 """A constraint on the namespace for the wildcard.
3165
3166 Valid values are:
3167 - L{Wildcard.NC_any}
3168 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3169 - set(of_namespaces)
3170
3171 Note that namespace are represented by
3172 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3173 actually define a namespace. Absence of a namespace is represented by
3174 C{None}, both in the "not" pair and in the set.
3175 """
3176 return self.__namespaceConstraint
3177
3178 @classmethod
3180 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3181 assert 0 < len(constraints)
3182 o1 = constraints.pop(0)
3183 while 0 < len(constraints):
3184 o2 = constraints.pop(0)
3185
3186 if (o1 == o2):
3187 continue
3188
3189 if (cls.NC_any == o1) or (cls.NC_any == o2):
3190 o1 = cls.NC_any
3191 continue
3192
3193 if isinstance(o1, set) and isinstance(o2, set):
3194 o1 = o1.union(o2)
3195 continue
3196
3197 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3198 o1 = ( cls.NC_not, None )
3199 continue
3200
3201
3202 c_tuple = None
3203 c_set = None
3204 if isinstance(o1, tuple):
3205 assert isinstance(o2, set)
3206 c_tuple = o1
3207 c_set = o2
3208 else:
3209 assert isinstance(o1, set)
3210 assert isinstance(o2, tuple)
3211 c_tuple = o2
3212 c_set = o1
3213 negated_ns = c_tuple[1]
3214 if negated_ns is not None:
3215
3216 if (negated_ns in c_set) and (None in c_set):
3217 o1 = cls.NC_any
3218 continue
3219
3220 if negated_ns in c_set:
3221 o1 = ( cls.NC_not, None )
3222 continue
3223
3224 if None in c_set:
3225 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3226 o1 = c_tuple
3227 continue
3228
3229 if None in c_set:
3230 o1 = cls.NC_any
3231 else:
3232 o1 = ( cls.NC_not, None )
3233 return o1
3234
3235 @classmethod
3237 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3238 assert 0 < len(constraints)
3239 o1 = constraints.pop(0)
3240 while 0 < len(constraints):
3241 o2 = constraints.pop(0)
3242
3243 if (o1 == o2):
3244 continue
3245
3246 if (cls.NC_any == o1) or (cls.NC_any == o2):
3247 if cls.NC_any == o1:
3248 o1 = o2
3249 continue
3250
3251 if isinstance(o1, set) and isinstance(o2, set):
3252 o1 = o1.intersection(o2)
3253 continue
3254 if isinstance(o1, tuple) and isinstance(o2, tuple):
3255 ns1 = o1[1]
3256 ns2 = o2[1]
3257
3258 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3259 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3260
3261 assert (ns1 is None) or (ns2 is None)
3262 if ns1 is None:
3263 assert ns2 is not None
3264 o1 = ( cls.NC_not, ns2 )
3265 else:
3266 assert ns1 is not None
3267 o1 = ( cls.NC_not, ns1 )
3268 continue
3269
3270
3271
3272 c_tuple = None
3273 c_set = None
3274 if isinstance(o1, tuple):
3275 assert isinstance(o2, set)
3276 c_tuple = o1
3277 c_set = o2
3278 else:
3279 assert isinstance(o1, set)
3280 assert isinstance(o2, tuple)
3281 c_tuple = o2
3282 c_set = o1
3283 negated_ns = c_tuple[1]
3284 if negated_ns in c_set:
3285 c_set.remove(negated_ns)
3286 if None in c_set:
3287 c_set.remove(None)
3288 o1 = c_set
3289 return o1
3290
3291 PC_skip = 'skip'
3292 PC_lax = 'lax'
3293 PC_strict = 'strict'
3294
3295
3296 __processContents = None
3297 - def processContents (self):
3298 return self.__processContents
3299
3301 """Return True, since Wildcard components are wildcards."""
3302 return True
3303
3309
3312
3313 - def _walkParticleTree (self, visit, arg):
3314 visit(self, None, arg)
3315
3316
3318 """Wildcards are scope-independent; return self"""
3319 return self
3320
3321
3322 @classmethod
3324 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3325 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3326 nc = domutils.NodeAttribute(node, 'namespace')
3327 if nc is None:
3328 namespace_constraint = cls.NC_any
3329 else:
3330 if cls.NC_any == nc:
3331 namespace_constraint = cls.NC_any
3332 elif cls.NC_not == nc:
3333 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3334 else:
3335 ncs = set()
3336 for ns_uri in nc.split():
3337 if cls.NC_local == ns_uri:
3338 ncs.add(None)
3339 elif cls.NC_targetNamespace == ns_uri:
3340 ncs.add(namespace_context.targetNamespace())
3341 else:
3342 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3343 namespace_constraint = frozenset(ncs)
3344
3345 pc = domutils.NodeAttribute(node, 'processContents')
3346 if pc is None:
3347 process_contents = cls.PC_strict
3348 else:
3349 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3350 process_contents = pc
3351 else:
3352 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3353
3354 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3355 rv._annotationFromDOM(node)
3356 return rv
3357
3358
3359 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3360 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3361
3362 ICC_KEY = 0x01
3363 ICC_KEYREF = 0x02
3364 ICC_UNIQUE = 0x04
3365
3366 __identityConstraintCategory = None
3369
3370 __selector = None
3373
3374 __fields = None
3377
3378 __referencedKey = None
3379 __referAttribute = None
3380 __icc = None
3381
3382 __annotations = None
3385
3386
3387 @classmethod
3389 name = domutils.NodeAttribute(node, 'name')
3390 scope = kw['scope']
3391 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3392 rv = cls(name=name, node=node, **kw)
3393
3394 kw.pop('node', None)
3395 kw['owner'] = rv
3396
3397
3398 rv.__isResolved = True
3399 icc = None
3400 if xsd.nodeIsNamed(node, 'key'):
3401 icc = rv.ICC_KEY
3402 elif xsd.nodeIsNamed(node, 'keyref'):
3403 icc = rv.ICC_KEYREF
3404 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3405 if rv.__referAttribute is None:
3406 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3407 rv.__isResolved = False
3408 elif xsd.nodeIsNamed(node, 'unique'):
3409 icc = rv.ICC_UNIQUE
3410 else:
3411 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3412 rv.__icc = icc
3413
3414 cn = domutils.LocateUniqueChild(node, 'selector')
3415 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3416 if rv.__selector is None:
3417 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3418
3419 rv.__fields = []
3420 for cn in domutils.LocateMatchingChildren(node, 'field'):
3421 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3422 if xp_attr is None:
3423 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3424 rv.__fields.append(xp_attr)
3425
3426 rv._annotationFromDOM(node)
3427 rv.__annotations = []
3428 if rv.annotation() is not None:
3429 rv.__annotations.append(rv)
3430
3431 for cn in node.childNodes:
3432 if (Node.ELEMENT_NODE != cn.nodeType):
3433 continue
3434 an = None
3435 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3436 an = domutils.LocateUniqueChild(cn, 'annotation')
3437 elif xsd.nodeIsNamed(cn, 'annotation'):
3438 an = cn
3439 if an is not None:
3440 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3441
3442 rv.__identityConstraintCategory = icc
3443 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3444 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3445
3446 if not rv.isResolved():
3447 rv._queueForResolution('creation')
3448 return rv
3449
3450 __isResolved = False
3453
3454
3469
3470
3472 """Constraint definitions that are by reference require the referenced constraint."""
3473 rv = set()
3474 if include_lax and (self.__referencedKey is not None):
3475 rv.add(self.__referencedKey)
3476 return frozenset(rv)
3477
3478
3479
3480
3481 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3482 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3483 __systemIdentifier = None
3486
3487 __publicIdentifier = None
3490
3491
3492 @classmethod
3502
3505 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3506
3507 __applicationInformation = None
3510
3511 __userInformation = None
3514
3515
3517 application_information = kw.pop('application_information', None)
3518 user_information = kw.pop('user_information', None)
3519 super(Annotation, self).__init__(**kw)
3520 if (user_information is not None) and (not isinstance(user_information, list)):
3521 user_information = [ unicode(user_information) ]
3522 if (application_information is not None) and (not isinstance(application_information, list)):
3523 application_information = [ unicode(application_information) ]
3524 self.__userInformation = user_information
3525 self.__applicationInformation = application_information
3526
3527
3528
3529
3530
3531
3532
3533
3534 __attributes = None
3535
3536
3537 @classmethod
3561
3562 __RemoveMultiQuote_re = re.compile('""+')
3564 """Return the text in a form suitable for embedding in a
3565 triple-double-quoted docstring.
3566
3567 Any sequence of two or more double quotes is replaced by a sequence of
3568 single quotes that is the same length. Following this, spaces are
3569 added at the start and the end as necessary to ensure a double quote
3570 does not appear in those positions."""
3571 rv = self.text()
3572 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3573 if rv.startswith('"'):
3574 rv = ' ' + rv
3575 if rv.endswith('"'):
3576 rv = rv + ' '
3577 return rv
3578
3580 if self.__userInformation is None:
3581 return ''
3582 text = []
3583
3584
3585 for dn in self.__userInformation:
3586 for cn in dn.childNodes:
3587 if Node.TEXT_NODE == cn.nodeType:
3588 text.append(cn.data)
3589 return ''.join(text)
3590
3592 """Return the catenation of all user information elements in the
3593 annotation as a single unicode string. Returns the empty string if
3594 there are no user information elements."""
3595 return self.text()
3596
3597
3598 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3599 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3600
3601
3602
3603
3604 __baseTypeDefinition = None
3607
3608 __memberTypes = None
3609 __itemTypeAttribute = None
3610 __baseAttribute = None
3611 __memberTypesAttribute = None
3612 __localFacets = None
3613
3614
3615
3616
3617
3618
3619 __facets = None
3623
3624
3625 __fundamentalFacets = None
3627 """A frozenset of instances of facets.FundamentallFacet."""
3628 return self.__fundamentalFacets
3629
3630 STD_empty = 0
3631 STD_extension = 0x01
3632 STD_list = 0x02
3633 STD_restriction = 0x04
3634 STD_union = 0x08
3635
3636 _STD_Map = { 'extension' : STD_extension
3637 , 'list' : STD_list
3638 , 'restriction' : STD_restriction
3639 , 'union' : STD_union }
3640
3641
3642 __final = STD_empty
3643 @classmethod
3645 """Convert a final value to a string."""
3646 tags = []
3647 if final_value & cls.STD_extension:
3648 tags.append('extension')
3649 if final_value & cls.STD_list:
3650 tags.append('list')
3651 if final_value & cls.STD_restriction:
3652 tags.append('restriction')
3653 if final_value & cls.STD_union:
3654 tags.append('union')
3655 return ' '.join(tags)
3656
3657 VARIETY_absent = 0x01
3658 VARIETY_atomic = 0x02
3659 VARIETY_list = 0x03
3660 VARIETY_union = 0x04
3661
3662
3663 _DA_empty = 'none specified'
3664 _DA_restriction = 'restriction'
3665 _DA_list = 'list'
3666 _DA_union = 'union'
3667
3670 __derivationAlternative = None
3671
3672
3673
3674 __variety = None
3677 @classmethod
3689
3690
3691 __primitiveTypeDefinition = None
3698
3699
3700 __itemTypeDefinition = None
3706
3707
3708 __memberTypeDefinitions = None
3714
3715
3744
3745
3746
3747
3748
3749 __domNode = None
3750
3751
3752
3753 __isBuiltin = False
3754
3755
3756
3757
3761
3763 """Extend base class unpickle support to retain link between
3764 this instance and the Python class that it describes.
3765
3766 This is because the pythonSupport value is a class reference,
3767 not an instance reference, so it wasn't deserialized, and its
3768 class member link was never set.
3769 """
3770 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3771 super_fn(state)
3772 if self.__pythonSupport is not None:
3773 self.__pythonSupport._SimpleTypeDefinition(self)
3774
3802
3804 """Override fields in this instance with those from the other.
3805
3806 This method is invoked only by Schema._addNamedComponent, and
3807 then only when a built-in type collides with a schema-defined
3808 type. Material like facets is not (currently) held in the
3809 built-in copy, so the DOM information is copied over to the
3810 built-in STD, which is subsequently re-resolved.
3811
3812 Returns self.
3813 """
3814 assert self != other
3815 assert self.isNameEquivalent(other)
3816 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3817
3818
3819 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3820 assert other.__domNode is not None
3821 self.__domNode = other.__domNode
3822
3823
3824 if other.__pythonSupport is not None:
3825
3826 self.__pythonSupport = other.__pythonSupport
3827
3828
3829 self.__variety = None
3830 return self
3831
3833 """Indicate whether this simple type is a built-in type."""
3834 return self.__isBuiltin
3835
3836 __SimpleUrTypeDefinition = None
3837 @classmethod
3873
3874 @classmethod
3909
3910 @classmethod
3941
3942 @classmethod
3973
3974 @classmethod
4001
4002 @classmethod
4004 """(Placeholder) Create a union simple type in the target namespace.
4005
4006 This function has not been implemented."""
4007 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4008
4010 simple_type_child = None
4011 for cn in body.childNodes:
4012 if (Node.ELEMENT_NODE == cn.nodeType):
4013 if not xsd.nodeIsNamed(cn, 'simpleType'):
4014 if other_elts_ok:
4015 continue
4016 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4017 assert not simple_type_child
4018 simple_type_child = cn
4019 if simple_type_child is None:
4020 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4021 return simple_type_child
4022
4023
4024
4025
4026
4027
4028
4029
4039
4046
4047 __localMemberTypes = None
4057
4068
4070 """Create facets for varieties that can take facets that are undeclared.
4071
4072 This means unions, which per section 4.1.2.3 of
4073 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4074 pattern restrictions."""
4075 if self.VARIETY_union != variety:
4076 return self
4077 self.__facets.setdefault(facets.CF_pattern)
4078 self.__facets.setdefault(facets.CF_enumeration)
4079 return self
4080
4082 """Identify the facets and properties for this stype.
4083
4084 This method simply identifies the facets that apply to this
4085 specific type, and records property values. Only
4086 explicitly-associated facets and properties are stored; others
4087 from base types will also affect this type. The information
4088 is taken from the applicationInformation children of the
4089 definition's annotation node, if any. If there is no support
4090 for the XMLSchema_hasFacetAndProperty namespace, this is a
4091 no-op.
4092
4093 Upon return, self.__facets is a map from the class for an
4094 associated fact to None, and self.__fundamentalFacets is a
4095 frozenset of instances of FundamentalFacet.
4096
4097 The return value is self.
4098 """
4099 self.__facets = { }
4100 self.__fundamentalFacets = frozenset()
4101 if self.annotation() is None:
4102 return self.__defineDefaultFacets(variety)
4103 app_info = self.annotation().applicationInformation()
4104 if app_info is None:
4105 return self.__defineDefaultFacets(variety)
4106 facet_map = { }
4107 fundamental_facets = set()
4108 seen_facets = set()
4109 for ai in app_info:
4110 for cn in ai.childNodes:
4111 if Node.ELEMENT_NODE != cn.nodeType:
4112 continue
4113 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4114 facet_name = domutils.NodeAttribute(cn, 'name')
4115 if facet_name is None:
4116 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4117 if facet_name in seen_facets:
4118 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4119 seen_facets.add(facet_name)
4120 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4121
4122 facet_map[facet_class] = None
4123 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4124 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4125 if 0 < len(facet_map):
4126 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4127 self.__facets = facet_map
4128 assert type(self.__facets) == types.DictType
4129 if 0 < len(fundamental_facets):
4130 self.__fundamentalFacets = frozenset(fundamental_facets)
4131 return self
4132
4133
4184
4199
4200
4201
4202
4204 assert self.__variety is None
4205 if self.__baseTypeDefinition is None:
4206 assert self.__baseAttribute is not None
4207 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4208 base_type = base_en.typeDefinition()
4209 if not isinstance(base_type, SimpleTypeDefinition):
4210 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4211 self.__baseTypeDefinition = base_type
4212
4213
4214
4215 assert self.__baseTypeDefinition != self
4216 if not self.__baseTypeDefinition.isResolved():
4217 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4218 return self
4219 if variety is None:
4220
4221
4222 variety = self.__baseTypeDefinition.__variety
4223 assert variety is not None
4224
4225 if self.VARIETY_absent == variety:
4226
4227
4228 pass
4229 elif self.VARIETY_atomic == variety:
4230
4231
4232
4233 ptd = self
4234 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4235 ptd = ptd.__baseTypeDefinition
4236
4237 self.__primitiveTypeDefinition = ptd
4238 elif self.VARIETY_list == variety:
4239 if self._DA_list == alternative:
4240 if self.__itemTypeAttribute is not None:
4241 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4242 self.__itemTypeDefinition = it_en.typeDefinition()
4243 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4244 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4245 elif self._DA_restriction == alternative:
4246 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4247 else:
4248 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4249 elif self.VARIETY_union == variety:
4250 if self._DA_union == alternative:
4251
4252
4253
4254
4255 if self.__memberTypeDefinitions is None:
4256 mtd = []
4257
4258
4259 if self.__memberTypesAttribute is not None:
4260 for mn in self.__memberTypesAttribute.split():
4261
4262 mn_en = self._namespaceContext().interpretQName(mn)
4263 std = mn_en.typeDefinition()
4264 if std is None:
4265 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4266
4267 assert isinstance(std, SimpleTypeDefinition)
4268 mtd.append(std)
4269
4270 mtd.extend(self.__localMemberTypes)
4271 self.__memberTypeDefinitions = mtd
4272 assert None not in self.__memberTypeDefinitions
4273
4274
4275
4276
4277
4278
4279 mtd = []
4280 for mt in self.__memberTypeDefinitions:
4281 assert isinstance(mt, SimpleTypeDefinition)
4282 if not mt.isResolved():
4283 self._queueForResolution('member type not resolved', depends_on=mt)
4284 return self
4285 if self.VARIETY_union == mt.variety():
4286 mtd.extend(mt.memberTypeDefinitions())
4287 else:
4288 mtd.append(mt)
4289 elif self._DA_restriction == alternative:
4290 assert self.__baseTypeDefinition
4291
4292 assert self.__baseTypeDefinition.isResolved()
4293 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4294 assert mtd is not None
4295 else:
4296 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4297
4298 self.__memberTypeDefinitions = mtd[:]
4299 else:
4300 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4301
4302
4303
4304 self.__processHasFacetAndProperty(variety)
4305 self.__updateFacets(body)
4306
4307 self.__derivationAlternative = alternative
4308 self.__variety = variety
4309 self.__domNode = None
4310 return self
4311
4313 """Indicate whether this simple type is fully defined.
4314
4315 Type resolution for simple types means that the corresponding
4316 schema component fields have been set. Specifically, that
4317 means variety, baseTypeDefinition, and the appropriate
4318 additional fields depending on variety. See _resolve() for
4319 more information.
4320 """
4321
4322 return (self.__variety is not None)
4323
4324
4326 """Attempt to resolve the type.
4327
4328 Type resolution for simple types means that the corresponding
4329 schema component fields have been set. Specifically, that
4330 means variety, baseTypeDefinition, and the appropriate
4331 additional fields depending on variety.
4332
4333 All built-in STDs are resolved upon creation. Schema-defined
4334 STDs are held unresolved until the schema has been completely
4335 read, so that references to later schema-defined STDs can be
4336 resolved. Resolution is performed after the entire schema has
4337 been scanned and STD instances created for all
4338 topLevelSimpleTypes.
4339
4340 If a built-in STD is also defined in a schema (which it should
4341 be for XMLSchema), the built-in STD is kept, with the
4342 schema-related information copied over from the matching
4343 schema-defined STD. The former then replaces the latter in
4344 the list of STDs to be resolved.
4345
4346 Types defined by restriction have the same variety as the type
4347 they restrict. If a simple type restriction depends on an
4348 unresolved type, this method simply queues it for resolution
4349 in a later pass and returns.
4350 """
4351 if self.__variety is not None:
4352 return self
4353 assert self.__domNode
4354 node = self.__domNode
4355
4356 kw = { 'owner' : self
4357 , 'schema' : self._schema() }
4358
4359 bad_instance = False
4360
4361
4362 candidate = domutils.LocateUniqueChild(node, 'list')
4363 if candidate:
4364 self.__initializeFromList(candidate, **kw)
4365
4366 candidate = domutils.LocateUniqueChild(node, 'restriction')
4367 if candidate:
4368 if self.__variety is None:
4369 self.__initializeFromRestriction(candidate, **kw)
4370 else:
4371 bad_instance = True
4372
4373 candidate = domutils.LocateUniqueChild(node, 'union')
4374 if candidate:
4375 if self.__variety is None:
4376 self.__initializeFromUnion(candidate, **kw)
4377 else:
4378 bad_instance = True
4379
4380 if self.__baseTypeDefinition is None:
4381 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4382
4383 if self._schema() is not None:
4384 self.__final = self._schema().finalForNode(node, self._STD_Map)
4385
4386
4387 if bad_instance:
4388 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4389
4390 return self
4391
4392
4393 @classmethod
4409
4410
4411
4412
4413 __pythonSupport = None
4414
4424
4427
4432
4435
4438
4440 """Subclass ensures there is only one simple ur-type."""
4441 pass
4442
4548
4549 -class Schema (_SchemaComponent_mixin):
4550 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4551
4554
4555
4556 __annotations = None
4557
4558
4559
4560 __pastProlog = False
4561
4563 """URI or path to where the schema can be found.
4564
4565 For schema created by a user, the location should be provided to the
4566 constructor using the C{schema_location} keyword. In the case of
4567 imported or included schema, the including schema's location is used
4568 as the base URI for determining the absolute URI of the included
4569 schema from its (possibly relative) location value. For files,
4570 the scheme and authority portions are generally absent, as is often
4571 the abs_path part."""
4572 return self.__location
4573 __location = None
4574
4577 __locationTag = None
4578
4581 __signature = None
4582
4585 __generationUID = None
4586
4589 __originRecord = None
4590
4592 """The targetNamespace of a componen.
4593
4594 This is None, or a reference to a Namespace in which the
4595 component is declared (either as a global or local to one of
4596 the namespace's complex type definitions). This is immutable
4597 after creation.
4598 """
4599 return self.__targetNamespace
4600 __targetNamespace = None
4601
4603 """Default namespace of the schema.
4604
4605 Will be None unless the schema has an 'xmlns' attribute. The
4606 value must currently be provided as a keyword parameter to the
4607 constructor. """
4608 return self.__defaultNamespace
4609 __defaultNamespace = None
4610
4613 __referencedNamespaces = None
4614
4615 __namespaceData = None
4616
4619 __importEIIs = None
4620
4623 __importedSchema = None
4626 __includedSchema = None
4627
4628 _QUALIFIED = "qualified"
4629 _UNQUALIFIED = "unqualified"
4630
4631
4632 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4633 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4634 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4635 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4636 , pyxb.namespace.ExpandedName(None, 'id') : None
4637 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4638 , pyxb.namespace.ExpandedName(None, 'version') : None
4639 , pyxb.namespace.XML.createExpandedName('lang') : None
4640 }
4641
4646
4648 """Override the schema attributes with values from the given map."""
4649 self.__attributeMap.update(attr_map)
4650 return self
4651
4653 """Return True iff the schema has an attribute with the given (nc)name."""
4654 if isinstance(attr_name, basestring):
4655 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4656 return self.__attributeMap.has_key(attr_name)
4657
4659 """Return the schema attribute value associated with the given (nc)name.
4660
4661 @param attr_name: local name for the attribute in the schema element.
4662 @return: the value of the corresponding attribute, or C{None} if it
4663 has not been defined and has no default.
4664 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4665 """
4666 if isinstance(attr_name, basestring):
4667 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4668 return self.__attributeMap[attr_name]
4669
4670 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4671 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4672 'identityConstraintDefinition' )
4673
4676 __uriContentArchiveDirectory = None
4677
4719
4720 __TopLevelComponentMap = {
4721 'element' : ElementDeclaration,
4722 'attribute' : AttributeDeclaration,
4723 'notation' : NotationDeclaration,
4724 'simpleType' : SimpleTypeDefinition,
4725 'complexType' : ComplexTypeDefinition,
4726 'group' : ModelGroupDefinition,
4727 'attributeGroup' : AttributeGroupDefinition
4728 }
4729
4730 @classmethod
4735
4736 @classmethod
4738 """Create a schema from a schema location.
4739
4740 Reads an XML document from the schema location and creates a schema
4741 using it. All keyword parameters are passed to L{CreateFromDOM}.
4742
4743 @keyword schema_location: A file path or a URI. If this is a relative
4744 URI and C{parent_uri} is present, the actual location will be
4745 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4746 @keyword parent_uri: The context within which schema_location will be
4747 normalized, if necessary.
4748 @keyword absolute_schema_location: A file path or URI. This value is
4749 not normalized, and supersedes C{schema_location}.
4750 """
4751 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4752 kw['location_base'] = kw['schema_location'] = schema_location
4753 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4754 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4755 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4756
4757 @classmethod
4760
4761 @classmethod
4762 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4763 """Take the root element of the document, and scan its attributes under
4764 the assumption it is an XMLSchema schema element. That means
4765 recognize namespace declarations and process them. Also look for
4766 and set the default namespace. All other attributes are passed up
4767 to the parent class for storage."""
4768
4769
4770
4771 including_context = kw.get('including_context')
4772
4773 root_node = node
4774 if Node.DOCUMENT_NODE == node.nodeType:
4775 root_node = root_node.documentElement
4776 if Node.ELEMENT_NODE != root_node.nodeType:
4777 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4778
4779 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4780 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4781 parent_context=namespace_context,
4782 including_context=including_context)
4783
4784 tns = ns_ctx.targetNamespace()
4785 if tns is None:
4786 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4787 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4788 schema.__namespaceData = ns_ctx
4789
4790 if schema.targetNamespace() != ns_ctx.targetNamespace():
4791 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4792
4793
4794 for ai in range(root_node.attributes.length):
4795 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4796
4797
4798 if not xsd.nodeIsNamed(root_node, 'schema'):
4799 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4800
4801 for cn in root_node.childNodes:
4802 if Node.ELEMENT_NODE == cn.nodeType:
4803 rv = schema.__processTopLevelNode(cn)
4804 if rv is None:
4805 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4806 elif Node.TEXT_NODE == cn.nodeType:
4807
4808
4809 text = cn.data.strip()
4810 if text:
4811 _log.info('Ignored text: %s', text)
4812 elif Node.COMMENT_NODE == cn.nodeType:
4813 pass
4814 else:
4815
4816
4817
4818
4819
4820
4821
4822 _log.info('Ignoring non-element: %s', cn)
4823
4824
4825
4826
4827 return schema
4828
4829 _SA_All = '#all'
4830
4832 ebv = domutils.NodeAttribute(dom_node, attr)
4833 if ebv is None:
4834 ebv = self.schemaAttribute('%sDefault' % (attr,))
4835 rv = 0
4836 if ebv == self._SA_All:
4837 for v in candidate_map.values():
4838 rv += v
4839 else:
4840 for candidate in ebv.split():
4841 rv += candidate_map.get(candidate, 0)
4842 return rv
4843
4845 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4846
4847 A value of '#all' means enable every options; otherwise, the attribute
4848 value should be a list of tokens, for which the corresponding value
4849 will be added to the return value.
4850
4851 @param dom_node: the node from which the "block" attribute will be retrieved
4852 @type dom_node: C{xml.dom.Node}
4853 @param candidate_map: map from strings to bitmask values
4854 """
4855 return self.__ebvForNode('block', dom_node, candidate_map)
4856
4858 """Return a bit mask indicating a set of options read from the node's
4859 "final" attribute or the schema's "finalDefault" attribute.
4860
4861 A value of '#all' means enable every options; otherwise, the attribute
4862 value should be a list of tokens, for which the corresponding value
4863 will be added to the return value.
4864
4865 @param dom_node: the node from which the "final" attribute will be retrieved
4866 @type dom_node: C{xml.dom.Node}
4867 @param candidate_map: map from strings to bitmask values
4868 """
4869 return self.__ebvForNode('final', dom_node, candidate_map)
4870
4872 """Determine the target namespace for a local attribute or element declaration.
4873
4874 Look at the node's C{form} attribute, or if none the schema's
4875 C{attributeFormDefault} or C{elementFormDefault} value. If the
4876 resulting value is C{"qualified"} and the parent schema has a
4877 non-absent target namespace, return it to use as the declaration
4878 target namespace. Otherwise, return None to indicate that the
4879 declaration has no namespace.
4880
4881 @param dom_node: The node defining an element or attribute declaration
4882 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4883 @return: L{pyxb.namespace.Namespace} or None
4884 """
4885
4886 form_type = domutils.NodeAttribute(dom_node, 'form')
4887 if form_type is None:
4888 if declaration_type == ElementDeclaration:
4889 form_type = self.schemaAttribute('elementFormDefault')
4890 elif declaration_type == AttributeDeclaration:
4891 form_type = self.schemaAttribute('attributeFormDefault')
4892 else:
4893 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4894 tns = None
4895 if (self._QUALIFIED == form_type):
4896 tns = self.targetNamespace()
4897 if tns.isAbsentNamespace():
4898 tns = None
4899 else:
4900 if (self._UNQUALIFIED != form_type):
4901 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4902 return tns
4903
4905 """Throw a SchemaValidationException referencing the given
4906 node if we have passed the sequence point representing the end
4907 of prolog elements."""
4908
4909 if self.__pastProlog:
4910 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4911
4913 self.__requireInProlog(node.nodeName)
4914
4915 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
4916 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
4917 if not has_schema:
4918 kw = { 'absolute_schema_location': abs_uri,
4919 'including_context': self.__namespaceData,
4920 'generation_uid': self.generationUID(),
4921 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
4922 }
4923 try:
4924 schema_instance = self.CreateFromLocation(**kw)
4925 except pyxb.SchemaUniquenessError as e:
4926 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
4927 except Exception as e:
4928 _log.exception('INCLUDE %s caught', abs_uri)
4929 raise
4930 if schema_instance:
4931 if self.targetNamespace() != schema_instance.targetNamespace():
4932 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
4933 self.__includedSchema.add(schema_instance)
4934 return node
4935
4953
4957
4961
4985
4989
4991 tns = self.targetNamespace()
4992 assert tns is not None
4993 if not isinstance(nc, _NamedComponent_mixin):
4994 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
4995 if nc.isAnonymous():
4996 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
4997 if isinstance(nc, _ScopedDeclaration_mixin):
4998 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
4999 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5000 return self.__addTypeDefinition(nc)
5001 if isinstance(nc, AttributeDeclaration):
5002 return self.__addAttributeDeclaration(nc)
5003 if isinstance(nc, AttributeGroupDefinition):
5004 return self.__addAttributeGroupDefinition(nc)
5005 if isinstance(nc, ModelGroupDefinition):
5006 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5007 if isinstance(nc, ElementDeclaration):
5008 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5009 if isinstance(nc, NotationDeclaration):
5010 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5011 if isinstance(nc, IdentityConstraintDefinition):
5012 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5013 assert False, 'No support to record named component of type %s' % (nc.__class__,)
5014
5034
5051
5068
5070 return 'SCH[%s]' % (self.location(),)
5071
5074 """Add to the schema the definitions of the built-in types of XMLSchema.
5075 This should only be invoked by L{pyxb.namespace} when the built-in
5076 namespaces are initialized. """
5077
5078
5079 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5080 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5081 assert td.isResolved()
5082
5083 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5084 assert td.isResolved()
5085
5086 pts_std_map = {}
5087 for dtc in datatypes._PrimitiveDatatypes:
5088 name = dtc.__name__.rstrip('_')
5089 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5090 assert td.isResolved()
5091 assert dtc.SimpleTypeDefinition() == td
5092 pts_std_map.setdefault(dtc, td)
5093 for dtc in datatypes._DerivedDatatypes:
5094 name = dtc.__name__.rstrip('_')
5095 parent_std = pts_std_map[dtc.XsdSuperType()]
5096 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5097 assert td.isResolved()
5098 assert dtc.SimpleTypeDefinition() == td
5099 pts_std_map.setdefault(dtc, td)
5100 for dtc in datatypes._ListDatatypes:
5101 list_name = dtc.__name__.rstrip('_')
5102 element_name = dtc._ItemType.__name__.rstrip('_')
5103 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5104 assert element_std is not None
5105 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5106 assert td.isResolved()
5107 global _PastAddBuiltInTypes
5108 _PastAddBuiltInTypes = True
5109
5110 return schema
5111
5112 import sys
5113 import pyxb.namespace.builtin
5114 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5115
5116
5117
5118
5119