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: _PluralityData, _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 createas, 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 self.__namespaceContext = None
90 return self
91 __namespaceContext = None
92 __PrivateTransient.add('namespaceContext')
93
94
95
96
97
98 __nameInBinding = None
99
100
101
102 __owner = None
103 __PrivateTransient.add('owner')
104
105
106 __ownedComponents = None
107 __PrivateTransient.add('ownedComponent')
108
110 """The context into which declarations in or subordinate to this nodeare placed."""
111 return self.__scope
112 __scope = None
113
117
121
123 """Set the scope of this instance after construction.
124
125 This should only be invoked on cloned declarations being incorporated
126 into a complex type definition. Note that the source of the clone may
127 be any scope: indeterminate if from a model (attribute) group
128 definition; global if a reference to a global component; or ctd if
129 inherited from a complex base type."""
130 assert self.__cloneSource is not None
131 assert isinstance(self, _ScopedDeclaration_mixin)
132 assert isinstance(ctd, ComplexTypeDefinition)
133 self.__scope = ctd
134 return self
135
137 """Initialize portions of a component.
138
139 @keyword scope: The scope in which the component is defined
140
141 @keyword namespace_context: The NamespaceContext to use within this component
142
143 @keyword node: If no C{namespace_context} is provided, a DOM node must
144 be provided from which a namespace context can be identified.
145
146 @keyword owner: Reference to the component that owns this one (the
147 immediately enclosing component). Is C{None} in the case of top-level
148 components.
149
150 @keyword schema: Reference to the L{Schema} component to which the
151 component belongs. Required for every component except L{Schema},
152 L{Annotation}, and L{Wildcard}.
153 """
154
155 self.__ownedComponents = set()
156 self.__scope = kw.get('scope')
157 self.__namespaceContext = kw.get('namespace_context')
158 node = kw.get('node')
159 if self.__namespaceContext is None:
160 if node is None:
161 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node')
162 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
163 if self.__namespaceContext is None:
164 raise pyxb.LogicError('No namespace_context for schema component')
165
166 super(_SchemaComponent_mixin, self).__init__(*args, **kw)
167
168 if isinstance(node, pyxb.utils.utility.Locatable_mixin):
169 self._setLocation(node._location())
170
171 self._namespaceContext().targetNamespace()._associateComponent(self)
172
173 self._setOwner(kw.get('owner'))
174
175 schema = kw.get('schema')
176 if schema is not None:
177 self._setObjectOrigin(schema.originRecord())
178 else:
179 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),)
180
181 if isinstance(self, ComplexTypeDefinition):
182 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
183
184
186 """Dissociate this component from its owning namespace.
187
188 This should only be done whwen there are no other references to the
189 component, and you want to ensure it does not appear in the model."""
190 self._namespaceContext().targetNamespace()._replaceComponent(self, None)
191 return self
192
194 """Set the owner of this component.
195
196 If C{owner} is C{None}, this has no effect. Otherwise, the
197 component's current owner must be either C{None} or the same as the
198 input C{owner}."""
199
200 if owner is not None:
201 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner)
202 self.__owner = owner
203 owner.__ownedComponents.add(self)
204 return self
205
208
209
210 __cloneSource = None
211 __PrivateTransient.add('cloneSource')
212
214 """The source component from which this is a clone.
215
216 Returns C{None} if this is not a clone."""
217 return self.__cloneSource
218
219
220 __clones = None
221 __PrivateTransient.add('clones')
222
224 """The set of instances cloned from this component.
225
226 Returns None if no instances have been cloned from this."""
227 return self.__clones
228
255
256 - def _clone (self, owner, origin):
280
285
290
292 """Return the name of this component, as best it can be determined.
293
294 For example, ModelGroup instances will be named by their
295 ModelGroupDefinition, if available. Returns None if no name can be
296 inferred."""
297 if isinstance(self, _NamedComponent_mixin):
298 return self.name()
299 if isinstance(self, ModelGroup):
300 agd = self.modelGroupDefinition()
301 if agd is not None:
302 return agd.name()
303 return None
304
306 """Return the name by which this component is known in the generated
307 binding.
308
309 @note: To support builtin datatypes, type definitions with an
310 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class
311 initialize their binding name from the class name when the support
312 association is created. As long as no built-in datatype conflicts
313 with a language keyword, this should be fine."""
314 return self.__nameInBinding
315
317 """Return C{True} iff this is a component which has a user-visible
318 Python construct which serves as its binding.
319
320 Type definitions have classes as their bindings. Global element
321 declarations have instances of L{pyxb.binding.basis.element} as their
322 bindings."""
323 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
324
326 """Set the name by which this component shall be known in the XSD binding."""
327 self.__nameInBinding = name_in_binding
328 return self
329
331 """Override fields in this instance with those from the other.
332
333 Post-extended; description in leaf implementation in
334 ComplexTypeDefinition and SimpleTypeDefinition."""
335 assert self != other
336 self_fn = lambda *_args, **_kw: self
337 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', self_fn)(other)
338
339 if self.__nameInBinding is None:
340 self.__nameInBinding = other.__nameInBinding
341 return self
342
344 """This class is a mix-in which guarantees that only one instance
345 of the class will be created. It is used to ensure that the
346 ur-type instances are pointer-equivalent even when unpickling.
347 See ComplexTypeDefinition.UrTypeDefinition()."""
349 singleton_property = '_%s__singleton' % (cls.__name__,)
350 if not (singleton_property in cls.__dict__):
351 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
352 return cls.__dict__[singleton_property]
353
355 """Mix-in that supports an optional single annotation that describes the component.
356
357 Most schema components have annotations. The ones that don't are
358 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
359 and L{Schema} support multiple annotations, so do not mix-in this
360 class."""
361
362
363 __annotation = None
364
368
376
378 """Override fields in this instance with those from the other.
379
380 Post-extended; description in leaf implementation in
381 ComplexTypeDefinition and SimpleTypeDefinition."""
382 assert self != other
383 self_fn = lambda *_args, **_kw: self
384 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', self_fn)(other)
385
386 self.__annotation = other.__annotation
387 return self
388
391
393 """A helper that encapsulates a reference to an anonymous type in a different namespace.
394
395 Normally references to components in other namespaces can be made using
396 the component's name. This is not the case when a namespace derives from
397 a base type in another namespace and needs to reference the attribute or
398 element declarations held in that type. If these declarations are local
399 to the base complex type, they cannot be identified by name. This class
400 provides a pickleable representation for them that behaves rather like an
401 L{pyxb.namespace.ExpandedName} instance in that it can be used to
402 dereference various component types."""
403
404 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
405
406 __namespace = None
407 __anonymousName = None
408 - def __init__ (self, namespace, anonymous_name):
409 """Create a new anonymous reference.
410
411 @param namespace: The namespace in which the component is declared.
412 @type namespace: L{pyxb.namespace.Namespace}
413 @param anonymous_name: A generated name guaranteed to be unique within
414 the namespace. See L{_NamedComponent_mixin._anonymousName}.
415 @type anonymous_name: C{basestring}.
416 """
417 self.__namespace = namespace
418 self.__anonymousName = anonymous_name
419 assert self.__anonymousName is not None
420
421 @classmethod
423 """Return the component referred to by the provided reference,
424 regardless of whether it is a normal or anonymous reference."""
425 if not isinstance(object_reference, _PickledAnonymousReference):
426 assert isinstance(object_reference, tuple)
427 object_reference = pyxb.namespace.ExpandedName(object_reference)
428 return object_reference
429
432
435
439
442
443 typeDefinition = __lookupObject
444 attributeGroupDefinition = __lookupObject
445 modelGroupDefinition = __lookupObject
446 attributeDeclaration = __lookupObject
447 elementDeclaration = __lookupObject
448 identityConstraintDefinition = __lookupObject
449 notationDeclaration = __lookupObject
450
454
456 """Mix-in to hold the name and targetNamespace of a component.
457
458 The name may be None, indicating an anonymous component. The
459 targetNamespace is never None, though it could be an empty namespace. The
460 name and targetNamespace values are immutable after creation.
461
462 This class overrides the pickling behavior: when pickling a Namespace,
463 objects that do not belong to that namespace are pickled as references,
464 not as values. This ensures the uniqueness of objects when multiple
465 namespace definitions are pre-loaded.
466
467 This class must follow L{_SchemaComponent_mixin} in the MRO.
468 """
469
470 __PrivateTransient = set()
471
473 """Name of the component within its scope or namespace.
474
475 This is an NCName. The value isNone if the component is
476 anonymous. The attribute is immutable after the component is
477 created creation."""
478 return self.__name
479 __name = None
480
482 """Return true iff this instance is locally scoped (has no name)."""
483 return self.__name is None
484
509 __anonymousName = None
510
512 """The targetNamespace of a component.
513
514 This is None, or a reference to a Namespace in which the
515 component is declared (either as a global or local to one of
516 the namespace's complex type definitions). This is immutable
517 after creation.
518 """
519 return self.__targetNamespace
520 __targetNamespace = None
521
523 """The namespace in which this component's binding is placed."""
524 return self.__bindingNamespace
527 __bindingNamespace = None
528
530 """A map from template keys to component-specific values.
531
532 This is used in code generation to maintain unique names for accessor
533 methods, identifiers, keys, and other characteristics associated with
534 the code generated in support of the binding for this component."""
535 return self.__templateMap
536 __templateMap = None
537
538 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
539
545
547 """Return the schema component from which this component was defined.
548
549 Needed so we can distinguish components that came from different
550 locations, since that imposes an external order dependency on them and
551 on cross-namespace inclusions.
552
553 @note: This characteristic is removed when the component is stored in
554 a namespace archive."""
555 return self.__schema
556 __schema = None
557 __PrivateTransient.add('schema')
558
564
566 """Return C{True} if this component should be pickled by value in the
567 given namespace.
568
569 When pickling, a declaration component is considered to belong to the
570 namespace if it has a local scope which belongs to the namespace. In
571 that case, the declaration is a clone of something that does not
572 belong to the namespace; but the clone does.
573
574 @see: L{_bindsInNamespace}
575
576 @return: C{False} if the component should be pickled by reference.
577 """
578 if isinstance(self._scope(), ComplexTypeDefinition):
579 return self._scope()._picklesInArchive(archive)
580 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
581 assert not (self._objectOrigin() is None)
582 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
583 return new_flag
584
586 """Return C{True} if the binding for this component should be
587 generated in the given namespace.
588
589 This is the case when the component is in the given namespace. It's
590 also the case when the component has no associated namespace (but not
591 an absent namespace). Be aware that cross-namespace inheritance means
592 you will get references to elements in another namespace when
593 generating code for a subclass; that's fine, and those references
594 should not be generated locally.
595 """
596 return self.targetNamespace() in (ns, None)
597
603
605 """Pickling support.
606
607 Normally, we just create a new instance of this class.
608 However, if we're unpickling a reference in a loadable schema,
609 we need to return the existing component instance by looking
610 up the name in the component map of the desired namespace. We
611 can tell the difference because no normal constructors that
612 inherit from this have positional arguments; only invocations
613 by unpickling with a value returned in __getnewargs__ do.
614
615 This does require that the dependent namespace already have
616 been validated (or that it be validated here). That shouldn't
617 be a problem, except for the dependency loop resulting from
618 use of xml:lang in the XMLSchema namespace. For that issue,
619 see pyxb.namespace._XMLSchema.
620 """
621
622 if 0 == len(args):
623 rv = super(_NamedComponent_mixin, cls).__new__(cls)
624 return rv
625 ( object_reference, scope, icls ) = args
626
627 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
628
629
630
631 object_reference.validateComponentModel()
632 if isinstance(scope, (tuple, _PickledAnonymousReference)):
633
634
635 scope_ref = _PickledAnonymousReference.FromPickled(scope)
636 if object_reference.namespace() != scope_ref.namespace():
637 scope_ref.validateComponentModel()
638 assert 'typeDefinition' in scope_ref.namespace().categories()
639 scope_ctd = scope_ref.typeDefinition()
640 if scope_ctd is None:
641 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
642 if issubclass(icls, AttributeDeclaration):
643 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
644 elif issubclass(icls, ElementDeclaration):
645 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
646 else:
647 raise pyxb.IncompleteImplementationError('Scope %s reference lookup of %s not implemented for type %s' % (scope_ref, object_reference, icls))
648 if rv is None:
649 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
650 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
651 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
652 rv = object_reference.typeDefinition()
653 elif issubclass(icls, AttributeGroupDefinition):
654 rv = object_reference.attributeGroupDefinition()
655 elif issubclass(icls, ModelGroupDefinition):
656 rv = object_reference.modelGroupDefinition()
657 elif issubclass(icls, AttributeDeclaration):
658 rv = object_reference.attributeDeclaration()
659 elif issubclass(icls, ElementDeclaration):
660 rv = object_reference.elementDeclaration()
661 elif issubclass(icls, IdentityConstraintDefinition):
662 rv = object_reference.identityConstraintDefinition()
663 else:
664 raise pyxb.IncompleteImplementationError('Reference lookup of %s not implemented for type %s' % (object_reference, icls))
665 if rv is None:
666 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
667 else:
668 raise pyxb.IncompleteImplementationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, scope.targetNamespace(), type(scope), icls))
669 return rv
670
691
693 """Return true iff this and the other component share the same name and target namespace.
694
695 Anonymous components are inherently name inequivalent, except to
696 themselves. This relies on equivalence as defined for
697 pyxb.namespace.ExpandedName, for which None is not equivalent to any
698 non-anonymous name."""
699
700 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
701
703 """Return True iff this and the other component have matching types.
704
705 It appears that name equivalence is used; two complex type definitions
706 with identical structures are not considered equivalent (at least, per
707 XMLSpy).
708 """
709 return (type(self) == type(other)) and self.isNameEquivalent(other)
710
712 """Return True iff this type can serve as a restriction of the other
713 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
714
715 It appears that name equivalence is normally used; two complex type
716 definitions with identical structures are not considered equivalent
717 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
718 that derivation by restriction from the other type is also acceptable.
719 That opens a whole can of worms; see
720 L{ElementDeclaration.isAdaptable}.
721 """
722 this = self
723
724 while this is not None:
725 if this.isTypeEquivalent(other):
726 return True
727 if not (this.isResolved() and other.isResolved()):
728 raise pyxb.IncompleteImplementationError('Oh fudge. Somebody violated the assumptions in ElementDeclaration.isAdaptable.')
729 if isinstance(self, ComplexTypeDefinition):
730 if self.DM_restriction != this.derivationMethod():
731 return False
732 elif isinstance(self, SimpleTypeDefinition):
733 if self._DA_restriction != this._derivationAlternative():
734 return False
735 else:
736 raise pyxb.IncompleteImplementationError('Need derivation consistency check for type %s' % (type(this),))
737 this = this.baseTypeDefinition()
738 if this.isUrTypeDefinition():
739
740
741 break
742 return False
743
749
767
792
794 """Pickling support.
795
796 If this instance is being pickled as a reference, provide the
797 arguments that are necessary so that the unpickler can locate
798 the appropriate component rather than create a duplicate
799 instance."""
800
801 if self.__pickleAsReference():
802 scope = self._scope()
803 if isinstance(self, _ScopedDeclaration_mixin):
804
805
806
807
808
809 if self.SCOPE_global == self.scope():
810 pass
811 elif isinstance(self.scope(), ComplexTypeDefinition):
812 scope = self.scope()._picklingReference()
813 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
814 elif self._scopeIsIndeterminate():
815
816
817 pass
818 else:
819 raise pyxb.IncompleteImplementationError('pickling unrecognized scope %s type %s' % (self.scope(), type(self.scope())))
820 else:
821 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
822 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
823
824 rv = ( self._picklingReference(), scope, self.__class__ )
825 return rv
826 return ()
827
844
854
856 """Mix-in indicating that the component contains a simple-type
857 value that may be constrained."""
858
859 VC_na = 0
860 VC_default = 1
861 VC_fixed = 2
862
863
864
865 __valueConstraint = None
867 """A constraint on the value of the attribute or element.
868
869 Either None, or a pair consisting of a string in the lexical
870 space of the typeDefinition and one of VC_default and
871 VC_fixed."""
872 return self.__valueConstraint
873
882
891
903
905 """Mix-in class for named components that have a scope.
906
907 Scope is important when doing cross-namespace inheritance,
908 e.g. extending or restricting a complex type definition that is
909 from a different namespace. In this case, we will need to retain
910 a reference to the external component when the schema is
911 serialized.
912
913 This is done in the pickling process by including the scope when
914 pickling a component as a reference. The scope is the
915 SCOPE_global if global; otherwise, it is a tuple containing the
916 external namespace URI and the NCName of the complex type
917 definition in that namespace. We assume that the complex type
918 definition has global scope; otherwise, it should not have been
919 possible to extend or restrict it. (Should this be untrue, there
920 are comments in the code about a possible solution.)
921
922 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
923 """
924
925 SCOPE_global = 'global'
926 XSCOPE_indeterminate = 'indeterminate'
927
928 @classmethod
931
932 @classmethod
935
936 @classmethod
939
941 """Return True if this scope currently assigned to this instance is compatible with the given scope.
942
943 If either scope is indeterminate, presume they will ultimately be
944 compatible. Scopes that are equal are compatible, as is a local scope
945 if this already has a global scope."""
946 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
947 return True
948 if self.scope() == scope:
949 return True
950 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
951
952
953
954
956 """The scope for the declaration.
957
958 Valid values are SCOPE_global, or a complex type definition.
959 A value of None means a non-global declaration that is not
960 owned by a complex type definition. These can only appear in
961 attribute group definitions or model group definitions.
962
963 @todo: For declarations in named model groups (viz., local
964 elements that aren't references), the scope needs to be set by
965 the owning complex type.
966 """
967 return self._scope()
968
969
970
971
972
973 __baseDeclaration = None
979
981 """This class represents an abstraction of the set of documents conformant
982 to a particle or particle term.
983
984 The abstraction of a given document is a map from element declarations
985 that can appear at the top level of the document to a boolean that is true
986 iff there could be multiple instances of that element declaration at the
987 top level of a valid document. The abstraction of the set is a list of
988 document abstractions.
989
990 This information is used in binding generation to determine whether a
991 field associated with a tag might need to hold multiple instances.
992 """
993
994 @classmethod
996 """Given two maps, return an updated map indicating the unified
997 plurality."""
998 umap = { }
999 for k in set(map1.keys()).union(map2.keys()):
1000 if k in map1:
1001 umap[k] = (k in map2) or map1[k]
1002 else:
1003 umap[k] = map2[k]
1004 return umap
1005
1007 """Combine all the document abstractions into a single one that covers
1008 all possible documents.
1009
1010 The combined plurality is simply the elemental maximum over all
1011 document abstractions.
1012 """
1013
1014 combined_plurality = { }
1015 for pdm in self:
1016 for (ed, v) in pdm.items():
1017 if isinstance(ed, ElementDeclaration):
1018 assert ed.baseDeclaration() == ed
1019 combined_plurality[ed] = combined_plurality.get(ed, False) or v
1020 elif isinstance(ed, Wildcard):
1021 pass
1022 else:
1023 raise pyxb.LogicError('Unexpected plurality index %s' % (ed,))
1024 return combined_plurality
1025
1051
1052 - def __fromParticle (self, particle):
1053 assert particle.isResolved()
1054 pd = particle.term().pluralityData()
1055
1056
1057 if 0 == particle.maxOccurs():
1058 return
1059
1060
1061
1062 if 1 == particle.maxOccurs():
1063 self.__setFromComponent(particle.term())
1064 return
1065
1066
1067
1068
1069 true_map = {}
1070 pd = _PluralityData(particle.term())
1071 while 0 < len(pd):
1072 pdm = pd.pop()
1073 [ true_map.setdefault(_k, True) for _k in pdm.keys() ]
1074 self.append(true_map)
1075
1095
1099
1101 """Support for components that accept attribute wildcards.
1102
1103 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1104 calculations of the appropriate wildcard are sufficiently complex that
1105 they need to be abstracted out to a mix-in class."""
1106
1107
1108 __attributeWildcard = None
1109
1111 """Return the L{Wildcard} component associated with attributes of this
1112 instance, or C{None} if attribute wildcards are not present in the
1113 instance."""
1114 return self.__attributeWildcard
1115
1117 """Set the attribute wildcard property for this instance."""
1118 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1119 self.__attributeWildcard = attribute_wildcard
1120 return self
1121
1123 """Return the nodes that are relevant for attribute processing.
1124
1125 @param node_list: A sequence of nodes found in a definition content
1126 information item.
1127
1128 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1129 where C{attributes} is the subsequence of C{node_list} that are
1130 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1131 C{attributeWildcard} is a single DOM node with XMLSchema name
1132 C{anyAttribute} (or C{None}, if no such node is present in the list).
1133
1134 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1135 present but does not have the required C{ref} attribute.
1136 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1137 identified.
1138 """
1139
1140 attributes = []
1141 attribute_groups = []
1142 any_attribute = None
1143
1144 for node in node_list:
1145 if Node.ELEMENT_NODE != node.nodeType:
1146 continue
1147 if xsd.nodeIsNamed(node, 'attribute'):
1148
1149 attributes.append(node)
1150 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1151
1152 agd_attr = domutils.NodeAttribute(node, 'ref')
1153 if agd_attr is None:
1154 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1155 attribute_groups.append(agd_attr)
1156 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1157 if any_attribute is not None:
1158 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1159 any_attribute = node
1160
1161 return (attributes, attribute_groups, any_attribute)
1162
1163 @classmethod
1164 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1165 """Implement the algorithm as described the
1166 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1167
1168 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1169 associated with any created L{Wildcard} instance
1170 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1171 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1172 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1173 is relevant
1174 """
1175
1176
1177 agd_wildcards = []
1178 for agd in attribute_groups:
1179 assert isinstance(agd, AttributeGroupDefinition)
1180 if agd.attributeWildcard() is not None:
1181 agd_wildcards.append(agd.attributeWildcard())
1182 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1183
1184
1185 if 0 == len(agd_wildcards):
1186 return local_wildcard
1187
1188 if local_wildcard is not None:
1189
1190 return Wildcard(process_contents=local_wildcard.processContents(),
1191 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1192 annotation=local_wildcard.annotation(),
1193 namespace_context=namespace_context)
1194
1195 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1196 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1197 namespace_context=namespace_context)
1198
1199 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1200 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1201 """
1202
1203
1204 __typeDefinition = None
1206 """The simple type definition to which an attribute value must
1207 conform."""
1208 return self.__typeDefinition
1209
1210
1211 __typeAttribute = None
1212
1216
1221
1222 @classmethod
1235
1236
1237 @classmethod
1239 """Create an attribute declaration from the given DOM node.
1240
1241 wxs is a Schema instance within which the attribute is being
1242 declared.
1243
1244 node is a DOM element. The name must be one of ( 'all',
1245 'choice', 'sequence' ), and the node must be in the XMLSchema
1246 namespace.
1247
1248 scope is the _ScopeDeclaration_mxin context into which the
1249 attribute declaration is placed. It can be SCOPE_global, a
1250 complex type definition, or XSCOPE_indeterminate if this is an
1251 anonymous declaration within an attribute group. It is a
1252 required parameter for this function.
1253 """
1254
1255 scope = kw['scope']
1256 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1257
1258
1259 assert xsd.nodeIsNamed(node, 'attribute')
1260
1261 name = domutils.NodeAttribute(node, 'name')
1262
1263
1264 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1265 assert cls.SCOPE_global == scope
1266 elif domutils.NodeAttribute(node, 'ref') is None:
1267
1268 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1269 else:
1270 raise pyxb.SchemaValidationError('Internal attribute declaration by reference')
1271
1272 rv = cls(name=name, node=node, **kw)
1273 rv._annotationFromDOM(node)
1274 rv._valueConstraintFromDOM(node)
1275
1276 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1277
1278 kw.pop('node', None)
1279 kw['owner'] = rv
1280
1281 st_node = domutils.LocateUniqueChild(node, 'simpleType')
1282 if st_node is not None:
1283 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw)
1284 elif rv.__typeAttribute is None:
1285 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition()
1286
1287 if rv.__typeDefinition is None:
1288 rv._queueForResolution('creation')
1289 return rv
1290
1293
1294
1310
1312 """Override fields in this instance with those from the other.
1313
1314 This method is invoked only by Schema._addNamedComponent, and
1315 then only when a built-in type collides with a schema-defined
1316 type. Material like facets is not (currently) held in the
1317 built-in copy, so the DOM information is copied over to the
1318 built-in STD, which is subsequently re-resolved.
1319
1320 Returns self.
1321 """
1322 assert self != other
1323 assert self.name() is not None
1324 assert self.isNameEquivalent(other)
1325 super(AttributeDeclaration, self)._updateFromOther_csc(other)
1326
1327
1328
1329 if not other.isResolved():
1330 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID():
1331
1332 _log.warning('Not destroying builtin %s: %s', self.expandedName(), self.__typeDefinition)
1333 else:
1334 self.__typeDefinition = None
1335 return self
1336
1337
1339 """Attribute declarations require their type."""
1340 return frozenset([ self.__typeDefinition ])
1341
1342 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1343 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component."""
1344
1345
1346
1347 __use = None
1348
1349 USE_required = 0x01
1350 USE_optional = 0x02
1351 USE_prohibited = 0x04
1352
1355
1358
1359
1360 __refAttribute = None
1361
1362 __restrictionOf = None
1370
1371
1373 """The attribute declaration for this use.
1374
1375 When the use scope is assigned, the declaration is cloned (if
1376 necessary) so that each declaration corresponds to only one use. We
1377 rely on this in code generation, because the template map for the use
1378 is stored in its declaration."""
1379 return self.__attributeDeclaration
1380 __attributeDeclaration = None
1381
1382
1385
1400
1401 @classmethod
1410
1411
1412 @classmethod
1414 """Create an Attribute Use from the given DOM node.
1415
1416 wxs is a Schema instance within which the attribute use is
1417 being defined.
1418
1419 node is a DOM element. The name must be 'attribute', and the
1420 node must be in the XMLSchema namespace.
1421
1422 scope is the _ScopeDeclaration_mixin context into which any
1423 required anonymous attribute declaration is put. This must be
1424 a complex type definition, or None if this use is in an
1425 attribute group.
1426 """
1427
1428 scope = kw['scope']
1429 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1430 assert xsd.nodeIsNamed(node, 'attribute')
1431 schema = kw['schema']
1432 rv = cls(node=node, **kw)
1433
1434 rv.__use = cls.USE_optional
1435 use = domutils.NodeAttribute(node, 'use')
1436 if use is not None:
1437 if 'required' == use:
1438 rv.__use = cls.USE_required
1439 elif 'optional' == use:
1440 rv.__use = cls.USE_optional
1441 elif 'prohibited' == use:
1442 rv.__use = cls.USE_prohibited
1443 else:
1444 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1445
1446 rv._valueConstraintFromDOM(node)
1447
1448 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
1449 if rv.__refAttribute is None:
1450
1451 kw.pop('node', None)
1452 kw['owner'] = rv
1453 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1454 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1455
1456 if not rv.isResolved():
1457 rv._queueForResolution('creation')
1458
1459 return rv
1460
1463
1475
1476
1478 """Attribute uses require their declarations, but only if lax."""
1479 if not include_lax:
1480 return frozenset()
1481 return frozenset([ self.attributeDeclaration() ])
1482
1483
1503
1506
1507
1508 -class ElementDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1509 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1510
1511
1512 __typeDefinition = None
1514 """The simple or complex type to which the element value conforms."""
1515 return self.__typeDefinition
1519
1520 __substitutionGroupAttribute = None
1521
1522 __typeAttribute = None
1523
1524 __nillable = False
1527
1528 __identityConstraintDefinitions = None
1532
1533 __substitutionGroupAffiliation = None
1537
1538 SGE_none = 0
1539 SGE_extension = 0x01
1540 SGE_restriction = 0x02
1541 SGE_substitution = 0x04
1542
1543 _SGE_Map = { 'extension' : SGE_extension
1544 , 'restriction' : SGE_restriction }
1545 _DS_Map = _SGE_Map.copy()
1546 _DS_Map.update( { 'substitution' : SGE_substitution } )
1547
1548
1549 __substitutionGroupExclusions = SGE_none
1550
1551
1552 __disallowedSubstitutions = SGE_none
1553
1554 __abstract = False
1557
1559 """Return the plurality information for this component.
1560
1561 An ElementDeclaration produces one instance of a single element."""
1562 return _PluralityData(self)
1563
1565 """Return False, since element declarations are not wildcards."""
1566 return False
1567
1568
1570 """Element declarations depend on the type definition of their
1571 content."""
1572 return frozenset([self.__typeDefinition])
1573
1576
1577
1578 @classmethod
1580 """Create an element declaration from the given DOM node.
1581
1582 wxs is a Schema instance within which the element is being
1583 declared.
1584
1585 scope is the _ScopeDeclaration_mixin context into which the
1586 element declaration is recorded. It can be SCOPE_global, a
1587 complex type definition, or None in the case of elements
1588 declared in a named model group.
1589
1590 node is a DOM element. The name must be 'element', and the
1591 node must be in the XMLSchema namespace."""
1592
1593 scope = kw['scope']
1594 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1595
1596
1597 assert xsd.nodeIsNamed(node, 'element')
1598
1599
1600 name = domutils.NodeAttribute(node, 'name')
1601 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1602 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1603 elif domutils.NodeAttribute(node, 'ref') is None:
1604
1605 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1606 else:
1607 raise pyxb.SchemaValidationError('Created reference as element declaration')
1608
1609 rv = cls(name=name, node=node, **kw)
1610 rv._annotationFromDOM(node)
1611 rv._valueConstraintFromDOM(node)
1612
1613 rv.__substitutionGroupAttribute = domutils.NodeAttribute(node, 'substitutionGroup')
1614
1615 kw.pop('node', None)
1616 kw['owner'] = rv
1617
1618 identity_constraints = []
1619 for cn in node.childNodes:
1620 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1621 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1622 rv.__identityConstraintDefinitions = identity_constraints
1623
1624 rv.__typeDefinition = None
1625 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1626 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1627 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1628 if rv.__typeAttribute is not None:
1629 if (simpleType_node is not None) and (complexType_node is not None):
1630 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1631 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1632 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw)
1633 if (rv.__typeDefinition is None) and (complexType_node is not None):
1634 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw)
1635 if rv.__typeDefinition is None:
1636 if rv.__typeAttribute is None:
1637
1638 for cn in node.childNodes:
1639 if Particle.IsParticleNode(cn):
1640 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1641 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition()
1642 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1643 if not rv.__isResolved:
1644 rv._queueForResolution('creation')
1645
1646 attr_val = domutils.NodeAttribute(node, 'nillable')
1647 if attr_val is not None:
1648 rv.__nillable = datatypes.boolean(attr_val)
1649
1650 attr_val = domutils.NodeAttribute(node, 'abstract')
1651 if attr_val is not None:
1652 rv.__abstract = datatypes.boolean(attr_val)
1653
1654 schema = kw['schema']
1655 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1656 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1657
1658 return rv
1659
1661 """Determine whether this element declaration is adaptable.
1662
1663 OK, this gets ugly. First, if this declaration isn't resolved, it's
1664 clearly not adaptable.
1665
1666 Now: For it to be adaptable, we must know enough about its type to
1667 verify that it is derivation-consistent with any other uses of the
1668 same name in the same complex type. If the element's type is
1669 resolved, that's good enough.
1670
1671 If the element's type isn't resolved, we're golden as long as
1672 type-equivalent types were used. But it's also allowed for the
1673 derived ctd to use the element name constraining it to a derivation of
1674 the element base type. (Go see namespace
1675 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1676 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1677 have to have the element's type resolved.
1678
1679 Except that if a CTD's content incorporates an element with the same
1680 type as the CTD (i.e., nested), this will never happen, because the
1681 CTD can't get resolved until after it has been resolved.
1682 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1683 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1684 an example).
1685
1686 So, we give the world a break and assume that if the type we're trying
1687 to resolve is the same as the type of an element in that type, then
1688 the element type will be resolved by the point it's needed. In point
1689 of fact, it won't, but we'll only notice that if a CTD contains an
1690 element whose type is a restriction of the CTD. In that case,
1691 isDerivationConsistent will blow chunks and somebody'll have to come
1692 back and finish up this mess.
1693 """
1694
1695 if not self.isResolved():
1696 return False
1697 if self.typeDefinition().isResolved():
1698 return True
1699
1700
1701 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1702 if existing_decl is None:
1703
1704
1705 return True
1706
1707 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1708
1709 return True
1710
1711
1712 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1713 return False
1714
1715
1725
1726 __isResolved = False
1729
1730
1753
1758
1759
1760 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1761 __PrivateTransient = set()
1762
1763
1764 __baseTypeDefinition = None
1768
1769 DM_empty = 0
1770 DM_extension = 0x01
1771 DM_restriction = 0x02
1772
1773 _DM_Map = { 'extension' : DM_extension
1774 , 'restriction' : DM_restriction }
1775
1776
1777
1778 __derivationMethod = None
1782
1783
1784 __final = DM_empty
1785
1786
1787 __abstract = False
1790
1791
1792 __attributeUses = None
1794 """A frozenset() of AttributeUse instances."""
1795 return self.__attributeUses
1796
1797
1798
1799 __scopedAttributeDeclarations = None
1807
1808
1809
1810 __scopedElementDeclarations = None
1818
1819 __localScopedDeclarations = None
1821 """Return a list of element and attribute declarations that were
1822 introduced in this definition (i.e., their scope is this CTD).
1823
1824 @note: This specifically returns a list, with element declarations
1825 first, because name binding should privilege the elements over the
1826 attributes. Within elements and attributes, the components are sorted
1827 by expanded name, to ensure consistency across a series of binding
1828 generations.
1829
1830 @keyword reset: If C{False} (default), a cached previous value (if it
1831 exists) will be returned.
1832 """
1833 if reset or (self.__localScopedDeclarations is None):
1834 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1835 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1836 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1837 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1838 self.__localScopedDeclarations = rve
1839 self.__localScopedDeclarations.extend(rva)
1840 return self.__localScopedDeclarations
1841
1843 """Record the given declaration as being locally scoped in
1844 this type."""
1845 assert isinstance(decl, _ScopedDeclaration_mixin)
1846 if isinstance(decl, ElementDeclaration):
1847 scope_map = self.__scopedElementDeclarations
1848 elif isinstance(decl, AttributeDeclaration):
1849 scope_map = self.__scopedAttributeDeclarations
1850 else:
1851 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1852 decl_en = decl.expandedName()
1853 existing_decl = scope_map.setdefault(decl_en, decl)
1854 if decl != existing_decl:
1855 if isinstance(decl, ElementDeclaration):
1856
1857 existing_type = existing_decl.typeDefinition()
1858 pending_type = decl.typeDefinition()
1859 if not pending_type.isDerivationConsistent(existing_type):
1860 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1861 elif isinstance(decl, AttributeDeclaration):
1862 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1863 else:
1864 assert False, 'Unrecognized type %s' % (type(decl),)
1865 decl._baseDeclaration(existing_decl)
1866 return self
1867
1873
1874 CT_EMPTY = 'EMPTY'
1875 CT_SIMPLE = 'SIMPLE'
1876 CT_MIXED = 'MIXED'
1877 CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1878
1879 - def _contentTypeTag (self):
1880 """Return the value of the content type identifier, i.e. one of the
1881 CT_ constants. Return value is None if no content type has been
1882 defined."""
1883 if isinstance(self.__contentType, tuple):
1884 return self.__contentType[0]
1885 return self.__contentType
1886
1888 if isinstance(self.__contentType, tuple):
1889 return self.__contentType[1]
1890 return None
1891
1892
1893 __contentType = None
1894 - def contentType (self):
1895 """Identify the sort of content in this type.
1896
1897 Valid values are:
1898 - C{CT_EMPTY}
1899 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1900 - ( C{CT_MIXED}, a L{Particle} instance )
1901 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1902 """
1903 return self.__contentType
1904
1906 if self.CT_EMPTY == self.contentType():
1907 return 'EMPTY'
1908 ( tag, particle ) = self.contentType()
1909 if self.CT_SIMPLE == tag:
1910 return 'Simple [%s]' % (particle,)
1911 if self.CT_MIXED == tag:
1912 return 'Mixed [%s]' % (particle,)
1913 if self.CT_ELEMENT_ONLY == tag:
1914 return 'Element [%s]' % (particle,)
1915 raise pyxb.LogicError('Unhandled content type')
1916
1917
1918 __prohibitedSubstitutions = DM_empty
1919
1920
1921 __annotations = None
1922
1928
1938
1940 """Override fields in this instance with those from the other.
1941
1942 This method is invoked only by Schema._addNamedComponent, and
1943 then only when a built-in type collides with a schema-defined
1944 type. Material like facets is not (currently) held in the
1945 built-in copy, so the DOM information is copied over to the
1946 built-in STD, which is subsequently re-resolved.
1947
1948 Returns self.
1949 """
1950 assert self != other
1951 assert self.isNameEquivalent(other)
1952 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1953
1954 if not other.isResolved():
1955 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1956 self.__derivationMethod = None
1957
1958 return self
1959
1960 __UrTypeDefinition = None
1961 @classmethod
1963 """Create the ComplexTypeDefinition instance that approximates
1964 the ur-type.
1965
1966 See section 3.4.7.
1967 """
1968
1969
1970
1971
1972
1973
1974
1975 if cls.__UrTypeDefinition is None:
1976
1977 assert schema is not None
1978
1979 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1980
1981 kw = { 'name' : 'anyType',
1982 'schema' : schema,
1983 'namespace_context' : ns_ctx,
1984 'binding_namespace' : schema.targetNamespace(),
1985 'derivation_method' : cls.DM_restriction,
1986 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1987 bi = _UrTypeDefinition(**kw)
1988
1989
1990 bi.__baseTypeDefinition = bi
1991
1992
1993 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1994
1995
1996
1997
1998
1999
2000 kw = { 'namespace_context' : ns_ctx
2001 , 'schema' : schema
2002 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
2003 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
2004 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
2005 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
2006 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
2007
2008
2009 bi.__attributeUses = set()
2010
2011
2012 bi.__final = cls.DM_empty
2013 bi.__prohibitedSubstitutions = cls.DM_empty
2014
2015 bi.__abstract = False
2016
2017
2018 bi.setNameInBinding(bi.name())
2019
2020
2021 bi.__derivationMethod = cls.DM_restriction
2022
2023 cls.__UrTypeDefinition = bi
2024 return cls.__UrTypeDefinition
2025
2027 """Indicate whether this simple type is a built-in type."""
2028 return (self.UrTypeDefinition() == self)
2029
2030
2046
2047
2048 @classmethod
2072
2073 __baseAttribute = None
2074
2075
2076 __ckw = None
2077 __anyAttribute = None
2078 __attributeGroupAttributes = None
2079 __usesC1 = None
2080 __usesC1C2 = None
2081 __attributeGroups = None
2082 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2083
2084
2086
2087 if self.__usesC1C2 is None:
2088
2089 uses_c1 = self.__usesC1
2090 uses_c2 = set()
2091 self.__attributeGroups = []
2092 for ag_attr in self.__attributeGroupAttributes:
2093 ag_en = self._namespaceContext().interpretQName(ag_attr)
2094 agd = ag_en.attributeGroupDefinition()
2095 if agd is None:
2096 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2097 if not agd.isResolved():
2098 self._queueForResolution('unresolved attribute group', depends_on=agd)
2099 return self
2100 self.__attributeGroups.append(agd)
2101 uses_c2.update(agd.attributeUses())
2102
2103 uses_c1c2 = uses_c1.union(uses_c2)
2104 for au in uses_c1c2:
2105 if not au.isResolved():
2106 self._queueForResolution('attribute use not resolved')
2107 return self
2108 ad = au.attributeDeclaration()
2109 if not ad.isResolved():
2110 ad_en = ad.expandedName()
2111 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2112 return self
2113
2114 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2115
2116
2117
2118
2119
2120
2121 uses_c3 = set()
2122 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2123
2124
2125 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2126 assert self.__baseTypeDefinition.isResolved()
2127 for au in uses_c3:
2128 if not au.isResolved():
2129 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2130 return self
2131 ad = au.attributeDeclaration()
2132 if not ad.isResolved():
2133 ad_en = ad.expandedName()
2134 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2135 return self
2136 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2137
2138 if self.DM_restriction == method:
2139
2140
2141
2142 for au in self.__usesC1C2:
2143 matching_uses = au.matchingQNameMembers(uses_c3)
2144 assert matching_uses is not None
2145 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2146 for au2 in matching_uses:
2147 assert au2.isResolved()
2148 uses_c3.remove(au2)
2149 au._setRestrictionOf(au2)
2150 else:
2151
2152
2153
2154 assert self.DM_extension == method
2155
2156 use_map = { }
2157 for au in self.__usesC1C2.union(uses_c3):
2158 assert au.isResolved()
2159 ad_en = au.attributeDeclaration().expandedName()
2160 if ad_en in use_map:
2161 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2162 use_map[ad_en] = au
2163
2164
2165
2166 self.__attributeUses = frozenset(use_map.values())
2167 if not self._scopeIsIndeterminate():
2168 for au in self.__attributeUses:
2169 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2170
2171
2172
2173 local_wildcard = None
2174 if self.__anyAttribute is not None:
2175 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2176
2177
2178 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2179
2180
2181 if self.DM_restriction == method:
2182
2183 self._setAttributeWildcard(complete_wildcard)
2184 else:
2185 assert (self.DM_extension == method)
2186 assert self.baseTypeDefinition().isResolved()
2187
2188 base_wildcard = None
2189 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2190 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2191
2192 if base_wildcard is not None:
2193 if complete_wildcard is None:
2194
2195 self._setAttributeWildcard(base_wildcard)
2196 else:
2197
2198 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2199 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2200 base_wildcard.namespaceConstraint()]),
2201 annotation=complete_wildcard.annotation(),
2202 namespace_context=self._namespaceContext()))
2203 else:
2204
2205 self._setAttributeWildcard(complete_wildcard)
2206
2207
2208
2209
2210 del self.__usesC1
2211 del self.__usesC1C2
2212 del self.__attributeGroups
2213 self.__ckw = None
2214
2215
2216
2217
2218 self.__derivationMethod = method
2219 return self
2220
2221 - def __simpleContent (self, method, **kw):
2222
2223 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2224
2225 parent_content_type = self.__baseTypeDefinition.__contentType
2226 if ((type(parent_content_type) == tuple) \
2227 and (self.CT_SIMPLE == parent_content_type[0]) \
2228 and (self.DM_restriction == method)):
2229
2230 assert self.__ctscRestrictionNode is not None
2231 std = self.__ctscClause2STD
2232 if std is None:
2233 std = parent_content_type[1]
2234 assert isinstance(std, SimpleTypeDefinition)
2235 if not std.isResolved():
2236 return None
2237 restriction_node = self.__ctscRestrictionNode
2238 self.__ctscClause2STD = None
2239 self.__ctscRestrictionNode = None
2240 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2241 if ((type(parent_content_type) == tuple) \
2242 and (self.CT_MIXED == parent_content_type[0]) \
2243 and parent_content_type[1].isEmptiable()):
2244
2245 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2246 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2247
2248 return parent_content_type
2249
2250 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2251
2252 __ctscClause2STD = None
2253 __ctscRestrictionNode = None
2254 __effectiveMixed = None
2255 __effectiveContent = None
2256 __pendingDerivationMethod = None
2257 __isComplexContent = None
2258 __ctscRestrictionMode = None
2259 __contentStyle = None
2260
2261 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2262
2263
2264 ckw = kw.copy()
2265 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2266
2267
2268 mixed_attr = None
2269 if content_node is not None:
2270 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2271 if mixed_attr is None:
2272 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2273 if mixed_attr is not None:
2274 effective_mixed = datatypes.boolean(mixed_attr)
2275 else:
2276 effective_mixed = False
2277
2278
2279 test_2_1_1 = True
2280 test_2_1_2 = False
2281 test_2_1_3 = False
2282 typedef_node = None
2283 for cn in definition_node_list:
2284 if Node.ELEMENT_NODE != cn.nodeType:
2285 continue
2286 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2287
2288 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2289 if Particle.IsTypedefNode(cn):
2290 typedef_node = cn
2291 test_2_1_1 = False
2292 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2293 and (not domutils.HasNonAnnotationChild(cn)):
2294 test_2_1_2 = True
2295 if xsd.nodeIsNamed(cn, 'choice') \
2296 and (not domutils.HasNonAnnotationChild(cn)):
2297 mo_attr = domutils.NodeAttribute(cn, 'minOccurs')
2298 if ((mo_attr is not None) \
2299 and (0 == datatypes.integer(mo_attr))):
2300 test_2_1_3 = True
2301 satisfied_predicates = 0
2302 if test_2_1_1:
2303 satisfied_predicates += 1
2304 if test_2_1_2:
2305 satisfied_predicates += 1
2306 if test_2_1_3:
2307 satisfied_predicates += 1
2308 if 1 == satisfied_predicates:
2309 if effective_mixed:
2310
2311 assert (typedef_node is None) or test_2_1_2
2312 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2313 effective_content = Particle(m, **ckw)
2314 else:
2315
2316 effective_content = self.CT_EMPTY
2317 else:
2318
2319 assert typedef_node is not None
2320 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2321
2322
2323
2324
2325
2326
2327
2328 self.__effectiveMixed = effective_mixed
2329 self.__effectiveContent = effective_content
2330 self.__ckw = ckw
2331
2332 - def __complexContent (self, method):
2333 ckw = self.__ckw
2334
2335
2336 if self.__effectiveMixed:
2337 ct = self.CT_MIXED
2338 else:
2339 ct = self.CT_ELEMENT_ONLY
2340
2341 if self.DM_restriction == method:
2342
2343 if self.CT_EMPTY == self.__effectiveContent:
2344
2345 content_type = self.CT_EMPTY
2346 else:
2347
2348 content_type = ( ct, self.__effectiveContent )
2349 assert 0 == len(self.__scopedElementDeclarations)
2350
2351
2352
2353
2354 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2355 else:
2356
2357 assert self.DM_extension == method
2358 assert self.__baseTypeDefinition.isResolved()
2359 parent_content_type = self.__baseTypeDefinition.contentType()
2360 if self.CT_EMPTY == self.__effectiveContent:
2361 content_type = parent_content_type
2362 elif self.CT_EMPTY == parent_content_type:
2363
2364 content_type = ( ct, self.__effectiveContent )
2365 else:
2366 assert type(parent_content_type) == tuple
2367 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2368 content_type = ( ct, Particle(m, **ckw) )
2369
2370 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2371 return content_type
2372
2374 """Indicate whether this complex type is fully defined.
2375
2376 All built-in type definitions are resolved upon creation.
2377 Schema-defined type definitionss are held unresolved until the
2378 schema has been completely read, so that references to later
2379 schema-defined types can be resolved. Resolution is performed
2380 after the entire schema has been scanned and type-definition
2381 instances created for all topLevel{Simple,Complex}Types.
2382
2383 If a built-in type definition is also defined in a schema
2384 (which it should be), the built-in definition is kept, with
2385 the schema-related information copied over from the matching
2386 schema-defined type definition. The former then replaces the
2387 latter in the list of type definitions to be resolved. See
2388 Schema._addNamedComponent.
2389 """
2390
2391 return (self.__derivationMethod is not None)
2392
2393
2394
2398
2399 - def __setContentFromDOM (self, node, **kw):
2400 schema = kw.get('schema')
2401 assert schema is not None
2402 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2403 self.__final = schema.finalForNode(node, self._DM_Map)
2404
2405 attr_val = domutils.NodeAttribute(node, 'abstract')
2406 if attr_val is not None:
2407 self.__abstract = datatypes.boolean(attr_val)
2408
2409
2410
2411 definition_node_list = node.childNodes
2412 is_complex_content = True
2413 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2414 method = self.DM_restriction
2415
2416
2417
2418
2419 first_elt = domutils.LocateFirstChildElement(node)
2420 content_node = None
2421 clause2_std = None
2422 ctsc_restriction_node = None
2423 if first_elt:
2424 have_content = False
2425 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2426 have_content = True
2427 is_complex_content = False
2428 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2429 have_content = True
2430 else:
2431
2432
2433 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2434 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2435 if have_content:
2436
2437 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2438 assert content_node == first_elt
2439
2440
2441
2442 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2443 if xsd.nodeIsNamed(ions, 'restriction'):
2444 method = self.DM_restriction
2445 if not is_complex_content:
2446
2447 ctsc_restriction_node = ions
2448 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2449 if ions_st is not None:
2450 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2451 elif xsd.nodeIsNamed(ions, 'extension'):
2452 method = self.DM_extension
2453 else:
2454 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2455 self.__baseAttribute = domutils.NodeAttribute(ions, 'base')
2456 if self.__baseAttribute is None:
2457 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2458 self.__baseTypeDefinition = None
2459
2460 definition_node_list = ions.childNodes
2461
2462 self.__pendingDerivationMethod = method
2463 self.__isComplexContent = is_complex_content
2464 self.__ctscRestrictionNode = ctsc_restriction_node
2465 self.__ctscClause2STD = clause2_std
2466
2467 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2468 self.__usesC1 = set()
2469 for cn in attributes:
2470 au = AttributeUse.CreateFromDOM(cn, **kw)
2471 self.__usesC1.add(au)
2472 self.__attributeGroupAttributes = attribute_group_attrs
2473 self.__anyAttribute = any_attribute
2474
2475 if self.__isComplexContent:
2476 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2477
2478
2479
2480 self._annotationFromDOM(node)
2481
2482 if not self.isResolved():
2483 self._queueForResolution('creation')
2484
2485 return self
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2551
2553 """Complex type definitions have no built-in type support."""
2554 return None
2555
2560
2562 """Subclass ensures there is only one ur-type."""
2564 """The ur-type does have a Python class backing it up."""
2565 return datatypes.anyType
2566
2571
2572
2573 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2684
2686 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2687
2688 __modelGroup = None
2689
2691 """The model group for which this definition provides a name."""
2692 return self.__modelGroup
2693
2694
2695 @classmethod
2697 """Create a Model Group Definition from a DOM element node.
2698
2699 wxs is a Schema instance within which the model group is being
2700 defined.
2701
2702 node is a DOM element. The name must be 'group', and the node
2703 must be in the XMLSchema namespace. The node must have a
2704 'name' attribute, and must not have a 'ref' attribute.
2705 """
2706 assert xsd.nodeIsNamed(node, 'group')
2707
2708 assert domutils.NodeAttribute(node, 'ref') is None
2709
2710 name = domutils.NodeAttribute(node, 'name')
2711 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2712 rv = cls(name=name, node=node, **kw)
2713 rv._annotationFromDOM(node)
2714
2715 kw.pop('node', None)
2716 kw['owner'] = rv
2717
2718 for cn in node.childNodes:
2719 if Node.ELEMENT_NODE != cn.nodeType:
2720 continue
2721 if ModelGroup.IsGroupMemberNode(cn):
2722 assert not rv.__modelGroup
2723
2724
2725
2726 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2727 assert rv.__modelGroup is not None
2728 return rv
2729
2730
2732 """Model group definitions depend on the contained model group."""
2733 if not include_lax:
2734 return frozenset()
2735 return frozenset([self.__modelGroup])
2736
2739
2740
2741 -class ModelGroup (_SchemaComponent_mixin, _Annotated_mixin):
2742 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2743 C_INVALID = 0
2744 C_ALL = 0x01
2745 C_CHOICE = 0x02
2746 C_SEQUENCE = 0x03
2747
2748
2749
2750 __compositor = C_INVALID
2753
2754 @classmethod
2764
2768
2769
2770
2771 __particles = None
2772 - def particles (self):
2773 return self.__particles
2774
2776 """A model group has an unresolvable particle if any of its
2777 particles is unresolvable. Duh."""
2778 for p in self.particles():
2779 if not p.isAdaptable(ctd):
2780 return False
2781 return True
2782
2784 """Return the minimum and maximum of the number of elements that can
2785 appear in a sequence matched by this particle.
2786
2787 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2788 """
2789 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2790 sum_minoccurs = 0
2791 sum_maxoccurs = 0
2792 for prt in self.__particles:
2793 (prt_min, prt_max) = prt.effectiveTotalRange()
2794 sum_minoccurs += prt_min
2795 if sum_maxoccurs is not None:
2796 if prt_max is None:
2797 sum_maxoccurs = None
2798 else:
2799 sum_maxoccurs += prt_max
2800 prod_maxoccurs = particle.maxOccurs()
2801 if prod_maxoccurs is not None:
2802 if sum_maxoccurs is None:
2803 prod_maxoccurs = None
2804 else:
2805 prod_maxoccurs *= sum_maxoccurs
2806 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2807 assert self.__compositor == self.C_CHOICE
2808 if 0 == len(self.__particles):
2809 min_minoccurs = 0
2810 max_maxoccurs = 0
2811 else:
2812 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2813 for prt in self.__particles[1:]:
2814 (prt_min, prt_max) = prt.effectiveTotalRange()
2815 if prt_min < min_minoccurs:
2816 min_minoccurs = prt_min
2817 if prt_max is None:
2818 max_maxoccurs = None
2819 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2820 max_maxoccurs = prt_max
2821 min_minoccurs *= particle.minOccurs()
2822 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2823 max_maxoccurs *= particle.maxOccurs()
2824 return (min_minoccurs, max_maxoccurs)
2825
2826
2827
2828
2829 __modelGroupDefinition = None
2831 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2832 return self.__modelGroupDefinition
2833
2834 - def __init__ (self, compositor, particles, *args, **kw):
2835 """Create a new model group.
2836
2837 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2838
2839 particles must be a list of zero or more Particle instances.
2840
2841 scope is the _ScopeDeclaration_mixin context into which new
2842 declarations are recorded. It can be SCOPE_global, a complex
2843 type definition, or None if this is (or is within) a named
2844 model group.
2845
2846 model_group_definition is an instance of ModelGroupDefinition
2847 if this is a named model group. It defaults to None
2848 indicating a local group.
2849 """
2850
2851 super(ModelGroup, self).__init__(*args, **kw)
2852 assert 'scope' in kw
2853 self.__compositor = compositor
2854 self.__particles = particles
2855 self.__modelGroupDefinition = kw.get('model_group_definition')
2856
2858 """Get the plurality data for this model group.
2859 """
2860 return _PluralityData(self)
2861
2863 """Return True if the model includes a wildcard amongst its particles."""
2864 for p in self.particles():
2865 if p.hasWildcardElement():
2866 return True
2867 return False
2868
2869
2871 if not include_lax:
2872 return frozenset()
2873 return frozenset(self.__particles)
2874
2875
2876 @classmethod
2878 """Create a model group from the given DOM node.
2879
2880 wxs is a Schema instance within which the model group is being
2881 defined.
2882
2883 node is a DOM element. The name must be one of ( 'all',
2884 'choice', 'sequence' ), and the node must be in the XMLSchema
2885 namespace.
2886
2887 scope is the _ScopeDeclaration_mxin context that is assigned
2888 to declarations that appear within the model group. It can be
2889 None, indicating no scope defined, or a complex type
2890 definition.
2891 """
2892
2893 scope = kw['scope']
2894 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2895
2896 if xsd.nodeIsNamed(node, 'all'):
2897 compositor = cls.C_ALL
2898 elif xsd.nodeIsNamed(node, 'choice'):
2899 compositor = cls.C_CHOICE
2900 elif xsd.nodeIsNamed(node, 'sequence'):
2901 compositor = cls.C_SEQUENCE
2902 else:
2903 raise pyxb.IncompleteImplementationError('ModelGroup: Got unexpected %s' % (node.nodeName,))
2904 particles = []
2905
2906 kw.pop('owner', None)
2907 for cn in node.childNodes:
2908 if Node.ELEMENT_NODE != cn.nodeType:
2909 continue
2910 if Particle.IsParticleNode(cn):
2911
2912 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2913 elif not xsd.nodeIsNamed(cn, 'annotation'):
2914 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2915 rv = cls(compositor, particles, node=node, **kw)
2916 for p in particles:
2917 p._setOwner(rv)
2918 rv._annotationFromDOM(node)
2919 return rv
2920
2921 @classmethod
2923 return xsd.nodeIsNamed(node, 'all', 'choice', 'sequence')
2924
2926 """Return a list of all ElementDeclarations that are at the
2927 top level of this model group, in the order in which they can
2928 occur."""
2929 element_decls = []
2930 model_groups = [ self ]
2931 while model_groups:
2932 mg = model_groups.pop(0)
2933 for p in mg.particles():
2934 if isinstance(p.term(), ModelGroup):
2935 model_groups.append(p.term())
2936 elif isinstance(p.term(), ElementDeclaration):
2937 element_decls.extend(p.elementDeclarations())
2938 else:
2939 assert p.term() is not None
2940 return element_decls
2941
2942
2953
2963
2964 -class Particle (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2965 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2966
2967
2968 __minOccurs = 1
2969 - def minOccurs (self):
2970 """The minimum number of times the term may appear.
2971
2972 Defaults to 1."""
2973 return self.__minOccurs
2974
2975
2976 __maxOccurs = 1
2977 - def maxOccurs (self):
2978 """Upper limit on number of times the term may appear.
2979
2980 If None, the term may appear any number of times; otherwise,
2981 this is an integral value indicating the maximum number of times
2982 the term may appear. The default value is 1; the value, unless
2983 None, must always be at least minOccurs().
2984 """
2985 return self.__maxOccurs
2986
2987
2988 __term = None
2990 """A reference to a ModelGroup, Wildcard, or ElementDeclaration."""
2991 return self.__term
2992 __pendingTerm = None
2993
2994 __refAttribute = None
2995 __resolvableType = None
2996
2998 assert self.__term is not None
2999 if isinstance(self.__term, ModelGroup):
3000 return self.__term.elementDeclarations()
3001 if isinstance(self.__term, ElementDeclaration):
3002 return [ self.__term ]
3003 if isinstance(self.__term, Wildcard):
3004 return [ ]
3005 raise pyxb.LogicError('Unexpected term type %s' % (self.__term,))
3006
3007 - def pluralityData (self):
3008 """Return the plurality data for this component.
3009
3010 The plurality data for a particle is the plurality data for
3011 its term, with the counts scaled by the effect of
3012 maxOccurs."""
3013 return _PluralityData(self)
3014
3016 """Extend the concept of effective total range to all particles.
3017
3018 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
3019 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
3020 """
3021 if isinstance(self.__term, ModelGroup):
3022 return self.__term.effectiveTotalRange(self)
3023 return (self.minOccurs(), self.maxOccurs())
3024
3025 - def isEmptiable (self):
3026 """Return C{True} iff this particle can legitimately match an empty
3027 sequence (no content).
3028
3029 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
3030 """
3031 return 0 == self.effectiveTotalRange()[0]
3032
3034 """Return True iff this particle has a wildcard in its term.
3035
3036 Note that the wildcard may be in a nested model group."""
3037 return self.term().hasWildcardElement()
3038
3039 - def __init__ (self, term, *args, **kw):
3040 """Create a particle from the given DOM node.
3041
3042 term is a XML Schema Component: one of ModelGroup,
3043 ElementDeclaration, and Wildcard.
3044
3045 The following keyword arguments are processed:
3046
3047 min_occurs is a non-negative integer value with default 1,
3048 denoting the minimum number of terms required by the content
3049 model.
3050
3051 max_occurs is a positive integer value with default 1, or None
3052 indicating unbounded, denoting the maximum number of terms
3053 allowed by the content model.
3054
3055 scope is the _ScopeDeclaration_mxin context that is assigned
3056 to declarations that appear within the particle. It can be
3057 None, indicating no scope defined, or a complex type
3058 definition.
3059 """
3060
3061 super(Particle, self).__init__(*args, **kw)
3062
3063 min_occurs = kw.get('min_occurs', 1)
3064 max_occurs = kw.get('max_occurs', 1)
3065
3066 assert 'scope' in kw
3067 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
3068
3069 if term is not None:
3070 self.__term = term
3071
3072 assert isinstance(min_occurs, (types.IntType, types.LongType))
3073 self.__minOccurs = min_occurs
3074 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
3075 self.__maxOccurs = max_occurs
3076 if self.__maxOccurs is not None:
3077 if self.__minOccurs > self.__maxOccurs:
3078 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3079
3080
3081 - def _resolve (self):
3082 if self.isResolved():
3083 return self
3084
3085
3086 if ModelGroup == self.__resolvableType:
3087 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3088 group_decl = ref_en.modelGroupDefinition()
3089 if group_decl is None:
3090 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
3091
3092 self.__pendingTerm = group_decl.modelGroup()
3093 assert self.__pendingTerm is not None
3094 elif ElementDeclaration == self.__resolvableType:
3095
3096
3097
3098 if self.__refAttribute is not None:
3099 assert self.__pendingTerm is None
3100 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3101 self.__pendingTerm = ref_en.elementDeclaration()
3102 if self.__pendingTerm is None:
3103 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3104 assert self.__pendingTerm is not None
3105
3106
3107
3108
3109 assert self.__pendingTerm is not None
3110 else:
3111 assert False
3112
3113 self.__term = self.__pendingTerm
3114 assert self.__term is not None
3115 return self
3116
3117 - def isResolved (self):
3118 return self.__term is not None
3119
3120
3121 @classmethod
3122 - def CreateFromDOM (cls, node, **kw):
3123 """Create a particle from the given DOM node.
3124
3125 wxs is a Schema instance within which the model group is being
3126 defined.
3127
3128 node is a DOM element. The name must be one of ( 'group',
3129 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3130 must be in the XMLSchema namespace.
3131
3132 scope is the _ScopeDeclaration_mxin context that is assigned
3133 to declarations that appear within the model group. It can be
3134 None, indicating no scope defined, or a complex type
3135 definition.
3136 """
3137 scope = kw['scope']
3138 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3139
3140 kw.update({ 'min_occurs' : 1
3141 , 'max_occurs' : 1
3142 , 'node' : node })
3143
3144 if not Particle.IsParticleNode(node):
3145 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3146 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3147 if attr_val is not None:
3148 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3149 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3150 if attr_val is not None:
3151 if 'unbounded' == attr_val:
3152 kw['max_occurs'] = None
3153 else:
3154 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3155
3156 rv = cls(None, **kw)
3157
3158 kw.pop('node', None)
3159 kw['owner'] = rv
3160
3161 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
3162 rv.__pendingTerm = None
3163 rv.__resolvableType = None
3164 if xsd.nodeIsNamed(node, 'group'):
3165
3166
3167
3168 if rv.__refAttribute is None:
3169 raise pyxb.SchemaValidationError('group particle without reference')
3170 rv.__resolvableType = ModelGroup
3171 elif xsd.nodeIsNamed(node, 'element'):
3172 if rv.__refAttribute is None:
3173 schema = kw.get('schema')
3174 assert schema is not None
3175 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3176 incoming_tns = kw.get('target_namespace')
3177 if incoming_tns is not None:
3178 assert incoming_tns == target_namespace
3179 else:
3180 kw['target_namespace'] = target_namespace
3181 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3182 else:
3183
3184
3185
3186 rv.__resolvableType = ElementDeclaration
3187 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3188 elif xsd.nodeIsNamed(node, 'any'):
3189
3190 rv.__term = Wildcard.CreateFromDOM(node=node)
3191 elif ModelGroup.IsGroupMemberNode(node):
3192
3193
3194
3195 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3196 else:
3197 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3198
3199 if not rv.isResolved():
3200 rv._queueForResolution('creation')
3201 return rv
3202
3203
3204 - def _bindingRequires_vx (self, include_lax):
3205 if not include_lax:
3206 return frozenset()
3207 return frozenset([ self.__term ])
3208
3209
3210 - def _adaptForScope (self, owner, ctd):
3211 rv = self
3212 assert isinstance(ctd, ComplexTypeDefinition)
3213 maybe_rv = self._clone(owner, ctd._objectOrigin())
3214 term = rv.__term._adaptForScope(maybe_rv, ctd)
3215 do_clone = (self._scope() != ctd) or (rv.__term != term)
3216 if do_clone:
3217 rv = maybe_rv
3218 rv.__term = term
3219 return rv
3220
3221 - def isAdaptable (self, ctd):
3222 """A particle has an unresolvable particle if it cannot be
3223 resolved, or if it has resolved to a term which is a model
3224 group that has an unresolvable particle.
3225 """
3226 if not self.isResolved():
3227 return False
3228 return self.term().isAdaptable(ctd)
3229
3230 @classmethod
3231 - def IsTypedefNode (cls, node):
3232 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3233
3234 @classmethod
3235 - def IsParticleNode (cls, node, *others):
3236 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3237
3238 - def __str__ (self):
3239
3240 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3241
3242
3243
3244 -class Wildcard (_SchemaComponent_mixin, _Annotated_mixin):
3245 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3246
3247 NC_any = '##any'
3248 NC_not = '##other'
3249 NC_targetNamespace = '##targetNamespace'
3250 NC_local = '##local'
3251
3252 __namespaceConstraint = None
3254 """A constraint on the namespace for the wildcard.
3255
3256 Valid values are:
3257 - L{Wildcard.NC_any}
3258 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3259 - set(of_namespaces)
3260
3261 Note that namespace are represented by
3262 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3263 actually define a namespace. Absence of a namespace is represented by
3264 C{None}, both in the "not" pair and in the set.
3265 """
3266 return self.__namespaceConstraint
3267
3268 @classmethod
3270 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3271 assert 0 < len(constraints)
3272 o1 = constraints.pop(0)
3273 while 0 < len(constraints):
3274 o2 = constraints.pop(0)
3275
3276 if (o1 == o2):
3277 continue
3278
3279 if (cls.NC_any == o1) or (cls.NC_any == o2):
3280 o1 = cls.NC_any
3281 continue
3282
3283 if isinstance(o1, set) and isinstance(o2, set):
3284 o1 = o1.union(o2)
3285 continue
3286
3287 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3288 o1 = ( cls.NC_not, None )
3289 continue
3290
3291
3292 c_tuple = None
3293 c_set = None
3294 if isinstance(o1, tuple):
3295 assert isinstance(o2, set)
3296 c_tuple = o1
3297 c_set = o2
3298 else:
3299 assert isinstance(o1, set)
3300 assert isinstance(o2, tuple)
3301 c_tuple = o2
3302 c_set = o1
3303 negated_ns = c_tuple[1]
3304 if negated_ns is not None:
3305
3306 if (negated_ns in c_set) and (None in c_set):
3307 o1 = cls.NC_any
3308 continue
3309
3310 if negated_ns in c_set:
3311 o1 = ( cls.NC_not, None )
3312 continue
3313
3314 if None in c_set:
3315 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3316 o1 = c_tuple
3317 continue
3318
3319 if None in c_set:
3320 o1 = cls.NC_any
3321 else:
3322 o1 = ( cls.NC_not, None )
3323 return o1
3324
3325 @classmethod
3327 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3328 assert 0 < len(constraints)
3329 o1 = constraints.pop(0)
3330 while 0 < len(constraints):
3331 o2 = constraints.pop(0)
3332
3333 if (o1 == o2):
3334 continue
3335
3336 if (cls.NC_any == o1) or (cls.NC_any == o2):
3337 if cls.NC_any == o1:
3338 o1 = o2
3339 continue
3340
3341 if isinstance(o1, set) and isinstance(o2, set):
3342 o1 = o1.intersection(o2)
3343 continue
3344 if isinstance(o1, tuple) and isinstance(o2, tuple):
3345 ns1 = o1[1]
3346 ns2 = o2[1]
3347
3348 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3349 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3350
3351 assert (ns1 is None) or (ns2 is None)
3352 if ns1 is None:
3353 assert ns2 is not None
3354 o1 = ( cls.NC_not, ns2 )
3355 else:
3356 assert ns1 is not None
3357 o1 = ( cls.NC_not, ns1 )
3358 continue
3359
3360
3361
3362 c_tuple = None
3363 c_set = None
3364 if isinstance(o1, tuple):
3365 assert isinstance(o2, set)
3366 c_tuple = o1
3367 c_set = o2
3368 else:
3369 assert isinstance(o1, set)
3370 assert isinstance(o2, tuple)
3371 c_tuple = o2
3372 c_set = o1
3373 negated_ns = c_tuple[1]
3374 if negated_ns in c_set:
3375 c_set.remove(negated_ns)
3376 if None in c_set:
3377 c_set.remove(None)
3378 o1 = c_set
3379 return o1
3380
3381 PC_skip = 'skip'
3382 PC_lax = 'lax'
3383 PC_strict = 'strict'
3384
3385
3386 __processContents = None
3387 - def processContents (self):
3388 return self.__processContents
3389
3391 """Get the plurality data for this wildcard
3392 """
3393 return _PluralityData(self)
3394
3396 """Return True, since Wildcard components are wildcards."""
3397 return True
3398
3404
3407
3408
3410 """Wildcards are scope-independent; return self"""
3411 return self
3412
3413
3414 @classmethod
3416 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3417 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3418 nc = domutils.NodeAttribute(node, 'namespace')
3419 if nc is None:
3420 namespace_constraint = cls.NC_any
3421 else:
3422 if cls.NC_any == nc:
3423 namespace_constraint = cls.NC_any
3424 elif cls.NC_not == nc:
3425 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3426 else:
3427 ncs = set()
3428 for ns_uri in nc.split():
3429 if cls.NC_local == ns_uri:
3430 ncs.add(None)
3431 elif cls.NC_targetNamespace == ns_uri:
3432 ncs.add(namespace_context.targetNamespace())
3433 else:
3434 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3435 namespace_constraint = frozenset(ncs)
3436
3437 pc = domutils.NodeAttribute(node, 'processContents')
3438 if pc is None:
3439 process_contents = cls.PC_strict
3440 else:
3441 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3442 process_contents = pc
3443 else:
3444 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3445
3446 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3447 rv._annotationFromDOM(node)
3448 return rv
3449
3450
3451 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3452 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3453
3454 ICC_KEY = 0x01
3455 ICC_KEYREF = 0x02
3456 ICC_UNIQUE = 0x04
3457
3458 __identityConstraintCategory = None
3461
3462 __selector = None
3465
3466 __fields = None
3469
3470 __referencedKey = None
3471 __referAttribute = None
3472 __icc = None
3473
3474 __annotations = None
3477
3478
3479 @classmethod
3481 name = domutils.NodeAttribute(node, 'name')
3482 scope = kw['scope']
3483 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3484 rv = cls(name=name, node=node, **kw)
3485
3486 kw.pop('node', None)
3487 kw['owner'] = rv
3488
3489
3490 rv.__isResolved = True
3491 icc = None
3492 if xsd.nodeIsNamed(node, 'key'):
3493 icc = rv.ICC_KEY
3494 elif xsd.nodeIsNamed(node, 'keyref'):
3495 icc = rv.ICC_KEYREF
3496 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3497 if rv.__referAttribute is None:
3498 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3499 rv.__isResolved = False
3500 elif xsd.nodeIsNamed(node, 'unique'):
3501 icc = rv.ICC_UNIQUE
3502 else:
3503 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3504 rv.__icc = icc
3505
3506 cn = domutils.LocateUniqueChild(node, 'selector')
3507 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3508 if rv.__selector is None:
3509 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3510
3511 rv.__fields = []
3512 for cn in domutils.LocateMatchingChildren(node, 'field'):
3513 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3514 if xp_attr is None:
3515 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3516 rv.__fields.append(xp_attr)
3517
3518 rv._annotationFromDOM(node)
3519 rv.__annotations = []
3520 if rv.annotation() is not None:
3521 rv.__annotations.append(rv)
3522
3523 for cn in node.childNodes:
3524 if (Node.ELEMENT_NODE != cn.nodeType):
3525 continue
3526 an = None
3527 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3528 an = domutils.LocateUniqueChild(cn, 'annotation')
3529 elif xsd.nodeIsNamed(cn, 'annotation'):
3530 an = cn
3531 if an is not None:
3532 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3533
3534 rv.__identityConstraintCategory = icc
3535 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3536 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3537
3538 if not rv.isResolved():
3539 rv._queueForResolution('creation')
3540 return rv
3541
3542 __isResolved = False
3545
3546
3561
3562
3564 """Constraint definitions that are by reference require the referenced constraint."""
3565 rv = set()
3566 if include_lax and (self.__referencedKey is not None):
3567 rv.add(self.__referencedKey)
3568 return frozenset(rv)
3569
3570
3571
3572
3573 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3574 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3575 __systemIdentifier = None
3578
3579 __publicIdentifier = None
3582
3583
3584 @classmethod
3594
3597 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3598
3599 __applicationInformation = None
3602
3603 __userInformation = None
3606
3607
3609 application_information = kw.pop('application_information', None)
3610 user_information = kw.pop('user_information', None)
3611 super(Annotation, self).__init__(**kw)
3612 if (user_information is not None) and (not isinstance(user_information, list)):
3613 user_information = [ unicode(user_information) ]
3614 if (application_information is not None) and (not isinstance(application_information, list)):
3615 application_information = [ unicode(application_information) ]
3616 self.__userInformation = user_information
3617 self.__applicationInformation = application_information
3618
3619
3620
3621
3622
3623
3624
3625
3626 __attributes = None
3627
3628
3629 @classmethod
3631 rv = cls(node=node, **kw)
3632
3633
3634
3635
3636
3637 assert xsd.nodeIsNamed(node, 'annotation')
3638 app_info = []
3639 user_info = []
3640 for cn in node.childNodes:
3641 if xsd.nodeIsNamed(cn, 'appinfo'):
3642 app_info.append(cn)
3643 elif xsd.nodeIsNamed(cn, 'documentation'):
3644 user_info.append(cn)
3645 else:
3646 pass
3647 if 0 < len(app_info):
3648 rv.__applicationInformation = app_info
3649 if 0 < len(user_info):
3650 rv.__userInformation = user_info
3651
3652 return rv
3653
3654 __RemoveMultiQuote_re = re.compile('""+')
3656 """Return the text in a form suitable for embedding in a
3657 triple-double-quoted docstring.
3658
3659 Any sequence of two or more double quotes is replaced by a sequence of
3660 single quotes that is the same length. Following this, spaces are
3661 added at the start and the end as necessary to ensure a double quote
3662 does not appear in those positions."""
3663 rv = self.text()
3664 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3665 if rv.startswith('"'):
3666 rv = ' ' + rv
3667 if rv.endswith('"'):
3668 rv = rv + ' '
3669 return rv
3670
3672 if self.__userInformation is None:
3673 return ''
3674 text = []
3675
3676
3677 for dn in self.__userInformation:
3678 for cn in dn.childNodes:
3679 if Node.TEXT_NODE == cn.nodeType:
3680 text.append(cn.data)
3681 return ''.join(text)
3682
3684 """Return the catenation of all user information elements in the
3685 annotation as a single unicode string. Returns the empty string if
3686 there are no user information elements."""
3687 return self.text()
3688
3689
3690 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3691 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3692
3693
3694
3695
3696 __baseTypeDefinition = None
3699
3700 __memberTypes = None
3701 __itemTypeAttribute = None
3702 __baseAttribute = None
3703 __memberTypesAttribute = None
3704 __localFacets = None
3705
3706
3707
3708
3709
3710
3711 __facets = None
3715
3716
3717 __fundamentalFacets = None
3719 """A frozenset of instances of facets.FundamentallFacet."""
3720 return self.__fundamentalFacets
3721
3722 STD_empty = 0
3723 STD_extension = 0x01
3724 STD_list = 0x02
3725 STD_restriction = 0x04
3726 STD_union = 0x08
3727
3728 _STD_Map = { 'extension' : STD_extension
3729 , 'list' : STD_list
3730 , 'restriction' : STD_restriction
3731 , 'union' : STD_union }
3732
3733
3734 __final = STD_empty
3735 @classmethod
3737 """Convert a final value to a string."""
3738 tags = []
3739 if final_value & cls.STD_extension:
3740 tags.append('extension')
3741 if final_value & cls.STD_list:
3742 tags.append('list')
3743 if final_value & cls.STD_restriction:
3744 tags.append('restriction')
3745 if final_value & cls.STD_union:
3746 tags.append('union')
3747 return ' '.join(tags)
3748
3749 VARIETY_absent = 0x01
3750 VARIETY_atomic = 0x02
3751 VARIETY_list = 0x03
3752 VARIETY_union = 0x04
3753
3754
3755 _DA_empty = 'none specified'
3756 _DA_restriction = 'restriction'
3757 _DA_list = 'list'
3758 _DA_union = 'union'
3759
3762 __derivationAlternative = None
3763
3764
3765
3766 __variety = None
3769 @classmethod
3781
3782
3783 __primitiveTypeDefinition = None
3791
3792
3793 __itemTypeDefinition = None
3800
3801
3802 __memberTypeDefinitions = None
3809
3810
3840
3841
3842
3843
3844
3845 __domNode = None
3846
3847
3848
3849 __isBuiltin = False
3850
3851
3852
3853
3857
3859 """Extend base class unpickle support to retain link between
3860 this instance and the Python class that it describes.
3861
3862 This is because the pythonSupport value is a class reference,
3863 not an instance reference, so it wasn't deserialized, and its
3864 class member link was never set.
3865 """
3866 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3867 super_fn(state)
3868 if self.__pythonSupport is not None:
3869 self.__pythonSupport._SimpleTypeDefinition(self)
3870
3898
3900 """Override fields in this instance with those from the other.
3901
3902 This method is invoked only by Schema._addNamedComponent, and
3903 then only when a built-in type collides with a schema-defined
3904 type. Material like facets is not (currently) held in the
3905 built-in copy, so the DOM information is copied over to the
3906 built-in STD, which is subsequently re-resolved.
3907
3908 Returns self.
3909 """
3910 assert self != other
3911 assert self.isNameEquivalent(other)
3912 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3913
3914
3915 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3916 assert other.__domNode is not None
3917 self.__domNode = other.__domNode
3918
3919
3920 if other.__pythonSupport is not None:
3921
3922 self.__pythonSupport = other.__pythonSupport
3923
3924
3925 self.__variety = None
3926 return self
3927
3929 """Indicate whether this simple type is a built-in type."""
3930 return self.__isBuiltin
3931
3932 __SimpleUrTypeDefinition = None
3933 @classmethod
3969
3970 @classmethod
4005
4006 @classmethod
4037
4038 @classmethod
4069
4070 @classmethod
4097
4098 @classmethod
4100 """(Placeholder) Create a union simple type in the target namespace.
4101
4102 This function has not been implemented."""
4103 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4104
4106 simple_type_child = None
4107 for cn in body.childNodes:
4108 if (Node.ELEMENT_NODE == cn.nodeType):
4109 if not xsd.nodeIsNamed(cn, 'simpleType'):
4110 if other_elts_ok:
4111 continue
4112 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4113 assert not simple_type_child
4114 simple_type_child = cn
4115 if simple_type_child is None:
4116 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4117 return simple_type_child
4118
4119
4120
4121
4122
4123
4124
4125
4135
4142
4143 __localMemberTypes = None
4153
4164
4166 """Create facets for varieties that can take facets that are undeclared.
4167
4168 This means unions, which per section 4.1.2.3 of
4169 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4170 pattern restrictions."""
4171 if self.VARIETY_union != variety:
4172 return self
4173 self.__facets.setdefault(facets.CF_pattern)
4174 self.__facets.setdefault(facets.CF_enumeration)
4175 return self
4176
4178 """Identify the facets and properties for this stype.
4179
4180 This method simply identifies the facets that apply to this
4181 specific type, and records property values. Only
4182 explicitly-associated facets and properties are stored; others
4183 from base types will also affect this type. The information
4184 is taken from the applicationInformation children of the
4185 definition's annotation node, if any. If there is no support
4186 for the XMLSchema_hasFacetAndProperty namespace, this is a
4187 no-op.
4188
4189 Upon return, self.__facets is a map from the class for an
4190 associated fact to None, and self.__fundamentalFacets is a
4191 frozenset of instances of FundamentalFacet.
4192
4193 The return value is self.
4194 """
4195 self.__facets = { }
4196 self.__fundamentalFacets = frozenset()
4197 if self.annotation() is None:
4198 return self.__defineDefaultFacets(variety)
4199 app_info = self.annotation().applicationInformation()
4200 if app_info is None:
4201 return self.__defineDefaultFacets(variety)
4202 facet_map = { }
4203 fundamental_facets = set()
4204 seen_facets = set()
4205 for ai in app_info:
4206 for cn in ai.childNodes:
4207 if Node.ELEMENT_NODE != cn.nodeType:
4208 continue
4209 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4210 facet_name = domutils.NodeAttribute(cn, 'name')
4211 if facet_name is None:
4212 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4213 if facet_name in seen_facets:
4214 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4215 seen_facets.add(facet_name)
4216 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4217
4218 facet_map[facet_class] = None
4219 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4220 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4221 if 0 < len(facet_map):
4222 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4223 self.__facets = facet_map
4224 assert type(self.__facets) == types.DictType
4225 if 0 < len(fundamental_facets):
4226 self.__fundamentalFacets = frozenset(fundamental_facets)
4227 return self
4228
4229
4280
4295
4296
4297
4298
4300 assert self.__variety is None
4301 if self.__baseTypeDefinition is None:
4302 assert self.__baseAttribute is not None
4303 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4304 base_type = base_en.typeDefinition()
4305 if not isinstance(base_type, SimpleTypeDefinition):
4306 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4307 self.__baseTypeDefinition = base_type
4308
4309
4310
4311 assert self.__baseTypeDefinition != self
4312 if not self.__baseTypeDefinition.isResolved():
4313 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4314 return self
4315 if variety is None:
4316
4317
4318 variety = self.__baseTypeDefinition.__variety
4319 assert variety is not None
4320
4321 if self.VARIETY_absent == variety:
4322
4323
4324 pass
4325 elif self.VARIETY_atomic == variety:
4326
4327
4328
4329 ptd = self
4330 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4331 ptd = ptd.__baseTypeDefinition
4332
4333 self.__primitiveTypeDefinition = ptd
4334 elif self.VARIETY_list == variety:
4335 if self._DA_list == alternative:
4336 if self.__itemTypeAttribute is not None:
4337 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4338 self.__itemTypeDefinition = it_en.typeDefinition()
4339 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4340 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4341 elif self._DA_restriction == alternative:
4342 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4343 else:
4344 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4345 elif self.VARIETY_union == variety:
4346 if self._DA_union == alternative:
4347
4348
4349
4350
4351 if self.__memberTypeDefinitions is None:
4352 mtd = []
4353
4354
4355 if self.__memberTypesAttribute is not None:
4356 for mn in self.__memberTypesAttribute.split():
4357
4358 mn_en = self._namespaceContext().interpretQName(mn)
4359 std = mn_en.typeDefinition()
4360 if std is None:
4361 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4362
4363 assert isinstance(std, SimpleTypeDefinition)
4364 mtd.append(std)
4365
4366 mtd.extend(self.__localMemberTypes)
4367 self.__memberTypeDefinitions = mtd
4368 assert None not in self.__memberTypeDefinitions
4369
4370
4371
4372
4373
4374
4375 mtd = []
4376 for mt in self.__memberTypeDefinitions:
4377 assert isinstance(mt, SimpleTypeDefinition)
4378 if not mt.isResolved():
4379 self._queueForResolution('member type not resolved', depends_on=mt)
4380 return self
4381 if self.VARIETY_union == mt.variety():
4382 mtd.extend(mt.memberTypeDefinitions())
4383 else:
4384 mtd.append(mt)
4385 elif self._DA_restriction == alternative:
4386 assert self.__baseTypeDefinition
4387
4388 assert self.__baseTypeDefinition.isResolved()
4389 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4390 assert mtd is not None
4391 else:
4392 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4393
4394 self.__memberTypeDefinitions = mtd[:]
4395 else:
4396 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4397
4398
4399
4400 self.__processHasFacetAndProperty(variety)
4401 self.__updateFacets(body)
4402
4403 self.__derivationAlternative = alternative
4404 self.__variety = variety
4405 self.__domNode = None
4406 return self
4407
4409 """Indicate whether this simple type is fully defined.
4410
4411 Type resolution for simple types means that the corresponding
4412 schema component fields have been set. Specifically, that
4413 means variety, baseTypeDefinition, and the appropriate
4414 additional fields depending on variety. See _resolve() for
4415 more information.
4416 """
4417
4418 return (self.__variety is not None)
4419
4420
4422 """Attempt to resolve the type.
4423
4424 Type resolution for simple types means that the corresponding
4425 schema component fields have been set. Specifically, that
4426 means variety, baseTypeDefinition, and the appropriate
4427 additional fields depending on variety.
4428
4429 All built-in STDs are resolved upon creation. Schema-defined
4430 STDs are held unresolved until the schema has been completely
4431 read, so that references to later schema-defined STDs can be
4432 resolved. Resolution is performed after the entire schema has
4433 been scanned and STD instances created for all
4434 topLevelSimpleTypes.
4435
4436 If a built-in STD is also defined in a schema (which it should
4437 be for XMLSchema), the built-in STD is kept, with the
4438 schema-related information copied over from the matching
4439 schema-defined STD. The former then replaces the latter in
4440 the list of STDs to be resolved.
4441
4442 Types defined by restriction have the same variety as the type
4443 they restrict. If a simple type restriction depends on an
4444 unresolved type, this method simply queues it for resolution
4445 in a later pass and returns.
4446 """
4447 if self.__variety is not None:
4448 return self
4449 assert self.__domNode
4450 node = self.__domNode
4451
4452 kw = { 'owner' : self
4453 , 'schema' : self._schema() }
4454
4455 bad_instance = False
4456
4457
4458 candidate = domutils.LocateUniqueChild(node, 'list')
4459 if candidate:
4460 self.__initializeFromList(candidate, **kw)
4461
4462 candidate = domutils.LocateUniqueChild(node, 'restriction')
4463 if candidate:
4464 if self.__variety is None:
4465 self.__initializeFromRestriction(candidate, **kw)
4466 else:
4467 bad_instance = True
4468
4469 candidate = domutils.LocateUniqueChild(node, 'union')
4470 if candidate:
4471 if self.__variety is None:
4472 self.__initializeFromUnion(candidate, **kw)
4473 else:
4474 bad_instance = True
4475
4476 if self.__baseTypeDefinition is None:
4477 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4478
4479 if self._schema() is not None:
4480 self.__final = self._schema().finalForNode(node, self._STD_Map)
4481
4482
4483 if bad_instance:
4484 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4485
4486 return self
4487
4488
4489 @classmethod
4505
4506
4507
4508
4509 __pythonSupport = None
4510
4520
4523
4528
4531
4534
4536 """Subclass ensures there is only one simple ur-type."""
4537 pass
4538
4644
4645 -class Schema (_SchemaComponent_mixin):
4646 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4647
4650
4651
4652 __annotations = None
4653
4654
4655
4656 __pastProlog = False
4657
4659 """URI or path to where the schema can be found.
4660
4661 For schema created by a user, the location should be provided to the
4662 constructor using the C{schema_location} keyword. In the case of
4663 imported or included schema, the including schema's location is used
4664 as the base URI for determining the absolute URI of the included
4665 schema from its (possibly relative) location value. For files,
4666 the scheme and authority portions are generally absent, as is often
4667 the abs_path part."""
4668 return self.__location
4669 __location = None
4670
4673 __locationTag = None
4674
4677 __signature = None
4678
4681 __generationUID = None
4682
4685 __originRecord = None
4686
4688 """The targetNamespace of a componen.
4689
4690 This is None, or a reference to a Namespace in which the
4691 component is declared (either as a global or local to one of
4692 the namespace's complex type definitions). This is immutable
4693 after creation.
4694 """
4695 return self.__targetNamespace
4696 __targetNamespace = None
4697
4699 """Default namespace of the schema.
4700
4701 Will be None unless the schema has an 'xmlns' attribute. The
4702 value must currently be provided as a keyword parameter to the
4703 constructor. """
4704 return self.__defaultNamespace
4705 __defaultNamespace = None
4706
4709 __referencedNamespaces = None
4710
4711 __namespaceData = None
4712
4715 __importEIIs = None
4716
4719 __importedSchema = None
4722 __includedSchema = None
4723
4724 _QUALIFIED = "qualified"
4725 _UNQUALIFIED = "unqualified"
4726
4727
4728 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4729 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4730 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4731 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4732 , pyxb.namespace.ExpandedName(None, 'id') : None
4733 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4734 , pyxb.namespace.ExpandedName(None, 'version') : None
4735 , pyxb.namespace.XML.createExpandedName('lang') : None
4736 }
4737
4742
4744 """Override the schema attributes with values from the given map."""
4745 self.__attributeMap.update(attr_map)
4746 return self
4747
4749 """Return True iff the schema has an attribute with the given (nc)name."""
4750 if isinstance(attr_name, basestring):
4751 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4752 return self.__attributeMap.has_key(attr_name)
4753
4755 """Return the schema attribute value associated with the given (nc)name.
4756
4757 @param attr_name: local name for the attribute in the schema element.
4758 @return: the value of the corresponding attribute, or C{None} if it
4759 has not been defined and has no default.
4760 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4761 """
4762 if isinstance(attr_name, basestring):
4763 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4764 return self.__attributeMap[attr_name]
4765
4766 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4767 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4768 'identityConstraintDefinition' )
4769
4772 __uriContentArchiveDirectory = None
4773
4815
4816 __TopLevelComponentMap = {
4817 'element' : ElementDeclaration,
4818 'attribute' : AttributeDeclaration,
4819 'notation' : NotationDeclaration,
4820 'simpleType' : SimpleTypeDefinition,
4821 'complexType' : ComplexTypeDefinition,
4822 'group' : ModelGroupDefinition,
4823 'attributeGroup' : AttributeGroupDefinition
4824 }
4825
4826 @classmethod
4831
4832 @classmethod
4834 """Create a schema from a schema location.
4835
4836 Reads an XML document from the schema location and creates a schema
4837 using it. All keyword parameters are passed to L{CreateFromDOM}.
4838
4839 @keyword schema_location: A file path or a URI. If this is a relative
4840 URI and C{parent_uri} is present, the actual location will be
4841 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4842 @keyword parent_uri: The context within which schema_location will be
4843 normalized, if necessary.
4844 @keyword absolute_schema_location: A file path or URI. This value is
4845 not normalized, and supersedes C{schema_location}.
4846 """
4847 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4848 kw['location_base'] = kw['schema_location'] = schema_location
4849 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4850 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4851 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4852
4853 @classmethod
4856
4857 @classmethod
4858 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4859 """Take the root element of the document, and scan its attributes under
4860 the assumption it is an XMLSchema schema element. That means
4861 recognize namespace declarations and process them. Also look for
4862 and set the default namespace. All other attributes are passed up
4863 to the parent class for storage."""
4864
4865
4866
4867 including_context = kw.get('including_context')
4868
4869 root_node = node
4870 if Node.DOCUMENT_NODE == node.nodeType:
4871 root_node = root_node.documentElement
4872 if Node.ELEMENT_NODE != root_node.nodeType:
4873 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4874
4875 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4876 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4877 parent_context=namespace_context,
4878 including_context=including_context)
4879
4880 tns = ns_ctx.targetNamespace()
4881 if tns is None:
4882 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4883 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4884 schema.__namespaceData = ns_ctx
4885
4886 if schema.targetNamespace() != ns_ctx.targetNamespace():
4887 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4888
4889
4890 for ai in range(root_node.attributes.length):
4891 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4892
4893
4894 if not xsd.nodeIsNamed(root_node, 'schema'):
4895 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4896
4897 for cn in root_node.childNodes:
4898 if Node.ELEMENT_NODE == cn.nodeType:
4899 rv = schema.__processTopLevelNode(cn)
4900 if rv is None:
4901 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4902 elif Node.TEXT_NODE == cn.nodeType:
4903
4904
4905 text = cn.data.strip()
4906 if text:
4907 _log.info('Ignored text: %s', text)
4908 elif Node.COMMENT_NODE == cn.nodeType:
4909 pass
4910 else:
4911
4912
4913
4914
4915
4916
4917
4918 _log.info('Ignoring non-element: %s', cn)
4919
4920
4921
4922
4923 return schema
4924
4925 _SA_All = '#all'
4926
4928 ebv = domutils.NodeAttribute(dom_node, attr)
4929 if ebv is None:
4930 ebv = self.schemaAttribute('%sDefault' % (attr,))
4931 rv = 0
4932 if ebv == self._SA_All:
4933 for v in candidate_map.values():
4934 rv += v
4935 else:
4936 for candidate in ebv.split():
4937 rv += candidate_map.get(candidate, 0)
4938 return rv
4939
4941 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4942
4943 A value of '#all' means enable every options; otherwise, the attribute
4944 value should be a list of tokens, for which the corresponding value
4945 will be added to the return value.
4946
4947 @param dom_node: the node from which the "block" attribute will be retrieved
4948 @type dom_node: C{xml.dom.Node}
4949 @param candidate_map: map from strings to bitmask values
4950 """
4951 return self.__ebvForNode('block', dom_node, candidate_map)
4952
4954 """Return a bit mask indicating a set of options read from the node's
4955 "final" attribute or the schema's "finalDefault" attribute.
4956
4957 A value of '#all' means enable every options; otherwise, the attribute
4958 value should be a list of tokens, for which the corresponding value
4959 will be added to the return value.
4960
4961 @param dom_node: the node from which the "final" attribute will be retrieved
4962 @type dom_node: C{xml.dom.Node}
4963 @param candidate_map: map from strings to bitmask values
4964 """
4965 return self.__ebvForNode('final', dom_node, candidate_map)
4966
4968 """Determine the target namespace for a local attribute or element declaration.
4969
4970 Look at the node's C{form} attribute, or if none the schema's
4971 C{attributeFormDefault} or C{elementFormDefault} value. If the
4972 resulting value is C{"qualified"} and the parent schema has a
4973 non-absent target namespace, return it to use as the declaration
4974 target namespace. Otherwise, return None to indicate that the
4975 declaration has no namespace.
4976
4977 @param dom_node: The node defining an element or attribute declaration
4978 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4979 @return: L{pyxb.namespace.Namespace} or None
4980 """
4981
4982 form_type = domutils.NodeAttribute(dom_node, 'form')
4983 if form_type is None:
4984 if declaration_type == ElementDeclaration:
4985 form_type = self.schemaAttribute('elementFormDefault')
4986 elif declaration_type == AttributeDeclaration:
4987 form_type = self.schemaAttribute('attributeFormDefault')
4988 else:
4989 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4990 tns = None
4991 if (self._QUALIFIED == form_type):
4992 tns = self.targetNamespace()
4993 if tns.isAbsentNamespace():
4994 tns = None
4995 else:
4996 if (self._UNQUALIFIED != form_type):
4997 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4998 return tns
4999
5001 """Throw a SchemaValidationException referencing the given
5002 node if we have passed the sequence point representing the end
5003 of prolog elements."""
5004
5005 if self.__pastProlog:
5006 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
5007
5009 self.__requireInProlog(node.nodeName)
5010
5011 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
5012 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
5013 if not has_schema:
5014 kw = { 'absolute_schema_location': abs_uri,
5015 'including_context': self.__namespaceData,
5016 'generation_uid': self.generationUID(),
5017 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
5018 }
5019 try:
5020 schema_instance = self.CreateFromLocation(**kw)
5021 except pyxb.SchemaUniquenessError, e:
5022 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
5023 except Exception, e:
5024 _log.exception('INCLUDE %s caught', abs_uri)
5025 raise
5026 if schema_instance:
5027 if self.targetNamespace() != schema_instance.targetNamespace():
5028 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
5029 self.__includedSchema.add(schema_instance)
5030 return node
5031
5049
5053
5057
5081
5085
5087 tns = self.targetNamespace()
5088 assert tns is not None
5089 if not isinstance(nc, _NamedComponent_mixin):
5090 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
5091 if nc.isAnonymous():
5092 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
5093 if isinstance(nc, _ScopedDeclaration_mixin):
5094 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
5095 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5096 return self.__addTypeDefinition(nc)
5097 if isinstance(nc, AttributeDeclaration):
5098 return self.__addAttributeDeclaration(nc)
5099 if isinstance(nc, AttributeGroupDefinition):
5100 return self.__addAttributeGroupDefinition(nc)
5101 if isinstance(nc, ModelGroupDefinition):
5102 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5103 if isinstance(nc, ElementDeclaration):
5104 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5105 if isinstance(nc, NotationDeclaration):
5106 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5107 if isinstance(nc, IdentityConstraintDefinition):
5108 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5109 raise pyxb.IncompleteImplementationError('No support to record named component of type %s' % (nc.__class__,))
5110
5130
5147
5164
5166 return 'SCH[%s]' % (self.location(),)
5167
5170 """Add to the schema the definitions of the built-in types of XMLSchema.
5171 This should only be invoked by L{pyxb.namespace} when the built-in
5172 namespaces are initialized. """
5173
5174
5175 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5176 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5177 assert td.isResolved()
5178
5179 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5180 assert td.isResolved()
5181
5182 pts_std_map = {}
5183 for dtc in datatypes._PrimitiveDatatypes:
5184 name = dtc.__name__.rstrip('_')
5185 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5186 assert td.isResolved()
5187 assert dtc.SimpleTypeDefinition() == td
5188 pts_std_map.setdefault(dtc, td)
5189 for dtc in datatypes._DerivedDatatypes:
5190 name = dtc.__name__.rstrip('_')
5191 parent_std = pts_std_map[dtc.XsdSuperType()]
5192 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5193 assert td.isResolved()
5194 assert dtc.SimpleTypeDefinition() == td
5195 pts_std_map.setdefault(dtc, td)
5196 for dtc in datatypes._ListDatatypes:
5197 list_name = dtc.__name__.rstrip('_')
5198 element_name = dtc._ItemType.__name__.rstrip('_')
5199 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5200 assert element_std is not None
5201 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5202 assert td.isResolved()
5203 global _PastAddBuiltInTypes
5204 _PastAddBuiltInTypes = True
5205
5206 return schema
5207
5208 import sys
5209 import pyxb.namespace.builtin
5210 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5211
5212
5213
5214
5215