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