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.schemaOrderSortKey()
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
375 __schemaOrderSortKey = None
376
378 """A sort key matching preferred content order.
379
380 This is an ordinal (integer) used to control which candidate
381 transitions are attempted first when testing symbols against the
382 content automaton state.
383
384 @note: The value associated with a node (especially a L{ModelGroup} or
385 L{Particle} will be different for different complex types, and is
386 valid only during generation of the automata code for a given type."""
387 assert self.__facStateSortKey is not None
388 return self.__facStateSortKey
389
391 """Set the automata state sort key.
392
393 @param key: the ordinal used for sorting."""
394 self.__facStateSortKey = key
395 __facStateSortKey = None
396 __PrivateTransient.add('facStateSortKey')
397
398 -class _ParticleTree_mixin (pyxb.cscRoot):
399 - def _walkParticleTree (self, visit, arg):
400 """Mix-in supporting walks of L{Particle} trees.
401
402 This invokes a provided function on each node in a tree defining the
403 content model of a particle, both on the way down the tree and on the
404 way back up. A standard implementation would be::
405
406 def _walkParticleTree (self, visit, arg):
407 visit(self, True, arg)
408 self.__term.walkParticleTree(visit, arg)
409 visit(self, False, arg)
410
411 @param visit: A callable with parameters C{node, entering, arg} where
412 C{node} is an instance of a class inheriting L{_ParticleTree_mixin},
413 C{entering} indicates tree transition status, and C{arg} is a
414 caller-provided state parameter. C{entering} is C{True} if C{node}
415 has particle children and the call is before they are visited;
416 C{None} if the C{node} has no particle children; and C{False} if
417 C{node} has particle children and they have been visited.
418
419 @param arg: The caller-provided state parameter to be passed along
420 with the node and entry/exit status in the invocation of C{visit}.
421 """
422 raise NotImplementedError('%s._walkParticleTree' % (self.__class__.__name__,))
423
425 """This class is a mix-in which guarantees that only one instance
426 of the class will be created. It is used to ensure that the
427 ur-type instances are pointer-equivalent even when unpickling.
428 See ComplexTypeDefinition.UrTypeDefinition()."""
430 singleton_property = '_%s__singleton' % (cls.__name__,)
431 if not (singleton_property in cls.__dict__):
432 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
433 return cls.__dict__[singleton_property]
434
436 """Mix-in that supports an optional single annotation that describes the component.
437
438 Most schema components have annotations. The ones that don't are
439 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
440 and L{Schema} support multiple annotations, so do not mix-in this
441 class."""
442
443
444 __annotation = None
445
449
457
459 """Override fields in this instance with those from the other.
460
461 Post-extended; description in leaf implementation in
462 ComplexTypeDefinition and SimpleTypeDefinition."""
463 assert self != other
464 self_fn = lambda *_args, **_kw: self
465 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', self_fn)(other)
466
467 self.__annotation = other.__annotation
468 return self
469
472
474 """A helper that encapsulates a reference to an anonymous type in a different namespace.
475
476 Normally references to components in other namespaces can be made using
477 the component's name. This is not the case when a namespace derives from
478 a base type in another namespace and needs to reference the attribute or
479 element declarations held in that type. If these declarations are local
480 to the base complex type, they cannot be identified by name. This class
481 provides a pickleable representation for them that behaves rather like an
482 L{pyxb.namespace.ExpandedName} instance in that it can be used to
483 dereference various component types."""
484
485 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
486
487 __namespace = None
488 __anonymousName = None
489 - def __init__ (self, namespace, anonymous_name):
490 """Create a new anonymous reference.
491
492 @param namespace: The namespace in which the component is declared.
493 @type namespace: L{pyxb.namespace.Namespace}
494 @param anonymous_name: A generated name guaranteed to be unique within
495 the namespace. See L{_NamedComponent_mixin._anonymousName}.
496 @type anonymous_name: C{basestring}.
497 """
498 self.__namespace = namespace
499 self.__anonymousName = anonymous_name
500 assert self.__anonymousName is not None
501
502 @classmethod
504 """Return the component referred to by the provided reference,
505 regardless of whether it is a normal or anonymous reference."""
506 if not isinstance(object_reference, _PickledAnonymousReference):
507 assert isinstance(object_reference, tuple)
508 object_reference = pyxb.namespace.ExpandedName(object_reference)
509 return object_reference
510
513
516
520
523
524 typeDefinition = __lookupObject
525 attributeGroupDefinition = __lookupObject
526 modelGroupDefinition = __lookupObject
527 attributeDeclaration = __lookupObject
528 elementDeclaration = __lookupObject
529 identityConstraintDefinition = __lookupObject
530 notationDeclaration = __lookupObject
531
535
537 """Mix-in to hold the name and targetNamespace of a component.
538
539 The name may be None, indicating an anonymous component. The
540 targetNamespace is never None, though it could be an empty namespace. The
541 name and targetNamespace values are immutable after creation.
542
543 This class overrides the pickling behavior: when pickling a Namespace,
544 objects that do not belong to that namespace are pickled as references,
545 not as values. This ensures the uniqueness of objects when multiple
546 namespace definitions are pre-loaded.
547
548 This class must follow L{_SchemaComponent_mixin} in the MRO.
549 """
550
551 __PrivateTransient = set()
552
554 """Name of the component within its scope or namespace.
555
556 This is an NCName. The value isNone if the component is
557 anonymous. The attribute is immutable after the component is
558 created creation."""
559 return self.__name
560 __name = None
561
563 """Return true iff this instance is locally scoped (has no name)."""
564 return self.__name is None
565
590 __anonymousName = None
591
593 """The targetNamespace of a component.
594
595 This is None, or a reference to a Namespace in which the
596 component is declared (either as a global or local to one of
597 the namespace's complex type definitions). This is immutable
598 after creation.
599 """
600 return self.__targetNamespace
601 __targetNamespace = None
602
604 """The namespace in which this component's binding is placed."""
605 return self.__bindingNamespace
608 __bindingNamespace = None
609
611 """A map from template keys to component-specific values.
612
613 This is used in code generation to maintain unique names for accessor
614 methods, identifiers, keys, and other characteristics associated with
615 the code generated in support of the binding for this component."""
616 return self.__templateMap
617 __templateMap = None
618
619 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
620
626
628 """Return the schema component from which this component was defined.
629
630 Needed so we can distinguish components that came from different
631 locations, since that imposes an external order dependency on them and
632 on cross-namespace inclusions.
633
634 @note: This characteristic is removed when the component is stored in
635 a namespace archive."""
636 return self.__schema
637 __schema = None
638 __PrivateTransient.add('schema')
639
645
647 """Return C{True} if this component should be pickled by value in the
648 given namespace.
649
650 When pickling, a declaration component is considered to belong to the
651 namespace if it has a local scope which belongs to the namespace. In
652 that case, the declaration is a clone of something that does not
653 belong to the namespace; but the clone does.
654
655 @see: L{_bindsInNamespace}
656
657 @return: C{False} if the component should be pickled by reference.
658 """
659 if isinstance(self._scope(), ComplexTypeDefinition):
660 return self._scope()._picklesInArchive(archive)
661 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
662 assert not (self._objectOrigin() is None)
663 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
664 return new_flag
665
667 """Return C{True} if the binding for this component should be
668 generated in the given namespace.
669
670 This is the case when the component is in the given namespace. It's
671 also the case when the component has no associated namespace (but not
672 an absent namespace). Be aware that cross-namespace inheritance means
673 you will get references to elements in another namespace when
674 generating code for a subclass; that's fine, and those references
675 should not be generated locally.
676 """
677 return self.targetNamespace() in (ns, None)
678
684
686 """Pickling support.
687
688 Normally, we just create a new instance of this class.
689 However, if we're unpickling a reference in a loadable schema,
690 we need to return the existing component instance by looking
691 up the name in the component map of the desired namespace. We
692 can tell the difference because no normal constructors that
693 inherit from this have positional arguments; only invocations
694 by unpickling with a value returned in __getnewargs__ do.
695
696 This does require that the dependent namespace already have
697 been validated (or that it be validated here). That shouldn't
698 be a problem, except for the dependency loop resulting from
699 use of xml:lang in the XMLSchema namespace. For that issue,
700 see pyxb.namespace._XMLSchema.
701 """
702
703 if 0 == len(args):
704 rv = super(_NamedComponent_mixin, cls).__new__(cls)
705 return rv
706 ( object_reference, scope, icls ) = args
707
708 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
709
710
711
712 object_reference.validateComponentModel()
713 rv = None
714 if isinstance(scope, (tuple, _PickledAnonymousReference)):
715
716
717 scope_ref = _PickledAnonymousReference.FromPickled(scope)
718 if object_reference.namespace() != scope_ref.namespace():
719 scope_ref.validateComponentModel()
720 assert 'typeDefinition' in scope_ref.namespace().categories()
721 scope_ctd = scope_ref.typeDefinition()
722 if scope_ctd is None:
723 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
724 if issubclass(icls, AttributeDeclaration):
725 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
726 elif issubclass(icls, ElementDeclaration):
727 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
728 if rv is None:
729 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
730 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
731 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
732 rv = object_reference.typeDefinition()
733 elif issubclass(icls, AttributeGroupDefinition):
734 rv = object_reference.attributeGroupDefinition()
735 elif issubclass(icls, ModelGroupDefinition):
736 rv = object_reference.modelGroupDefinition()
737 elif issubclass(icls, AttributeDeclaration):
738 rv = object_reference.attributeDeclaration()
739 elif issubclass(icls, ElementDeclaration):
740 rv = object_reference.elementDeclaration()
741 elif issubclass(icls, IdentityConstraintDefinition):
742 rv = object_reference.identityConstraintDefinition()
743 if rv is None:
744 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
745 if rv is None:
746 raise pyxb.SchemaValidationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, (scope is None and "<unknown>" or scope.targetNamespace()), type(scope), icls))
747 return rv
748
769
771 """Return true iff this and the other component share the same name and target namespace.
772
773 Anonymous components are inherently name inequivalent, except to
774 themselves. This relies on equivalence as defined for
775 pyxb.namespace.ExpandedName, for which None is not equivalent to any
776 non-anonymous name."""
777
778 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
779
781 """Return True iff this and the other component have matching types.
782
783 It appears that name equivalence is used; two complex type definitions
784 with identical structures are not considered equivalent (at least, per
785 XMLSpy).
786 """
787 return (type(self) == type(other)) and self.isNameEquivalent(other)
788
790 """Return True iff this type can serve as a restriction of the other
791 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
792
793 It appears that name equivalence is normally used; two complex type
794 definitions with identical structures are not considered equivalent
795 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
796 that derivation by restriction from the other type is also acceptable.
797 That opens a whole can of worms; see
798 L{ElementDeclaration.isAdaptable}.
799 """
800 this = self
801
802 while this is not None:
803 if this.isTypeEquivalent(other):
804 return True
805
806 assert this.isResolved() and other.isResolved()
807 if isinstance(self, ComplexTypeDefinition):
808 if self.DM_restriction != this.derivationMethod():
809 return False
810 else:
811 assert isinstance(self, SimpleTypeDefinition)
812 if self._DA_restriction != this._derivationAlternative():
813 return False
814 if not this.baseTypeDefinition().isDerivationConsistent(other):
815 return False
816 this = this.baseTypeDefinition()
817 return False
818
824
842
867
869 """Pickling support.
870
871 If this instance is being pickled as a reference, provide the
872 arguments that are necessary so that the unpickler can locate
873 the appropriate component rather than create a duplicate
874 instance."""
875
876 if self.__pickleAsReference():
877 scope = self._scope()
878 if isinstance(self, _ScopedDeclaration_mixin):
879
880
881
882
883
884 if self.SCOPE_global == self.scope():
885 pass
886 elif isinstance(self.scope(), ComplexTypeDefinition):
887 scope = self.scope()._picklingReference()
888 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
889 else:
890 assert self._scopeIsIndeterminate()
891
892
893 else:
894 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
895 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
896
897 rv = ( self._picklingReference(), scope, self.__class__ )
898 return rv
899 return ()
900
917
927
929 """Mix-in indicating that the component contains a simple-type
930 value that may be constrained."""
931
932 VC_na = 0
933 VC_default = 1
934 VC_fixed = 2
935
936
937
938 __valueConstraint = None
940 """A constraint on the value of the attribute or element.
941
942 Either None, or a pair consisting of a string in the lexical
943 space of the typeDefinition and one of VC_default and
944 VC_fixed."""
945 return self.__valueConstraint
946
955
964
981
983 """Mix-in class for named components that have a scope.
984
985 Scope is important when doing cross-namespace inheritance,
986 e.g. extending or restricting a complex type definition that is
987 from a different namespace. In this case, we will need to retain
988 a reference to the external component when the schema is
989 serialized.
990
991 This is done in the pickling process by including the scope when
992 pickling a component as a reference. The scope is the
993 SCOPE_global if global; otherwise, it is a tuple containing the
994 external namespace URI and the NCName of the complex type
995 definition in that namespace. We assume that the complex type
996 definition has global scope; otherwise, it should not have been
997 possible to extend or restrict it. (Should this be untrue, there
998 are comments in the code about a possible solution.)
999
1000 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
1001 """
1002
1003 SCOPE_global = 'global'
1004 XSCOPE_indeterminate = 'indeterminate'
1005
1006 @classmethod
1009
1010 @classmethod
1013
1014 @classmethod
1017
1019 """Return True if this scope currently assigned to this instance is compatible with the given scope.
1020
1021 If either scope is indeterminate, presume they will ultimately be
1022 compatible. Scopes that are equal are compatible, as is a local scope
1023 if this already has a global scope."""
1024 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
1025 return True
1026 if self.scope() == scope:
1027 return True
1028 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
1029
1030
1031
1032
1034 """The scope for the declaration.
1035
1036 Valid values are SCOPE_global, or a complex type definition.
1037 A value of None means a non-global declaration that is not
1038 owned by a complex type definition. These can only appear in
1039 attribute group definitions or model group definitions.
1040
1041 @todo: For declarations in named model groups (viz., local
1042 elements that aren't references), the scope needs to be set by
1043 the owning complex type.
1044 """
1045 return self._scope()
1046
1047
1048
1049
1050
1051 __baseDeclaration = None
1057
1059 """Support for components that accept attribute wildcards.
1060
1061 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1062 calculations of the appropriate wildcard are sufficiently complex that
1063 they need to be abstracted out to a mix-in class."""
1064
1065
1066 __attributeWildcard = None
1067
1069 """Return the L{Wildcard} component associated with attributes of this
1070 instance, or C{None} if attribute wildcards are not present in the
1071 instance."""
1072 return self.__attributeWildcard
1073
1075 """Set the attribute wildcard property for this instance."""
1076 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1077 self.__attributeWildcard = attribute_wildcard
1078 return self
1079
1081 """Return the nodes that are relevant for attribute processing.
1082
1083 @param node_list: A sequence of nodes found in a definition content
1084 information item.
1085
1086 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1087 where C{attributes} is the subsequence of C{node_list} that are
1088 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1089 C{attributeWildcard} is a single DOM node with XMLSchema name
1090 C{anyAttribute} (or C{None}, if no such node is present in the list).
1091
1092 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1093 present but does not have the required C{ref} attribute.
1094 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1095 identified.
1096 """
1097
1098 attributes = []
1099 attribute_groups = []
1100 any_attribute = None
1101
1102 for node in node_list:
1103 if Node.ELEMENT_NODE != node.nodeType:
1104 continue
1105 if xsd.nodeIsNamed(node, 'attribute'):
1106
1107 attributes.append(node)
1108 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1109
1110 agd_attr = domutils.NodeAttribute(node, 'ref')
1111 if agd_attr is None:
1112 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1113 attribute_groups.append(agd_attr)
1114 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1115 if any_attribute is not None:
1116 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1117 any_attribute = node
1118
1119 return (attributes, attribute_groups, any_attribute)
1120
1121 @classmethod
1122 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1123 """Implement the algorithm as described the
1124 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1125
1126 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1127 associated with any created L{Wildcard} instance
1128 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1129 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1130 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1131 is relevant
1132 """
1133
1134
1135 agd_wildcards = []
1136 for agd in attribute_groups:
1137 assert isinstance(agd, AttributeGroupDefinition)
1138 if agd.attributeWildcard() is not None:
1139 agd_wildcards.append(agd.attributeWildcard())
1140 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1141
1142
1143 if 0 == len(agd_wildcards):
1144 return local_wildcard
1145
1146 if local_wildcard is not None:
1147
1148 return Wildcard(process_contents=local_wildcard.processContents(),
1149 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1150 annotation=local_wildcard.annotation(),
1151 namespace_context=namespace_context)
1152
1153 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1154 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1155 namespace_context=namespace_context)
1156
1157 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1158 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1159 """
1160
1161
1162 __typeDefinition = None
1164 """The simple type definition to which an attribute value must
1165 conform."""
1166 return self.__typeDefinition
1167
1168
1169 __typeAttribute = None
1170
1174
1179
1180 @classmethod
1193
1194
1195 @classmethod
1197 """Create an attribute declaration from the given DOM node.
1198
1199 wxs is a Schema instance within which the attribute is being
1200 declared.
1201
1202 node is a DOM element. The name must be one of ( 'all',
1203 'choice', 'sequence' ), and the node must be in the XMLSchema
1204 namespace.
1205
1206 scope is the _ScopeDeclaration_mxin context into which the
1207 attribute declaration is placed. It can be SCOPE_global, a
1208 complex type definition, or XSCOPE_indeterminate if this is an
1209 anonymous declaration within an attribute group. It is a
1210 required parameter for this function.
1211 """
1212
1213 scope = kw['scope']
1214 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1215
1216
1217 assert xsd.nodeIsNamed(node, 'attribute')
1218
1219 name = domutils.NodeAttribute(node, 'name')
1220
1221
1222 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1223 assert cls.SCOPE_global == scope
1224 elif domutils.NodeAttribute(node, 'ref') is None:
1225
1226 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1227 else:
1228 raise pyxb.SchemaValidationError('Internal attribute declaration by reference')
1229
1230 rv = cls(name=name, node=node, **kw)
1231 rv._annotationFromDOM(node)
1232 rv._valueConstraintFromDOM(node)
1233
1234 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1235
1236 kw.pop('node', None)
1237 kw['owner'] = rv
1238
1239 st_node = domutils.LocateUniqueChild(node, 'simpleType')
1240 if st_node is not None:
1241 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw)
1242 elif rv.__typeAttribute is None:
1243 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition()
1244
1245 if rv.__typeDefinition is None:
1246 rv._queueForResolution('creation')
1247 return rv
1248
1251
1252
1268
1270 """Override fields in this instance with those from the other.
1271
1272 This method is invoked only by Schema._addNamedComponent, and
1273 then only when a built-in type collides with a schema-defined
1274 type. Material like facets is not (currently) held in the
1275 built-in copy, so the DOM information is copied over to the
1276 built-in STD, which is subsequently re-resolved.
1277
1278 Returns self.
1279 """
1280 assert self != other
1281 assert self.name() is not None
1282 assert self.isNameEquivalent(other)
1283 super(AttributeDeclaration, self)._updateFromOther_csc(other)
1284
1285
1286
1287 if not other.isResolved():
1288 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID():
1289
1290 _log.warning('Not destroying builtin %s: %s', self.expandedName(), self.__typeDefinition)
1291 else:
1292 self.__typeDefinition = None
1293 return self
1294
1295
1297 """Attribute declarations require their type."""
1298 return frozenset([ self.__typeDefinition ])
1299
1300 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1301 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component."""
1302
1303
1304
1305 __use = None
1306
1307 USE_required = 0x01
1308 USE_optional = 0x02
1309 USE_prohibited = 0x04
1310
1313
1316
1317
1318 __refAttribute = None
1319
1320 __restrictionOf = None
1328
1329
1331 """The attribute declaration for this use.
1332
1333 When the use scope is assigned, the declaration is cloned (if
1334 necessary) so that each declaration corresponds to only one use. We
1335 rely on this in code generation, because the template map for the use
1336 is stored in its declaration."""
1337 return self.__attributeDeclaration
1338 __attributeDeclaration = None
1339
1340
1343
1358
1359 @classmethod
1368
1369
1370 @classmethod
1372 """Create an Attribute Use from the given DOM node.
1373
1374 wxs is a Schema instance within which the attribute use is
1375 being defined.
1376
1377 node is a DOM element. The name must be 'attribute', and the
1378 node must be in the XMLSchema namespace.
1379
1380 scope is the _ScopeDeclaration_mixin context into which any
1381 required anonymous attribute declaration is put. This must be
1382 a complex type definition, or None if this use is in an
1383 attribute group.
1384 """
1385
1386 scope = kw['scope']
1387 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1388 assert xsd.nodeIsNamed(node, 'attribute')
1389 schema = kw['schema']
1390 rv = cls(node=node, **kw)
1391
1392 rv.__use = cls.USE_optional
1393 use = domutils.NodeAttribute(node, 'use')
1394 if use is not None:
1395 if 'required' == use:
1396 rv.__use = cls.USE_required
1397 elif 'optional' == use:
1398 rv.__use = cls.USE_optional
1399 elif 'prohibited' == use:
1400 rv.__use = cls.USE_prohibited
1401 else:
1402 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1403
1404 rv._valueConstraintFromDOM(node)
1405
1406 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
1407 if rv.__refAttribute is None:
1408
1409 kw.pop('node', None)
1410 kw['owner'] = rv
1411 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1412 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1413
1414 if not rv.isResolved():
1415 rv._queueForResolution('creation')
1416
1417 return rv
1418
1421
1433
1434
1436 """Attribute uses require their declarations, but only if lax."""
1437 if not include_lax:
1438 return frozenset()
1439 return frozenset([ self.attributeDeclaration() ])
1440
1441
1461
1464
1465
1466 -class ElementDeclaration (_ParticleTree_mixin, _SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1467 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1468
1469
1470 __typeDefinition = None
1472 """The simple or complex type to which the element value conforms."""
1473 return self.__typeDefinition
1498
1499 __substitutionGroupAttribute = None
1500
1501 __typeAttribute = None
1502
1503 __nillable = False
1506
1507 __identityConstraintDefinitions = None
1511
1512 __substitutionGroupAffiliation = None
1516
1517 SGE_none = 0
1518 SGE_extension = 0x01
1519 SGE_restriction = 0x02
1520 SGE_substitution = 0x04
1521
1522 _SGE_Map = { 'extension' : SGE_extension
1523 , 'restriction' : SGE_restriction }
1524 _DS_Map = _SGE_Map.copy()
1525 _DS_Map.update( { 'substitution' : SGE_substitution } )
1526
1527
1528 __substitutionGroupExclusions = SGE_none
1529
1530
1531 __disallowedSubstitutions = SGE_none
1532
1533 __abstract = False
1536
1538 """Return False, since element declarations are not wildcards."""
1539 return False
1540
1541
1543 """Element declarations depend on the type definition of their
1544 content."""
1545 return frozenset([self.__typeDefinition])
1546
1549
1550
1551 @classmethod
1553 """Create an element declaration from the given DOM node.
1554
1555 wxs is a Schema instance within which the element is being
1556 declared.
1557
1558 scope is the _ScopeDeclaration_mixin context into which the
1559 element declaration is recorded. It can be SCOPE_global, a
1560 complex type definition, or None in the case of elements
1561 declared in a named model group.
1562
1563 node is a DOM element. The name must be 'element', and the
1564 node must be in the XMLSchema namespace."""
1565
1566 scope = kw['scope']
1567 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1568
1569
1570 assert xsd.nodeIsNamed(node, 'element')
1571
1572
1573 name = domutils.NodeAttribute(node, 'name')
1574 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1575 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1576 elif domutils.NodeAttribute(node, 'ref') is None:
1577
1578 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1579 else:
1580 raise pyxb.SchemaValidationError('Created reference as element declaration')
1581
1582 rv = cls(name=name, node=node, **kw)
1583 rv._annotationFromDOM(node)
1584 rv._valueConstraintFromDOM(node)
1585
1586 rv.__substitutionGroupAttribute = domutils.NodeAttribute(node, 'substitutionGroup')
1587
1588 kw.pop('node', None)
1589 kw['owner'] = rv
1590
1591 identity_constraints = []
1592 for cn in node.childNodes:
1593 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1594 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1595 rv.__identityConstraintDefinitions = identity_constraints
1596
1597 rv.__typeDefinition = None
1598 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1599 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1600 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1601 if rv.__typeAttribute is not None:
1602 if (simpleType_node is not None) and (complexType_node is not None):
1603 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1604 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1605 rv._typeDefinition(SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw))
1606 if (rv.__typeDefinition is None) and (complexType_node is not None):
1607 rv._typeDefinition(ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw))
1608 if rv.__typeDefinition is None:
1609 if rv.__typeAttribute is None:
1610
1611 for cn in node.childNodes:
1612 if Particle.IsParticleNode(cn):
1613 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1614 rv._typeDefinition(ComplexTypeDefinition.UrTypeDefinition())
1615 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1616 if not rv.__isResolved:
1617 rv._queueForResolution('creation')
1618
1619 attr_val = domutils.NodeAttribute(node, 'nillable')
1620 if attr_val is not None:
1621 rv.__nillable = datatypes.boolean(attr_val)
1622
1623 attr_val = domutils.NodeAttribute(node, 'abstract')
1624 if attr_val is not None:
1625 rv.__abstract = datatypes.boolean(attr_val)
1626
1627 schema = kw['schema']
1628 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1629 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1630
1631 return rv
1632
1634 """Determine whether this element declaration is adaptable.
1635
1636 OK, this gets ugly. First, if this declaration isn't resolved, it's
1637 clearly not adaptable.
1638
1639 Now: For it to be adaptable, we must know enough about its type to
1640 verify that it is derivation-consistent with any other uses of the
1641 same name in the same complex type. If the element's type is
1642 resolved, that's good enough.
1643
1644 If the element's type isn't resolved, we're golden as long as
1645 type-equivalent types were used. But it's also allowed for the
1646 derived ctd to use the element name constraining it to a derivation of
1647 the element base type. (Go see namespace
1648 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1649 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1650 have to have the element's type resolved.
1651
1652 Except that if a CTD's content incorporates an element with the same
1653 type as the CTD (i.e., nested), this will never happen, because the
1654 CTD can't get resolved until after it has been resolved.
1655 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1656 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1657 an example).
1658
1659 So, we give the world a break and assume that if the type we're trying
1660 to resolve is the same as the type of an element in that type, then
1661 the element type will be resolved by the point it's needed. In point
1662 of fact, it won't, but we'll only notice that if a CTD contains an
1663 element whose type is a restriction of the CTD. In that case,
1664 isDerivationConsistent will blow chunks and somebody'll have to come
1665 back and finish up this mess.
1666 """
1667
1668 if not self.isResolved():
1669 return False
1670 if self.typeDefinition().isResolved():
1671 return True
1672
1673
1674 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1675 if existing_decl is None:
1676
1677
1678 return True
1679
1680 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1681
1682 return True
1683
1684
1685 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1686 return False
1687
1688
1698
1699 __isResolved = False
1702
1703
1726
1727 - def _walkParticleTree (self, visit, arg):
1728 visit(self, None, arg)
1729
1734
1735
1736 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1737 __PrivateTransient = set()
1738
1739
1740 __baseTypeDefinition = None
1744
1745 DM_empty = 0
1746 DM_extension = 0x01
1747 DM_restriction = 0x02
1748
1749 _DM_Map = { 'extension' : DM_extension
1750 , 'restriction' : DM_restriction }
1751
1752
1753
1754 __derivationMethod = None
1758
1759
1760 __final = DM_empty
1761
1762
1763 __abstract = False
1766
1767
1768 __attributeUses = None
1770 """A frozenset() of AttributeUse instances."""
1771 return self.__attributeUses
1772
1773
1774
1775 __scopedAttributeDeclarations = None
1783
1784
1785
1786 __scopedElementDeclarations = None
1794
1795 __localScopedDeclarations = None
1797 """Return a list of element and attribute declarations that were
1798 introduced in this definition (i.e., their scope is this CTD).
1799
1800 @note: This specifically returns a list, with element declarations
1801 first, because name binding should privilege the elements over the
1802 attributes. Within elements and attributes, the components are sorted
1803 by expanded name, to ensure consistency across a series of binding
1804 generations.
1805
1806 @keyword reset: If C{False} (default), a cached previous value (if it
1807 exists) will be returned.
1808 """
1809 if reset or (self.__localScopedDeclarations is None):
1810 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1811 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1812 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1813 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1814 self.__localScopedDeclarations = rve
1815 self.__localScopedDeclarations.extend(rva)
1816 return self.__localScopedDeclarations
1817
1819 """Record the given declaration as being locally scoped in
1820 this type."""
1821 assert isinstance(decl, _ScopedDeclaration_mixin)
1822 if isinstance(decl, ElementDeclaration):
1823 scope_map = self.__scopedElementDeclarations
1824 elif isinstance(decl, AttributeDeclaration):
1825 scope_map = self.__scopedAttributeDeclarations
1826 else:
1827 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1828 decl_en = decl.expandedName()
1829 existing_decl = scope_map.setdefault(decl_en, decl)
1830 if decl != existing_decl:
1831 if isinstance(decl, ElementDeclaration):
1832
1833 existing_type = existing_decl.typeDefinition()
1834 pending_type = decl.typeDefinition()
1835 if not pending_type.isDerivationConsistent(existing_type):
1836 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1837 elif isinstance(decl, AttributeDeclaration):
1838 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1839 else:
1840 assert False, 'Unrecognized type %s' % (type(decl),)
1841 decl._baseDeclaration(existing_decl)
1842 return self
1843
1849
1850 CT_EMPTY = 'EMPTY'
1851 CT_SIMPLE = 'SIMPLE'
1852 CT_MIXED = 'MIXED'
1853 CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1854
1855 - def _contentTypeTag (self):
1856 """Return the value of the content type identifier, i.e. one of the
1857 CT_ constants. Return value is None if no content type has been
1858 defined."""
1859 if isinstance(self.__contentType, tuple):
1860 return self.__contentType[0]
1861 return self.__contentType
1862
1864 if isinstance(self.__contentType, tuple):
1865 return self.__contentType[1]
1866 return None
1867
1868
1869 __contentType = None
1870 - def contentType (self):
1871 """Identify the sort of content in this type.
1872
1873 Valid values are:
1874 - C{CT_EMPTY}
1875 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1876 - ( C{CT_MIXED}, a L{Particle} instance )
1877 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1878 """
1879 return self.__contentType
1880
1882 if self.CT_EMPTY == self.contentType():
1883 return 'EMPTY'
1884 ( tag, particle ) = self.contentType()
1885 if self.CT_SIMPLE == tag:
1886 return 'Simple [%s]' % (particle,)
1887 if self.CT_MIXED == tag:
1888 return 'Mixed [%s]' % (particle,)
1889 if self.CT_ELEMENT_ONLY == tag:
1890 return 'Element [%s]' % (particle,)
1891 raise pyxb.LogicError('Unhandled content type')
1892
1893
1894 __prohibitedSubstitutions = DM_empty
1895
1896
1897 __annotations = None
1898
1904
1914
1916 """Override fields in this instance with those from the other.
1917
1918 This method is invoked only by Schema._addNamedComponent, and
1919 then only when a built-in type collides with a schema-defined
1920 type. Material like facets is not (currently) held in the
1921 built-in copy, so the DOM information is copied over to the
1922 built-in STD, which is subsequently re-resolved.
1923
1924 Returns self.
1925 """
1926 assert self != other
1927 assert self.isNameEquivalent(other)
1928 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1929
1930 if not other.isResolved():
1931 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1932 self.__derivationMethod = None
1933
1934 return self
1935
1936 __UrTypeDefinition = None
1937 @classmethod
1939 """Create the ComplexTypeDefinition instance that approximates
1940 the ur-type.
1941
1942 See section 3.4.7.
1943 """
1944
1945
1946
1947
1948
1949
1950
1951 if cls.__UrTypeDefinition is None:
1952
1953 assert schema is not None
1954
1955 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1956
1957 kw = { 'name' : 'anyType',
1958 'schema' : schema,
1959 'namespace_context' : ns_ctx,
1960 'binding_namespace' : schema.targetNamespace(),
1961 'derivation_method' : cls.DM_restriction,
1962 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1963 bi = _UrTypeDefinition(**kw)
1964
1965
1966 bi.__baseTypeDefinition = bi
1967
1968
1969 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1970
1971
1972
1973
1974
1975
1976 kw = { 'namespace_context' : ns_ctx
1977 , 'schema' : schema
1978 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
1979 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
1980 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
1981 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
1982 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
1983
1984
1985 bi.__attributeUses = set()
1986
1987
1988 bi.__final = cls.DM_empty
1989 bi.__prohibitedSubstitutions = cls.DM_empty
1990
1991 bi.__abstract = False
1992
1993
1994 bi.setNameInBinding(bi.name())
1995
1996
1997 bi.__derivationMethod = cls.DM_restriction
1998
1999 cls.__UrTypeDefinition = bi
2000 return cls.__UrTypeDefinition
2001
2003 """Indicate whether this simple type is a built-in type."""
2004 return (self.UrTypeDefinition() == self)
2005
2006
2022
2023
2024 @classmethod
2048
2049 __baseAttribute = None
2050
2051
2052 __ckw = None
2053 __anyAttribute = None
2054 __attributeGroupAttributes = None
2055 __usesC1 = None
2056 __usesC1C2 = None
2057 __attributeGroups = None
2058 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2059
2060
2062
2063 if self.__usesC1C2 is None:
2064
2065 uses_c1 = self.__usesC1
2066 uses_c2 = set()
2067 self.__attributeGroups = []
2068 for ag_attr in self.__attributeGroupAttributes:
2069 ag_en = self._namespaceContext().interpretQName(ag_attr)
2070 agd = ag_en.attributeGroupDefinition()
2071 if agd is None:
2072 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2073 if not agd.isResolved():
2074 self._queueForResolution('unresolved attribute group', depends_on=agd)
2075 return self
2076 self.__attributeGroups.append(agd)
2077 uses_c2.update(agd.attributeUses())
2078
2079 uses_c1c2 = uses_c1.union(uses_c2)
2080 for au in uses_c1c2:
2081 if not au.isResolved():
2082 self._queueForResolution('attribute use not resolved')
2083 return self
2084 ad = au.attributeDeclaration()
2085 if not ad.isResolved():
2086 ad_en = ad.expandedName()
2087 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2088 return self
2089
2090 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2091
2092
2093
2094
2095
2096
2097 uses_c3 = set()
2098 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2099
2100
2101 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2102 assert self.__baseTypeDefinition.isResolved()
2103 for au in uses_c3:
2104 if not au.isResolved():
2105 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2106 return self
2107 ad = au.attributeDeclaration()
2108 if not ad.isResolved():
2109 ad_en = ad.expandedName()
2110 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2111 return self
2112 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2113
2114 if self.DM_restriction == method:
2115
2116
2117
2118 for au in self.__usesC1C2:
2119 matching_uses = au.matchingQNameMembers(uses_c3)
2120 assert matching_uses is not None
2121 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2122 for au2 in matching_uses:
2123 assert au2.isResolved()
2124 uses_c3.remove(au2)
2125 au._setRestrictionOf(au2)
2126 else:
2127
2128
2129
2130 assert self.DM_extension == method
2131
2132 use_map = { }
2133 for au in self.__usesC1C2.union(uses_c3):
2134 assert au.isResolved()
2135 ad_en = au.attributeDeclaration().expandedName()
2136 if ad_en in use_map:
2137 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2138 use_map[ad_en] = au
2139
2140
2141
2142 self.__attributeUses = frozenset(use_map.values())
2143 if not self._scopeIsIndeterminate():
2144 for au in self.__attributeUses:
2145 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2146
2147
2148
2149 local_wildcard = None
2150 if self.__anyAttribute is not None:
2151 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2152
2153
2154 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2155
2156
2157 if self.DM_restriction == method:
2158
2159 self._setAttributeWildcard(complete_wildcard)
2160 else:
2161 assert (self.DM_extension == method)
2162 assert self.baseTypeDefinition().isResolved()
2163
2164 base_wildcard = None
2165 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2166 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2167
2168 if base_wildcard is not None:
2169 if complete_wildcard is None:
2170
2171 self._setAttributeWildcard(base_wildcard)
2172 else:
2173
2174 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2175 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2176 base_wildcard.namespaceConstraint()]),
2177 annotation=complete_wildcard.annotation(),
2178 namespace_context=self._namespaceContext()))
2179 else:
2180
2181 self._setAttributeWildcard(complete_wildcard)
2182
2183
2184
2185
2186 del self.__usesC1
2187 del self.__usesC1C2
2188 del self.__attributeGroups
2189 self.__ckw = None
2190
2191
2192
2193
2194 self.__derivationMethod = method
2195 return self
2196
2197 - def __simpleContent (self, method, **kw):
2198
2199 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2200
2201 parent_content_type = self.__baseTypeDefinition.__contentType
2202 if ((type(parent_content_type) == tuple) \
2203 and (self.CT_SIMPLE == parent_content_type[0]) \
2204 and (self.DM_restriction == method)):
2205
2206 assert self.__ctscRestrictionNode is not None
2207 std = self.__ctscClause2STD
2208 if std is None:
2209 std = parent_content_type[1]
2210 assert isinstance(std, SimpleTypeDefinition)
2211 if not std.isResolved():
2212 return None
2213 restriction_node = self.__ctscRestrictionNode
2214 self.__ctscClause2STD = None
2215 self.__ctscRestrictionNode = None
2216 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2217 if ((type(parent_content_type) == tuple) \
2218 and (self.CT_MIXED == parent_content_type[0]) \
2219 and parent_content_type[1].isEmptiable()):
2220
2221 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2222 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2223
2224 return parent_content_type
2225
2226 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2227
2228 __ctscClause2STD = None
2229 __ctscRestrictionNode = None
2230 __effectiveMixed = None
2231 __effectiveContent = None
2232 __pendingDerivationMethod = None
2233 __isComplexContent = None
2234 - def _isComplexContent (self):
2236 __ctscRestrictionMode = None
2237 __contentStyle = None
2238
2239 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2240
2241
2242 ckw = kw.copy()
2243 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2244
2245
2246 mixed_attr = None
2247 if content_node is not None:
2248 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2249 if mixed_attr is None:
2250 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2251 if mixed_attr is not None:
2252 effective_mixed = datatypes.boolean(mixed_attr)
2253 else:
2254 effective_mixed = False
2255
2256
2257 test_2_1_1 = True
2258 test_2_1_2 = False
2259 test_2_1_3 = False
2260 typedef_node = None
2261 for cn in definition_node_list:
2262 if Node.ELEMENT_NODE != cn.nodeType:
2263 continue
2264 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2265
2266 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2267 if Particle.IsTypedefNode(cn):
2268 typedef_node = cn
2269 test_2_1_1 = False
2270 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2271 and (not domutils.HasNonAnnotationChild(cn)):
2272 test_2_1_2 = True
2273 if xsd.nodeIsNamed(cn, 'choice') \
2274 and (not domutils.HasNonAnnotationChild(cn)):
2275 mo_attr = domutils.NodeAttribute(cn, 'minOccurs')
2276 if ((mo_attr is not None) \
2277 and (0 == datatypes.integer(mo_attr))):
2278 test_2_1_3 = True
2279 satisfied_predicates = 0
2280 if test_2_1_1:
2281 satisfied_predicates += 1
2282 if test_2_1_2:
2283 satisfied_predicates += 1
2284 if test_2_1_3:
2285 satisfied_predicates += 1
2286 if 1 == satisfied_predicates:
2287 if effective_mixed:
2288
2289 assert (typedef_node is None) or test_2_1_2
2290 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2291 effective_content = Particle(m, **ckw)
2292 else:
2293
2294 effective_content = self.CT_EMPTY
2295 else:
2296
2297 assert typedef_node is not None
2298 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2299
2300
2301
2302
2303
2304
2305
2306 self.__effectiveMixed = effective_mixed
2307 self.__effectiveContent = effective_content
2308 self.__ckw = ckw
2309
2310 - def __complexContent (self, method):
2311 ckw = self.__ckw
2312
2313
2314 if self.__effectiveMixed:
2315 ct = self.CT_MIXED
2316 else:
2317 ct = self.CT_ELEMENT_ONLY
2318
2319 if self.DM_restriction == method:
2320
2321 if self.CT_EMPTY == self.__effectiveContent:
2322
2323 content_type = self.CT_EMPTY
2324 else:
2325
2326 content_type = ( ct, self.__effectiveContent )
2327 assert 0 == len(self.__scopedElementDeclarations)
2328
2329
2330
2331
2332 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2333 else:
2334
2335 assert self.DM_extension == method
2336 assert self.__baseTypeDefinition.isResolved()
2337 parent_content_type = self.__baseTypeDefinition.contentType()
2338 if self.CT_EMPTY == self.__effectiveContent:
2339 content_type = parent_content_type
2340 elif self.CT_EMPTY == parent_content_type:
2341
2342 content_type = ( ct, self.__effectiveContent )
2343 else:
2344 assert type(parent_content_type) == tuple
2345 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2346 content_type = ( ct, Particle(m, **ckw) )
2347
2348 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2349 return content_type
2350
2352 """Indicate whether this complex type is fully defined.
2353
2354 All built-in type definitions are resolved upon creation.
2355 Schema-defined type definitionss are held unresolved until the
2356 schema has been completely read, so that references to later
2357 schema-defined types can be resolved. Resolution is performed
2358 after the entire schema has been scanned and type-definition
2359 instances created for all topLevel{Simple,Complex}Types.
2360
2361 If a built-in type definition is also defined in a schema
2362 (which it should be), the built-in definition is kept, with
2363 the schema-related information copied over from the matching
2364 schema-defined type definition. The former then replaces the
2365 latter in the list of type definitions to be resolved. See
2366 Schema._addNamedComponent.
2367 """
2368
2369 return (self.__derivationMethod is not None)
2370
2371
2372
2376
2377 - def __setContentFromDOM (self, node, **kw):
2378 schema = kw.get('schema')
2379 assert schema is not None
2380 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2381 self.__final = schema.finalForNode(node, self._DM_Map)
2382
2383 attr_val = domutils.NodeAttribute(node, 'abstract')
2384 if attr_val is not None:
2385 self.__abstract = datatypes.boolean(attr_val)
2386
2387
2388
2389 definition_node_list = node.childNodes
2390 is_complex_content = True
2391 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2392 method = self.DM_restriction
2393
2394
2395
2396
2397 first_elt = domutils.LocateFirstChildElement(node)
2398 content_node = None
2399 clause2_std = None
2400 ctsc_restriction_node = None
2401 if first_elt:
2402 have_content = False
2403 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2404 have_content = True
2405 is_complex_content = False
2406 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2407 have_content = True
2408 else:
2409
2410
2411 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2412 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2413 if have_content:
2414
2415 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2416 assert content_node == first_elt
2417
2418
2419
2420 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2421 if xsd.nodeIsNamed(ions, 'restriction'):
2422 method = self.DM_restriction
2423 if not is_complex_content:
2424
2425 ctsc_restriction_node = ions
2426 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2427 if ions_st is not None:
2428 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2429 elif xsd.nodeIsNamed(ions, 'extension'):
2430 method = self.DM_extension
2431 else:
2432 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2433 self.__baseAttribute = domutils.NodeAttribute(ions, 'base')
2434 if self.__baseAttribute is None:
2435 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2436 self.__baseTypeDefinition = None
2437
2438 definition_node_list = ions.childNodes
2439
2440 self.__pendingDerivationMethod = method
2441 self.__isComplexContent = is_complex_content
2442 self.__ctscRestrictionNode = ctsc_restriction_node
2443 self.__ctscClause2STD = clause2_std
2444
2445 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2446 self.__usesC1 = set()
2447 for cn in attributes:
2448 au = AttributeUse.CreateFromDOM(cn, **kw)
2449 self.__usesC1.add(au)
2450 self.__attributeGroupAttributes = attribute_group_attrs
2451 self.__anyAttribute = any_attribute
2452
2453 if self.__isComplexContent:
2454 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2455
2456
2457
2458 self._annotationFromDOM(node)
2459
2460 if not self.isResolved():
2461 self._queueForResolution('creation')
2462
2463 return self
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2529
2531 """Complex type definitions have no built-in type support."""
2532 return None
2533
2538
2540 """Subclass ensures there is only one ur-type."""
2542 """The ur-type does have a Python class backing it up."""
2543 return datatypes.anyType
2544
2549
2550
2551 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2662
2664 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2665
2666 __modelGroup = None
2667
2669 """The model group for which this definition provides a name."""
2670 return self.__modelGroup
2671
2672
2673 @classmethod
2675 """Create a Model Group Definition from a DOM element node.
2676
2677 wxs is a Schema instance within which the model group is being
2678 defined.
2679
2680 node is a DOM element. The name must be 'group', and the node
2681 must be in the XMLSchema namespace. The node must have a
2682 'name' attribute, and must not have a 'ref' attribute.
2683 """
2684 assert xsd.nodeIsNamed(node, 'group')
2685
2686 assert domutils.NodeAttribute(node, 'ref') is None
2687
2688 name = domutils.NodeAttribute(node, 'name')
2689 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2690 rv = cls(name=name, node=node, **kw)
2691 rv._annotationFromDOM(node)
2692
2693 kw.pop('node', None)
2694 kw['owner'] = rv
2695
2696 for cn in node.childNodes:
2697 if Node.ELEMENT_NODE != cn.nodeType:
2698 continue
2699 if ModelGroup.IsGroupMemberNode(cn):
2700 assert not rv.__modelGroup
2701
2702
2703
2704 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2705 assert rv.__modelGroup is not None
2706 return rv
2707
2708
2710 """Model group definitions depend on the contained model group."""
2711 if not include_lax:
2712 return frozenset()
2713 return frozenset([self.__modelGroup])
2714
2717
2718
2719 -class ModelGroup (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
2720 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2721 C_INVALID = 0
2722 C_ALL = 0x01
2723 C_CHOICE = 0x02
2724 C_SEQUENCE = 0x03
2725
2726
2727
2728 __compositor = C_INVALID
2731
2732 @classmethod
2742
2746
2747
2748
2749 __particles = None
2750 - def particles (self):
2751 return self.__particles
2752
2754 """A model group has an unresolvable particle if any of its
2755 particles is unresolvable. Duh."""
2756 for p in self.particles():
2757 if not p.isAdaptable(ctd):
2758 return False
2759 return True
2760
2762 """Return the minimum and maximum of the number of elements that can
2763 appear in a sequence matched by this particle.
2764
2765 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2766 """
2767 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2768 sum_minoccurs = 0
2769 sum_maxoccurs = 0
2770 for prt in self.__particles:
2771 (prt_min, prt_max) = prt.effectiveTotalRange()
2772 sum_minoccurs += prt_min
2773 if sum_maxoccurs is not None:
2774 if prt_max is None:
2775 sum_maxoccurs = None
2776 else:
2777 sum_maxoccurs += prt_max
2778 prod_maxoccurs = particle.maxOccurs()
2779 if prod_maxoccurs is not None:
2780 if sum_maxoccurs is None:
2781 prod_maxoccurs = None
2782 else:
2783 prod_maxoccurs *= sum_maxoccurs
2784 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2785 assert self.__compositor == self.C_CHOICE
2786 if 0 == len(self.__particles):
2787 min_minoccurs = 0
2788 max_maxoccurs = 0
2789 else:
2790 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2791 for prt in self.__particles[1:]:
2792 (prt_min, prt_max) = prt.effectiveTotalRange()
2793 if prt_min < min_minoccurs:
2794 min_minoccurs = prt_min
2795 if prt_max is None:
2796 max_maxoccurs = None
2797 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2798 max_maxoccurs = prt_max
2799 min_minoccurs *= particle.minOccurs()
2800 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2801 max_maxoccurs *= particle.maxOccurs()
2802 return (min_minoccurs, max_maxoccurs)
2803
2804
2805
2806
2807 __modelGroupDefinition = None
2809 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2810 return self.__modelGroupDefinition
2811
2812 - def __init__ (self, compositor, particles, *args, **kw):
2813 """Create a new model group.
2814
2815 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2816
2817 particles must be a list of zero or more Particle instances.
2818
2819 scope is the _ScopeDeclaration_mixin context into which new
2820 declarations are recorded. It can be SCOPE_global, a complex
2821 type definition, or None if this is (or is within) a named
2822 model group.
2823
2824 model_group_definition is an instance of ModelGroupDefinition
2825 if this is a named model group. It defaults to None
2826 indicating a local group.
2827 """
2828
2829 super(ModelGroup, self).__init__(*args, **kw)
2830 assert 'scope' in kw
2831 self.__compositor = compositor
2832 self.__particles = particles
2833 self.__modelGroupDefinition = kw.get('model_group_definition')
2834
2836 """Return True if the model includes a wildcard amongst its particles."""
2837 for p in self.particles():
2838 if p.hasWildcardElement():
2839 return True
2840 return False
2841
2842
2844 if not include_lax:
2845 return frozenset()
2846 return frozenset(self.__particles)
2847
2848
2849 @classmethod
2851 """Create a model group from the given DOM node.
2852
2853 wxs is a Schema instance within which the model group is being
2854 defined.
2855
2856 node is a DOM element. The name must be one of ( 'all',
2857 'choice', 'sequence' ), and the node must be in the XMLSchema
2858 namespace.
2859
2860 scope is the _ScopeDeclaration_mxin context that is assigned
2861 to declarations that appear within the model group. It can be
2862 None, indicating no scope defined, or a complex type
2863 definition.
2864 """
2865
2866 scope = kw['scope']
2867 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2868
2869 if xsd.nodeIsNamed(node, 'all'):
2870 compositor = cls.C_ALL
2871 elif xsd.nodeIsNamed(node, 'choice'):
2872 compositor = cls.C_CHOICE
2873 else:
2874 assert xsd.nodeIsNamed(node, 'sequence')
2875 compositor = cls.C_SEQUENCE
2876 particles = []
2877
2878 kw.pop('owner', None)
2879 for cn in node.childNodes:
2880 if Node.ELEMENT_NODE != cn.nodeType:
2881 continue
2882 if Particle.IsParticleNode(cn):
2883
2884 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2885 elif not xsd.nodeIsNamed(cn, 'annotation'):
2886 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2887 rv = cls(compositor, particles, node=node, **kw)
2888 for p in particles:
2889 p._setOwner(rv)
2890 rv._annotationFromDOM(node)
2891 return rv
2892
2893 @classmethod
2896
2897
2908
2909 - def _walkParticleTree (self, visit, arg):
2910 visit(self, True, arg)
2911 for p in self.particles():
2912 p._walkParticleTree(visit, arg)
2913 visit(self, False, arg)
2914
2924
2925 -class Particle (_ParticleTree_mixin, _SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2926 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2927
2928
2929 __minOccurs = 1
2930 - def minOccurs (self):
2931 """The minimum number of times the term may appear.
2932
2933 Defaults to 1."""
2934 return self.__minOccurs
2935
2936
2937 __maxOccurs = 1
2938 - def maxOccurs (self):
2939 """Upper limit on number of times the term may appear.
2940
2941 If None, the term may appear any number of times; otherwise,
2942 this is an integral value indicating the maximum number of times
2943 the term may appear. The default value is 1; the value, unless
2944 None, must always be at least minOccurs().
2945 """
2946 return self.__maxOccurs
2947
2948
2949 __term = None
2951 """A reference to a ModelGroup, Wildcard, or ElementDeclaration."""
2952 return self.__term
2953 __pendingTerm = None
2954
2955 __refAttribute = None
2956 __resolvableType = None
2957
2959 """Extend the concept of effective total range to all particles.
2960
2961 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
2962 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
2963 """
2964 if isinstance(self.__term, ModelGroup):
2965 return self.__term.effectiveTotalRange(self)
2966 return (self.minOccurs(), self.maxOccurs())
2967
2968 - def isEmptiable (self):
2969 """Return C{True} iff this particle can legitimately match an empty
2970 sequence (no content).
2971
2972 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
2973 """
2974 return 0 == self.effectiveTotalRange()[0]
2975
2977 """Return True iff this particle has a wildcard in its term.
2978
2979 Note that the wildcard may be in a nested model group."""
2980 return self.term().hasWildcardElement()
2981
2982 - def __init__ (self, term, *args, **kw):
2983 """Create a particle from the given DOM node.
2984
2985 term is a XML Schema Component: one of ModelGroup,
2986 ElementDeclaration, and Wildcard.
2987
2988 The following keyword arguments are processed:
2989
2990 min_occurs is a non-negative integer value with default 1,
2991 denoting the minimum number of terms required by the content
2992 model.
2993
2994 max_occurs is a positive integer value with default 1, or None
2995 indicating unbounded, denoting the maximum number of terms
2996 allowed by the content model.
2997
2998 scope is the _ScopeDeclaration_mxin context that is assigned
2999 to declarations that appear within the particle. It can be
3000 None, indicating no scope defined, or a complex type
3001 definition.
3002 """
3003
3004 super(Particle, self).__init__(*args, **kw)
3005
3006 min_occurs = kw.get('min_occurs', 1)
3007 max_occurs = kw.get('max_occurs', 1)
3008
3009 assert 'scope' in kw
3010 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
3011
3012 if term is not None:
3013 self.__term = term
3014
3015 assert isinstance(min_occurs, (types.IntType, types.LongType))
3016 self.__minOccurs = min_occurs
3017 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
3018 self.__maxOccurs = max_occurs
3019 if self.__maxOccurs is not None:
3020 if self.__minOccurs > self.__maxOccurs:
3021 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3022
3023
3024 - def _resolve (self):
3025 if self.isResolved():
3026 return self
3027
3028
3029 if ModelGroup == self.__resolvableType:
3030 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3031 group_decl = ref_en.modelGroupDefinition()
3032 if group_decl is None:
3033 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
3034
3035 self.__pendingTerm = group_decl.modelGroup()
3036 assert self.__pendingTerm is not None
3037 elif ElementDeclaration == self.__resolvableType:
3038
3039
3040
3041 if self.__refAttribute is not None:
3042 assert self.__pendingTerm is None
3043 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3044 self.__pendingTerm = ref_en.elementDeclaration()
3045 if self.__pendingTerm is None:
3046 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3047 assert self.__pendingTerm is not None
3048
3049
3050
3051
3052 assert self.__pendingTerm is not None
3053 else:
3054 assert False
3055
3056 self.__term = self.__pendingTerm
3057 assert self.__term is not None
3058
3059 return self
3060
3061 - def isResolved (self):
3062 return self.__term is not None
3063
3064
3065 @classmethod
3066 - def CreateFromDOM (cls, node, **kw):
3067 """Create a particle from the given DOM node.
3068
3069 wxs is a Schema instance within which the model group is being
3070 defined.
3071
3072 node is a DOM element. The name must be one of ( 'group',
3073 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3074 must be in the XMLSchema namespace.
3075
3076 scope is the _ScopeDeclaration_mxin context that is assigned
3077 to declarations that appear within the model group. It can be
3078 None, indicating no scope defined, or a complex type
3079 definition.
3080 """
3081 scope = kw['scope']
3082 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3083
3084 kw.update({ 'min_occurs' : 1
3085 , 'max_occurs' : 1
3086 , 'node' : node })
3087
3088 if not Particle.IsParticleNode(node):
3089 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3090 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3091 if attr_val is not None:
3092 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3093 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3094 if attr_val is not None:
3095 if 'unbounded' == attr_val:
3096 kw['max_occurs'] = None
3097 else:
3098 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3099
3100 rv = cls(None, **kw)
3101
3102 kw.pop('node', None)
3103 kw['owner'] = rv
3104
3105 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
3106 rv.__pendingTerm = None
3107 rv.__resolvableType = None
3108 if xsd.nodeIsNamed(node, 'group'):
3109
3110
3111
3112 if rv.__refAttribute is None:
3113 raise pyxb.SchemaValidationError('group particle without reference')
3114 rv.__resolvableType = ModelGroup
3115 elif xsd.nodeIsNamed(node, 'element'):
3116 if rv.__refAttribute is None:
3117 schema = kw.get('schema')
3118 assert schema is not None
3119 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3120 incoming_tns = kw.get('target_namespace')
3121 if incoming_tns is not None:
3122 assert incoming_tns == target_namespace
3123 else:
3124 kw['target_namespace'] = target_namespace
3125 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3126 else:
3127
3128
3129
3130 for tag in ('nillable', 'default', 'fixed', 'form', 'block', 'type'):
3131 av = domutils.NodeAttribute(node, tag)
3132 if av is not None:
3133 raise pyxb.SchemaValidationError('element with "ref" cannot have "%s"' % (tag,))
3134 rv.__resolvableType = ElementDeclaration
3135 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3136 elif xsd.nodeIsNamed(node, 'any'):
3137
3138 rv.__term = Wildcard.CreateFromDOM(node=node)
3139 elif ModelGroup.IsGroupMemberNode(node):
3140
3141
3142
3143 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3144 else:
3145 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3146
3147 if not rv.isResolved():
3148 rv._queueForResolution('creation')
3149 return rv
3150
3151
3152 - def _bindingRequires_vx (self, include_lax):
3153 if not include_lax:
3154 return frozenset()
3155 return frozenset([ self.__term ])
3156
3157
3158 - def _adaptForScope (self, owner, ctd):
3159 rv = self
3160 assert isinstance(ctd, ComplexTypeDefinition)
3161 maybe_rv = self._clone(owner, ctd._objectOrigin())
3162 term = rv.__term._adaptForScope(maybe_rv, ctd)
3163 do_clone = (self._scope() != ctd) or (rv.__term != term)
3164 if do_clone:
3165 rv = maybe_rv
3166 rv.__term = term
3167 return rv
3168
3169 - def isAdaptable (self, ctd):
3170 """A particle has an unresolvable particle if it cannot be
3171 resolved, or if it has resolved to a term which is a model
3172 group that has an unresolvable particle.
3173 """
3174 if not self.isResolved():
3175 return False
3176 return self.term().isAdaptable(ctd)
3177
3178 - def walkParticleTree (self, visit, arg):
3179 """The entry-point to walk a particle tree defining a content model.
3180
3181 See L{_ParticleTree_mixin._walkParticleTree}."""
3182 self._walkParticleTree(visit, arg)
3183
3184 - def _walkParticleTree (self, visit, arg):
3185 visit(self, True, arg)
3186 self.__term._walkParticleTree(visit, arg)
3187 visit(self, False, arg)
3188
3189 @classmethod
3190 - def IsTypedefNode (cls, node):
3191 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3192
3193 @classmethod
3194 - def IsParticleNode (cls, node, *others):
3195 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3196
3197 - def __str__ (self):
3198
3199 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3200
3201
3202
3203 -class Wildcard (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
3204 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3205
3206 NC_any = '##any'
3207 NC_not = '##other'
3208 NC_targetNamespace = '##targetNamespace'
3209 NC_local = '##local'
3210
3211 __namespaceConstraint = None
3213 """A constraint on the namespace for the wildcard.
3214
3215 Valid values are:
3216 - L{Wildcard.NC_any}
3217 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3218 - set(of_namespaces)
3219
3220 Note that namespace are represented by
3221 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3222 actually define a namespace. Absence of a namespace is represented by
3223 C{None}, both in the "not" pair and in the set.
3224 """
3225 return self.__namespaceConstraint
3226
3227 @classmethod
3229 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3230 assert 0 < len(constraints)
3231 o1 = constraints.pop(0)
3232 while 0 < len(constraints):
3233 o2 = constraints.pop(0)
3234
3235 if (o1 == o2):
3236 continue
3237
3238 if (cls.NC_any == o1) or (cls.NC_any == o2):
3239 o1 = cls.NC_any
3240 continue
3241
3242 if isinstance(o1, set) and isinstance(o2, set):
3243 o1 = o1.union(o2)
3244 continue
3245
3246 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3247 o1 = ( cls.NC_not, None )
3248 continue
3249
3250
3251 c_tuple = None
3252 c_set = None
3253 if isinstance(o1, tuple):
3254 assert isinstance(o2, set)
3255 c_tuple = o1
3256 c_set = o2
3257 else:
3258 assert isinstance(o1, set)
3259 assert isinstance(o2, tuple)
3260 c_tuple = o2
3261 c_set = o1
3262 negated_ns = c_tuple[1]
3263 if negated_ns is not None:
3264
3265 if (negated_ns in c_set) and (None in c_set):
3266 o1 = cls.NC_any
3267 continue
3268
3269 if negated_ns in c_set:
3270 o1 = ( cls.NC_not, None )
3271 continue
3272
3273 if None in c_set:
3274 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3275 o1 = c_tuple
3276 continue
3277
3278 if None in c_set:
3279 o1 = cls.NC_any
3280 else:
3281 o1 = ( cls.NC_not, None )
3282 return o1
3283
3284 @classmethod
3286 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3287 assert 0 < len(constraints)
3288 o1 = constraints.pop(0)
3289 while 0 < len(constraints):
3290 o2 = constraints.pop(0)
3291
3292 if (o1 == o2):
3293 continue
3294
3295 if (cls.NC_any == o1) or (cls.NC_any == o2):
3296 if cls.NC_any == o1:
3297 o1 = o2
3298 continue
3299
3300 if isinstance(o1, set) and isinstance(o2, set):
3301 o1 = o1.intersection(o2)
3302 continue
3303 if isinstance(o1, tuple) and isinstance(o2, tuple):
3304 ns1 = o1[1]
3305 ns2 = o2[1]
3306
3307 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3308 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3309
3310 assert (ns1 is None) or (ns2 is None)
3311 if ns1 is None:
3312 assert ns2 is not None
3313 o1 = ( cls.NC_not, ns2 )
3314 else:
3315 assert ns1 is not None
3316 o1 = ( cls.NC_not, ns1 )
3317 continue
3318
3319
3320
3321 c_tuple = None
3322 c_set = None
3323 if isinstance(o1, tuple):
3324 assert isinstance(o2, set)
3325 c_tuple = o1
3326 c_set = o2
3327 else:
3328 assert isinstance(o1, set)
3329 assert isinstance(o2, tuple)
3330 c_tuple = o2
3331 c_set = o1
3332 negated_ns = c_tuple[1]
3333 if negated_ns in c_set:
3334 c_set.remove(negated_ns)
3335 if None in c_set:
3336 c_set.remove(None)
3337 o1 = c_set
3338 return o1
3339
3340 PC_skip = 'skip'
3341 PC_lax = 'lax'
3342 PC_strict = 'strict'
3343
3344
3345 __processContents = None
3346 - def processContents (self):
3347 return self.__processContents
3348
3350 """Return True, since Wildcard components are wildcards."""
3351 return True
3352
3358
3361
3362 - def _walkParticleTree (self, visit, arg):
3363 visit(self, None, arg)
3364
3365
3367 """Wildcards are scope-independent; return self"""
3368 return self
3369
3370
3371 @classmethod
3373 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3374 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3375 nc = domutils.NodeAttribute(node, 'namespace')
3376 if nc is None:
3377 namespace_constraint = cls.NC_any
3378 else:
3379 if cls.NC_any == nc:
3380 namespace_constraint = cls.NC_any
3381 elif cls.NC_not == nc:
3382 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3383 else:
3384 ncs = set()
3385 for ns_uri in nc.split():
3386 if cls.NC_local == ns_uri:
3387 ncs.add(None)
3388 elif cls.NC_targetNamespace == ns_uri:
3389 ncs.add(namespace_context.targetNamespace())
3390 else:
3391 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3392 namespace_constraint = frozenset(ncs)
3393
3394 pc = domutils.NodeAttribute(node, 'processContents')
3395 if pc is None:
3396 process_contents = cls.PC_strict
3397 else:
3398 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3399 process_contents = pc
3400 else:
3401 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3402
3403 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3404 rv._annotationFromDOM(node)
3405 return rv
3406
3407
3408 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3409 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3410
3411 ICC_KEY = 0x01
3412 ICC_KEYREF = 0x02
3413 ICC_UNIQUE = 0x04
3414
3415 __identityConstraintCategory = None
3418
3419 __selector = None
3422
3423 __fields = None
3426
3427 __referencedKey = None
3428 __referAttribute = None
3429 __icc = None
3430
3431 __annotations = None
3434
3435
3436 @classmethod
3438 name = domutils.NodeAttribute(node, 'name')
3439 scope = kw['scope']
3440 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3441 rv = cls(name=name, node=node, **kw)
3442
3443 kw.pop('node', None)
3444 kw['owner'] = rv
3445
3446
3447 rv.__isResolved = True
3448 icc = None
3449 if xsd.nodeIsNamed(node, 'key'):
3450 icc = rv.ICC_KEY
3451 elif xsd.nodeIsNamed(node, 'keyref'):
3452 icc = rv.ICC_KEYREF
3453 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3454 if rv.__referAttribute is None:
3455 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3456 rv.__isResolved = False
3457 elif xsd.nodeIsNamed(node, 'unique'):
3458 icc = rv.ICC_UNIQUE
3459 else:
3460 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3461 rv.__icc = icc
3462
3463 cn = domutils.LocateUniqueChild(node, 'selector')
3464 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3465 if rv.__selector is None:
3466 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3467
3468 rv.__fields = []
3469 for cn in domutils.LocateMatchingChildren(node, 'field'):
3470 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3471 if xp_attr is None:
3472 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3473 rv.__fields.append(xp_attr)
3474
3475 rv._annotationFromDOM(node)
3476 rv.__annotations = []
3477 if rv.annotation() is not None:
3478 rv.__annotations.append(rv)
3479
3480 for cn in node.childNodes:
3481 if (Node.ELEMENT_NODE != cn.nodeType):
3482 continue
3483 an = None
3484 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3485 an = domutils.LocateUniqueChild(cn, 'annotation')
3486 elif xsd.nodeIsNamed(cn, 'annotation'):
3487 an = cn
3488 if an is not None:
3489 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3490
3491 rv.__identityConstraintCategory = icc
3492 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3493 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3494
3495 if not rv.isResolved():
3496 rv._queueForResolution('creation')
3497 return rv
3498
3499 __isResolved = False
3502
3503
3518
3519
3521 """Constraint definitions that are by reference require the referenced constraint."""
3522 rv = set()
3523 if include_lax and (self.__referencedKey is not None):
3524 rv.add(self.__referencedKey)
3525 return frozenset(rv)
3526
3527
3528
3529
3530 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3531 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3532 __systemIdentifier = None
3535
3536 __publicIdentifier = None
3539
3540
3541 @classmethod
3551
3554 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3555
3556 __applicationInformation = None
3559
3560 __userInformation = None
3563
3564
3566 application_information = kw.pop('application_information', None)
3567 user_information = kw.pop('user_information', None)
3568 super(Annotation, self).__init__(**kw)
3569 if (user_information is not None) and (not isinstance(user_information, list)):
3570 user_information = [ unicode(user_information) ]
3571 if (application_information is not None) and (not isinstance(application_information, list)):
3572 application_information = [ unicode(application_information) ]
3573 self.__userInformation = user_information
3574 self.__applicationInformation = application_information
3575
3576
3577
3578
3579
3580
3581
3582
3583 __attributes = None
3584
3585
3586 @classmethod
3610
3611 __RemoveMultiQuote_re = re.compile('""+')
3613 """Return the text in a form suitable for embedding in a
3614 triple-double-quoted docstring.
3615
3616 Any sequence of two or more double quotes is replaced by a sequence of
3617 single quotes that is the same length. Following this, spaces are
3618 added at the start and the end as necessary to ensure a double quote
3619 does not appear in those positions."""
3620 rv = self.text()
3621 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3622 if rv.startswith('"'):
3623 rv = ' ' + rv
3624 if rv.endswith('"'):
3625 rv = rv + ' '
3626 return rv
3627
3629 if self.__userInformation is None:
3630 return ''
3631 text = []
3632
3633
3634 for dn in self.__userInformation:
3635 for cn in dn.childNodes:
3636 if Node.TEXT_NODE == cn.nodeType:
3637 text.append(cn.data)
3638 return ''.join(text)
3639
3641 """Return the catenation of all user information elements in the
3642 annotation as a single unicode string. Returns the empty string if
3643 there are no user information elements."""
3644 return self.text()
3645
3646
3647 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3648 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3649
3650
3651
3652
3653 __baseTypeDefinition = None
3656
3657 __memberTypes = None
3658 __itemTypeAttribute = None
3659 __baseAttribute = None
3660 __memberTypesAttribute = None
3661 __localFacets = None
3662
3663
3664
3665
3666
3667
3668 __facets = None
3672
3673
3674 __fundamentalFacets = None
3676 """A frozenset of instances of facets.FundamentallFacet."""
3677 return self.__fundamentalFacets
3678
3679 STD_empty = 0
3680 STD_extension = 0x01
3681 STD_list = 0x02
3682 STD_restriction = 0x04
3683 STD_union = 0x08
3684
3685 _STD_Map = { 'extension' : STD_extension
3686 , 'list' : STD_list
3687 , 'restriction' : STD_restriction
3688 , 'union' : STD_union }
3689
3690
3691 __final = STD_empty
3692 @classmethod
3694 """Convert a final value to a string."""
3695 tags = []
3696 if final_value & cls.STD_extension:
3697 tags.append('extension')
3698 if final_value & cls.STD_list:
3699 tags.append('list')
3700 if final_value & cls.STD_restriction:
3701 tags.append('restriction')
3702 if final_value & cls.STD_union:
3703 tags.append('union')
3704 return ' '.join(tags)
3705
3706 VARIETY_absent = 0x01
3707 VARIETY_atomic = 0x02
3708 VARIETY_list = 0x03
3709 VARIETY_union = 0x04
3710
3711
3712 _DA_empty = 'none specified'
3713 _DA_restriction = 'restriction'
3714 _DA_list = 'list'
3715 _DA_union = 'union'
3716
3719 __derivationAlternative = None
3720
3721
3722
3723 __variety = None
3726 @classmethod
3738
3739
3740 __primitiveTypeDefinition = None
3747
3748
3749 __itemTypeDefinition = None
3755
3756
3757 __memberTypeDefinitions = None
3763
3764
3793
3794
3795
3796
3797
3798 __domNode = None
3799
3800
3801
3802 __isBuiltin = False
3803
3804
3805
3806
3810
3812 """Extend base class unpickle support to retain link between
3813 this instance and the Python class that it describes.
3814
3815 This is because the pythonSupport value is a class reference,
3816 not an instance reference, so it wasn't deserialized, and its
3817 class member link was never set.
3818 """
3819 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3820 super_fn(state)
3821 if self.__pythonSupport is not None:
3822 self.__pythonSupport._SimpleTypeDefinition(self)
3823
3851
3853 """Override fields in this instance with those from the other.
3854
3855 This method is invoked only by Schema._addNamedComponent, and
3856 then only when a built-in type collides with a schema-defined
3857 type. Material like facets is not (currently) held in the
3858 built-in copy, so the DOM information is copied over to the
3859 built-in STD, which is subsequently re-resolved.
3860
3861 Returns self.
3862 """
3863 assert self != other
3864 assert self.isNameEquivalent(other)
3865 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3866
3867
3868 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3869 assert other.__domNode is not None
3870 self.__domNode = other.__domNode
3871
3872
3873 if other.__pythonSupport is not None:
3874
3875 self.__pythonSupport = other.__pythonSupport
3876
3877
3878 self.__variety = None
3879 return self
3880
3882 """Indicate whether this simple type is a built-in type."""
3883 return self.__isBuiltin
3884
3885 __SimpleUrTypeDefinition = None
3886 @classmethod
3923
3924 @classmethod
3959
3960 @classmethod
3992
3993 @classmethod
4025
4026 @classmethod
4053
4054 @classmethod
4056 """(Placeholder) Create a union simple type in the target namespace.
4057
4058 This function has not been implemented."""
4059 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4060
4062 simple_type_child = None
4063 for cn in body.childNodes:
4064 if (Node.ELEMENT_NODE == cn.nodeType):
4065 if not xsd.nodeIsNamed(cn, 'simpleType'):
4066 if other_elts_ok:
4067 continue
4068 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4069 assert not simple_type_child
4070 simple_type_child = cn
4071 if simple_type_child is None:
4072 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4073 return simple_type_child
4074
4075
4076
4077
4078
4079
4080
4081
4091
4098
4099 __localMemberTypes = None
4109
4120
4122 """Create facets for varieties that can take facets that are undeclared.
4123
4124 This means unions, which per section 4.1.2.3 of
4125 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4126 pattern restrictions."""
4127 if self.VARIETY_union != variety:
4128 return self
4129 self.__facets.setdefault(facets.CF_pattern)
4130 self.__facets.setdefault(facets.CF_enumeration)
4131 return self
4132
4134 """Identify the facets and properties for this stype.
4135
4136 This method simply identifies the facets that apply to this
4137 specific type, and records property values. Only
4138 explicitly-associated facets and properties are stored; others
4139 from base types will also affect this type. The information
4140 is taken from the applicationInformation children of the
4141 definition's annotation node, if any. If there is no support
4142 for the XMLSchema_hasFacetAndProperty namespace, this is a
4143 no-op.
4144
4145 Upon return, self.__facets is a map from the class for an
4146 associated fact to None, and self.__fundamentalFacets is a
4147 frozenset of instances of FundamentalFacet.
4148
4149 The return value is self.
4150 """
4151 self.__facets = { }
4152 self.__fundamentalFacets = frozenset()
4153 if self.annotation() is None:
4154 return self.__defineDefaultFacets(variety)
4155 app_info = self.annotation().applicationInformation()
4156 if app_info is None:
4157 return self.__defineDefaultFacets(variety)
4158 facet_map = { }
4159 fundamental_facets = set()
4160 seen_facets = set()
4161 for ai in app_info:
4162 for cn in ai.childNodes:
4163 if Node.ELEMENT_NODE != cn.nodeType:
4164 continue
4165 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4166 facet_name = domutils.NodeAttribute(cn, 'name')
4167 if facet_name is None:
4168 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4169 if facet_name in seen_facets:
4170 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4171 seen_facets.add(facet_name)
4172 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4173
4174 facet_map[facet_class] = None
4175 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4176 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4177 if 0 < len(facet_map):
4178 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4179 self.__facets = facet_map
4180 assert type(self.__facets) == types.DictType
4181 if 0 < len(fundamental_facets):
4182 self.__fundamentalFacets = frozenset(fundamental_facets)
4183 return self
4184
4185
4236
4251
4252
4253
4254
4256 assert self.__variety is None
4257 if self.__baseTypeDefinition is None:
4258 assert self.__baseAttribute is not None
4259 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4260 base_type = base_en.typeDefinition()
4261 if not isinstance(base_type, SimpleTypeDefinition):
4262 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4263 self.__baseTypeDefinition = base_type
4264
4265
4266
4267 assert self.__baseTypeDefinition != self
4268 if not self.__baseTypeDefinition.isResolved():
4269 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4270 return self
4271 if variety is None:
4272
4273
4274 variety = self.__baseTypeDefinition.__variety
4275 assert variety is not None
4276
4277 if self.VARIETY_absent == variety:
4278
4279
4280 pass
4281 elif self.VARIETY_atomic == variety:
4282
4283
4284
4285 ptd = self
4286 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4287 ptd = ptd.__baseTypeDefinition
4288
4289 self.__primitiveTypeDefinition = ptd
4290 elif self.VARIETY_list == variety:
4291 if self._DA_list == alternative:
4292 if self.__itemTypeAttribute is not None:
4293 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4294 self.__itemTypeDefinition = it_en.typeDefinition()
4295 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4296 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4297 elif self._DA_restriction == alternative:
4298 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4299 else:
4300 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4301 elif self.VARIETY_union == variety:
4302 if self._DA_union == alternative:
4303
4304
4305
4306
4307 if self.__memberTypeDefinitions is None:
4308 mtd = []
4309
4310
4311 if self.__memberTypesAttribute is not None:
4312 for mn in self.__memberTypesAttribute.split():
4313
4314 mn_en = self._namespaceContext().interpretQName(mn)
4315 std = mn_en.typeDefinition()
4316 if std is None:
4317 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4318
4319 assert isinstance(std, SimpleTypeDefinition)
4320 mtd.append(std)
4321
4322 mtd.extend(self.__localMemberTypes)
4323 self.__memberTypeDefinitions = mtd
4324 assert None not in self.__memberTypeDefinitions
4325
4326
4327
4328
4329
4330
4331 mtd = []
4332 for mt in self.__memberTypeDefinitions:
4333 assert isinstance(mt, SimpleTypeDefinition)
4334 if not mt.isResolved():
4335 self._queueForResolution('member type not resolved', depends_on=mt)
4336 return self
4337 if self.VARIETY_union == mt.variety():
4338 mtd.extend(mt.memberTypeDefinitions())
4339 else:
4340 mtd.append(mt)
4341 elif self._DA_restriction == alternative:
4342 assert self.__baseTypeDefinition
4343
4344 assert self.__baseTypeDefinition.isResolved()
4345 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4346 assert mtd is not None
4347 else:
4348 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4349
4350 self.__memberTypeDefinitions = mtd[:]
4351 else:
4352 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4353
4354
4355
4356 self.__processHasFacetAndProperty(variety)
4357 self.__updateFacets(body)
4358
4359 self.__derivationAlternative = alternative
4360 self.__variety = variety
4361 self.__domNode = None
4362 return self
4363
4365 """Indicate whether this simple type is fully defined.
4366
4367 Type resolution for simple types means that the corresponding
4368 schema component fields have been set. Specifically, that
4369 means variety, baseTypeDefinition, and the appropriate
4370 additional fields depending on variety. See _resolve() for
4371 more information.
4372 """
4373
4374 return (self.__variety is not None)
4375
4376
4378 """Attempt to resolve the type.
4379
4380 Type resolution for simple types means that the corresponding
4381 schema component fields have been set. Specifically, that
4382 means variety, baseTypeDefinition, and the appropriate
4383 additional fields depending on variety.
4384
4385 All built-in STDs are resolved upon creation. Schema-defined
4386 STDs are held unresolved until the schema has been completely
4387 read, so that references to later schema-defined STDs can be
4388 resolved. Resolution is performed after the entire schema has
4389 been scanned and STD instances created for all
4390 topLevelSimpleTypes.
4391
4392 If a built-in STD is also defined in a schema (which it should
4393 be for XMLSchema), the built-in STD is kept, with the
4394 schema-related information copied over from the matching
4395 schema-defined STD. The former then replaces the latter in
4396 the list of STDs to be resolved.
4397
4398 Types defined by restriction have the same variety as the type
4399 they restrict. If a simple type restriction depends on an
4400 unresolved type, this method simply queues it for resolution
4401 in a later pass and returns.
4402 """
4403 if self.__variety is not None:
4404 return self
4405 assert self.__domNode
4406 node = self.__domNode
4407
4408 kw = { 'owner' : self
4409 , 'schema' : self._schema() }
4410
4411 bad_instance = False
4412
4413
4414 candidate = domutils.LocateUniqueChild(node, 'list')
4415 if candidate:
4416 self.__initializeFromList(candidate, **kw)
4417
4418 candidate = domutils.LocateUniqueChild(node, 'restriction')
4419 if candidate:
4420 if self.__variety is None:
4421 self.__initializeFromRestriction(candidate, **kw)
4422 else:
4423 bad_instance = True
4424
4425 candidate = domutils.LocateUniqueChild(node, 'union')
4426 if candidate:
4427 if self.__variety is None:
4428 self.__initializeFromUnion(candidate, **kw)
4429 else:
4430 bad_instance = True
4431
4432 if self.__baseTypeDefinition is None:
4433 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4434
4435 if self._schema() is not None:
4436 self.__final = self._schema().finalForNode(node, self._STD_Map)
4437
4438
4439 if bad_instance:
4440 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4441
4442 return self
4443
4444
4445 @classmethod
4461
4462
4463
4464
4465 __pythonSupport = None
4466
4476
4479
4484
4487
4490
4492 """Subclass ensures there is only one simple ur-type."""
4493 pass
4494
4600
4601 -class Schema (_SchemaComponent_mixin):
4602 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4603
4606
4607
4608 __annotations = None
4609
4610
4611
4612 __pastProlog = False
4613
4615 """URI or path to where the schema can be found.
4616
4617 For schema created by a user, the location should be provided to the
4618 constructor using the C{schema_location} keyword. In the case of
4619 imported or included schema, the including schema's location is used
4620 as the base URI for determining the absolute URI of the included
4621 schema from its (possibly relative) location value. For files,
4622 the scheme and authority portions are generally absent, as is often
4623 the abs_path part."""
4624 return self.__location
4625 __location = None
4626
4629 __locationTag = None
4630
4633 __signature = None
4634
4637 __generationUID = None
4638
4641 __originRecord = None
4642
4644 """The targetNamespace of a componen.
4645
4646 This is None, or a reference to a Namespace in which the
4647 component is declared (either as a global or local to one of
4648 the namespace's complex type definitions). This is immutable
4649 after creation.
4650 """
4651 return self.__targetNamespace
4652 __targetNamespace = None
4653
4655 """Default namespace of the schema.
4656
4657 Will be None unless the schema has an 'xmlns' attribute. The
4658 value must currently be provided as a keyword parameter to the
4659 constructor. """
4660 return self.__defaultNamespace
4661 __defaultNamespace = None
4662
4665 __referencedNamespaces = None
4666
4667 __namespaceData = None
4668
4671 __importEIIs = None
4672
4675 __importedSchema = None
4678 __includedSchema = None
4679
4680 _QUALIFIED = "qualified"
4681 _UNQUALIFIED = "unqualified"
4682
4683
4684 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4685 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4686 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4687 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4688 , pyxb.namespace.ExpandedName(None, 'id') : None
4689 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4690 , pyxb.namespace.ExpandedName(None, 'version') : None
4691 , pyxb.namespace.XML.createExpandedName('lang') : None
4692 }
4693
4698
4700 """Override the schema attributes with values from the given map."""
4701 self.__attributeMap.update(attr_map)
4702 return self
4703
4705 """Return True iff the schema has an attribute with the given (nc)name."""
4706 if isinstance(attr_name, basestring):
4707 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4708 return self.__attributeMap.has_key(attr_name)
4709
4711 """Return the schema attribute value associated with the given (nc)name.
4712
4713 @param attr_name: local name for the attribute in the schema element.
4714 @return: the value of the corresponding attribute, or C{None} if it
4715 has not been defined and has no default.
4716 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4717 """
4718 if isinstance(attr_name, basestring):
4719 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4720 return self.__attributeMap[attr_name]
4721
4722 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4723 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4724 'identityConstraintDefinition' )
4725
4728 __uriContentArchiveDirectory = None
4729
4771
4772 __TopLevelComponentMap = {
4773 'element' : ElementDeclaration,
4774 'attribute' : AttributeDeclaration,
4775 'notation' : NotationDeclaration,
4776 'simpleType' : SimpleTypeDefinition,
4777 'complexType' : ComplexTypeDefinition,
4778 'group' : ModelGroupDefinition,
4779 'attributeGroup' : AttributeGroupDefinition
4780 }
4781
4782 @classmethod
4787
4788 @classmethod
4790 """Create a schema from a schema location.
4791
4792 Reads an XML document from the schema location and creates a schema
4793 using it. All keyword parameters are passed to L{CreateFromDOM}.
4794
4795 @keyword schema_location: A file path or a URI. If this is a relative
4796 URI and C{parent_uri} is present, the actual location will be
4797 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4798 @keyword parent_uri: The context within which schema_location will be
4799 normalized, if necessary.
4800 @keyword absolute_schema_location: A file path or URI. This value is
4801 not normalized, and supersedes C{schema_location}.
4802 """
4803 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4804 kw['location_base'] = kw['schema_location'] = schema_location
4805 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4806 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4807 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4808
4809 @classmethod
4812
4813 @classmethod
4814 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4815 """Take the root element of the document, and scan its attributes under
4816 the assumption it is an XMLSchema schema element. That means
4817 recognize namespace declarations and process them. Also look for
4818 and set the default namespace. All other attributes are passed up
4819 to the parent class for storage."""
4820
4821
4822
4823 including_context = kw.get('including_context')
4824
4825 root_node = node
4826 if Node.DOCUMENT_NODE == node.nodeType:
4827 root_node = root_node.documentElement
4828 if Node.ELEMENT_NODE != root_node.nodeType:
4829 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4830
4831 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4832 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4833 parent_context=namespace_context,
4834 including_context=including_context)
4835
4836 tns = ns_ctx.targetNamespace()
4837 if tns is None:
4838 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4839 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4840 schema.__namespaceData = ns_ctx
4841
4842 if schema.targetNamespace() != ns_ctx.targetNamespace():
4843 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4844
4845
4846 for ai in range(root_node.attributes.length):
4847 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4848
4849
4850 if not xsd.nodeIsNamed(root_node, 'schema'):
4851 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4852
4853 for cn in root_node.childNodes:
4854 if Node.ELEMENT_NODE == cn.nodeType:
4855 rv = schema.__processTopLevelNode(cn)
4856 if rv is None:
4857 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4858 elif Node.TEXT_NODE == cn.nodeType:
4859
4860
4861 text = cn.data.strip()
4862 if text:
4863 _log.info('Ignored text: %s', text)
4864 elif Node.COMMENT_NODE == cn.nodeType:
4865 pass
4866 else:
4867
4868
4869
4870
4871
4872
4873
4874 _log.info('Ignoring non-element: %s', cn)
4875
4876
4877
4878
4879 return schema
4880
4881 _SA_All = '#all'
4882
4884 ebv = domutils.NodeAttribute(dom_node, attr)
4885 if ebv is None:
4886 ebv = self.schemaAttribute('%sDefault' % (attr,))
4887 rv = 0
4888 if ebv == self._SA_All:
4889 for v in candidate_map.values():
4890 rv += v
4891 else:
4892 for candidate in ebv.split():
4893 rv += candidate_map.get(candidate, 0)
4894 return rv
4895
4897 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4898
4899 A value of '#all' means enable every options; otherwise, the attribute
4900 value should be a list of tokens, for which the corresponding value
4901 will be added to the return value.
4902
4903 @param dom_node: the node from which the "block" attribute will be retrieved
4904 @type dom_node: C{xml.dom.Node}
4905 @param candidate_map: map from strings to bitmask values
4906 """
4907 return self.__ebvForNode('block', dom_node, candidate_map)
4908
4910 """Return a bit mask indicating a set of options read from the node's
4911 "final" attribute or the schema's "finalDefault" attribute.
4912
4913 A value of '#all' means enable every options; otherwise, the attribute
4914 value should be a list of tokens, for which the corresponding value
4915 will be added to the return value.
4916
4917 @param dom_node: the node from which the "final" attribute will be retrieved
4918 @type dom_node: C{xml.dom.Node}
4919 @param candidate_map: map from strings to bitmask values
4920 """
4921 return self.__ebvForNode('final', dom_node, candidate_map)
4922
4924 """Determine the target namespace for a local attribute or element declaration.
4925
4926 Look at the node's C{form} attribute, or if none the schema's
4927 C{attributeFormDefault} or C{elementFormDefault} value. If the
4928 resulting value is C{"qualified"} and the parent schema has a
4929 non-absent target namespace, return it to use as the declaration
4930 target namespace. Otherwise, return None to indicate that the
4931 declaration has no namespace.
4932
4933 @param dom_node: The node defining an element or attribute declaration
4934 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4935 @return: L{pyxb.namespace.Namespace} or None
4936 """
4937
4938 form_type = domutils.NodeAttribute(dom_node, 'form')
4939 if form_type is None:
4940 if declaration_type == ElementDeclaration:
4941 form_type = self.schemaAttribute('elementFormDefault')
4942 elif declaration_type == AttributeDeclaration:
4943 form_type = self.schemaAttribute('attributeFormDefault')
4944 else:
4945 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4946 tns = None
4947 if (self._QUALIFIED == form_type):
4948 tns = self.targetNamespace()
4949 if tns.isAbsentNamespace():
4950 tns = None
4951 else:
4952 if (self._UNQUALIFIED != form_type):
4953 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4954 return tns
4955
4957 """Throw a SchemaValidationException referencing the given
4958 node if we have passed the sequence point representing the end
4959 of prolog elements."""
4960
4961 if self.__pastProlog:
4962 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4963
4965 self.__requireInProlog(node.nodeName)
4966
4967 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
4968 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
4969 if not has_schema:
4970 kw = { 'absolute_schema_location': abs_uri,
4971 'including_context': self.__namespaceData,
4972 'generation_uid': self.generationUID(),
4973 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
4974 }
4975 try:
4976 schema_instance = self.CreateFromLocation(**kw)
4977 except pyxb.SchemaUniquenessError as e:
4978 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
4979 except Exception as e:
4980 _log.exception('INCLUDE %s caught', abs_uri)
4981 raise
4982 if schema_instance:
4983 if self.targetNamespace() != schema_instance.targetNamespace():
4984 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
4985 self.__includedSchema.add(schema_instance)
4986 return node
4987
5005
5009
5013
5037
5041
5043 tns = self.targetNamespace()
5044 assert tns is not None
5045 if not isinstance(nc, _NamedComponent_mixin):
5046 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
5047 if nc.isAnonymous():
5048 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
5049 if isinstance(nc, _ScopedDeclaration_mixin):
5050 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
5051 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5052 return self.__addTypeDefinition(nc)
5053 if isinstance(nc, AttributeDeclaration):
5054 return self.__addAttributeDeclaration(nc)
5055 if isinstance(nc, AttributeGroupDefinition):
5056 return self.__addAttributeGroupDefinition(nc)
5057 if isinstance(nc, ModelGroupDefinition):
5058 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5059 if isinstance(nc, ElementDeclaration):
5060 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5061 if isinstance(nc, NotationDeclaration):
5062 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5063 if isinstance(nc, IdentityConstraintDefinition):
5064 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5065 assert False, 'No support to record named component of type %s' % (nc.__class__,)
5066
5086
5103
5120
5122 return 'SCH[%s]' % (self.location(),)
5123
5126 """Add to the schema the definitions of the built-in types of XMLSchema.
5127 This should only be invoked by L{pyxb.namespace} when the built-in
5128 namespaces are initialized. """
5129
5130
5131 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5132 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5133 assert td.isResolved()
5134
5135 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5136 assert td.isResolved()
5137
5138 pts_std_map = {}
5139 for dtc in datatypes._PrimitiveDatatypes:
5140 name = dtc.__name__.rstrip('_')
5141 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5142 assert td.isResolved()
5143 assert dtc.SimpleTypeDefinition() == td
5144 pts_std_map.setdefault(dtc, td)
5145 for dtc in datatypes._DerivedDatatypes:
5146 name = dtc.__name__.rstrip('_')
5147 parent_std = pts_std_map[dtc.XsdSuperType()]
5148 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5149 assert td.isResolved()
5150 assert dtc.SimpleTypeDefinition() == td
5151 pts_std_map.setdefault(dtc, td)
5152 for dtc in datatypes._ListDatatypes:
5153 list_name = dtc.__name__.rstrip('_')
5154 element_name = dtc._ItemType.__name__.rstrip('_')
5155 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5156 assert element_std is not None
5157 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5158 assert td.isResolved()
5159 global _PastAddBuiltInTypes
5160 _PastAddBuiltInTypes = True
5161
5162 return schema
5163
5164 import sys
5165 import pyxb.namespace.builtin
5166 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5167
5168
5169
5170
5171