1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """Classes corresponding to W3C XML Schema components.
16
17 Class names and behavior should conform to the schema components described in
18 U{XML Schema Part 1: Structures<http://www.w3.org/TR/xmlschema-1/>}.
19 References to sections in the documentation of this module generally refers to
20 that document.
21
22 Each class has a C{CreateFromDOM} class method that creates an instance and
23 initializes it from a DOM node. Only the L{Wildcard}, L{Particle}, and
24 L{ModelGroup} components are created from non-DOM sources. However, the
25 requirements on DOM interface are restricted to attributes, child nodes, and
26 basic fields, though all these must support namespaces.
27
28 @group Mixins: *_mixin
29 @group Ur Type Specializations: *UrType*
30 @group Utilities: _PluralityData, _ImportElementInformationItem
31
32 """
33
34 import traceback
35 import pyxb
36 import pyxb.xmlschema
37 from xml.dom import Node
38 import xml.dom
39 import types
40 import re
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.domutils import *
49 import pyxb.utils.utility
50 import copy
51 import urllib2
52 import urlparse
53 import os.path
54
55
56 _PastAddBuiltInTypes = False
57
58
59 from pyxb.namespace import XMLSchema as xsd
60
61 -class _SchemaComponent_mixin (pyxb.namespace._ComponentDependency_mixin,
62 pyxb.namespace.archive._ArchivableObject_mixin,
63 pyxb.utils.utility.PrivateTransient_mixin,
64 pyxb.utils.utility.Locatable_mixin):
65 """A mix-in that marks the class as representing a schema component.
66
67 This exists so that we can determine the owning schema for any
68 component we encounter. This is normally done at construction
69 time by passing a C{schema=val} parameter to the constructor.
70 """
71
72
73
74 __PrivateTransient = set()
75
77 """The namespace context for this schema.
78
79 This defines where it looks things up, where it puts things it
80 createas, the in-scope namespace declarations, etc. Must be defined
81 for anything that does any sort of QName interpretation. The value is
82 generally a reference to a namespace context associated with the DOM
83 element node corresponding to this component."""
84 if self.__namespaceContext is None:
85 raise pyxb.LogicError('Attempt to access missing namespace context for %s' % (self,))
86 return self.__namespaceContext
88 self.__namespaceContext = None
89 return self
90 __namespaceContext = None
91 __PrivateTransient.add('namespaceContext')
92
93
94
95
96
97 __nameInBinding = None
98
99
100
101 __owner = None
102 __PrivateTransient.add('owner')
103
104
105 __ownedComponents = None
106 __PrivateTransient.add('ownedComponent')
107
109 """The context into which declarations in or subordinate to this nodeare placed."""
110 return self.__scope
111 __scope = None
112
116
120
122 """Set the scope of this instance after construction.
123
124 This should only be invoked on cloned declarations being incorporated
125 into a complex type definition. Note that the source of the clone may
126 be any scope: indeterminate if from a model (attribute) group
127 definition; global if a reference to a global component; or ctd if
128 inherited from a complex base type."""
129 assert self.__cloneSource is not None
130 assert isinstance(self, _ScopedDeclaration_mixin)
131 assert isinstance(ctd, ComplexTypeDefinition)
132 self.__scope = ctd
133 return self
134
136 """Initialize portions of a component.
137
138 @keyword scope: The scope in which the component is defined
139
140 @keyword namespace_context: The NamespaceContext to use within this component
141
142 @keyword node: If no C{namespace_context} is provided, a DOM node must
143 be provided from which a namespace context can be identified.
144
145 @keyword owner: Reference to the component that owns this one (the
146 immediately enclosing component). Is C{None} in the case of top-level
147 components.
148
149 @keyword schema: Reference to the L{Schema} component to which the
150 component belongs. Required for every component except L{Schema},
151 L{Annotation}, and L{Wildcard}.
152 """
153
154 self.__ownedComponents = set()
155 self.__scope = kw.get('scope')
156 self.__namespaceContext = kw.get('namespace_context')
157 node = kw.get('node')
158 if self.__namespaceContext is None:
159 if node is None:
160 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node')
161 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
162 if self.__namespaceContext is None:
163 raise pyxb.LogicError('No namespace_context for schema component')
164
165 super(_SchemaComponent_mixin, self).__init__(*args, **kw)
166
167 if isinstance(node, pyxb.utils.utility.Locatable_mixin):
168 self._setLocation(node._location())
169
170 self._namespaceContext().targetNamespace()._associateComponent(self)
171
172 self._setOwner(kw.get('owner'))
173
174 schema = kw.get('schema')
175 if schema is not None:
176 self._setObjectOrigin(schema.originRecord())
177 else:
178 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),)
179
180 if isinstance(self, ComplexTypeDefinition):
181 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
182
183
185 """Dissociate this component from its owning namespace.
186
187 This should only be done whwen there are no other references to the
188 component, and you want to ensure it does not appear in the model."""
189 self._namespaceContext().targetNamespace()._replaceComponent(self, None)
190 return self
191
193 """Set the owner of this component.
194
195 If C{owner} is C{None}, this has no effect. Otherwise, the
196 component's current owner must be either C{None} or the same as the
197 input C{owner}."""
198
199 if owner is not None:
200 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner)
201 self.__owner = owner
202 owner.__ownedComponents.add(self)
203 return self
204
207
208
209 __cloneSource = None
210 __PrivateTransient.add('cloneSource')
211
213 """The source component from which this is a clone.
214
215 Returns C{None} if this is not a clone."""
216 return self.__cloneSource
217
218
219 __clones = None
220 __PrivateTransient.add('clones')
221
223 """The set of instances cloned from this component.
224
225 Returns None if no instances have been cloned from this."""
226 return self.__clones
227
253
254 - def _clone (self, owner, origin):
278
283
288
290 """Return the name of this component, as best it can be determined.
291
292 For example, ModelGroup instances will be named by their
293 ModelGroupDefinition, if available. Returns None if no name can be
294 inferred."""
295 if isinstance(self, _NamedComponent_mixin):
296 return self.name()
297 if isinstance(self, ModelGroup):
298 agd = self.modelGroupDefinition()
299 if agd is not None:
300 return agd.name()
301 return None
302
304 """Return the name by which this component is known in the generated
305 binding.
306
307 @note: To support builtin datatypes, type definitions with an
308 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class
309 initialize their binding name from the class name when the support
310 association is created. As long as no built-in datatype conflicts
311 with a language keyword, this should be fine."""
312 return self.__nameInBinding
313
315 """Return C{True} iff this is a component which has a user-visible
316 Python construct which serves as its binding.
317
318 Type definitions have classes as their bindings. Global element
319 declarations have instances of L{pyxb.binding.basis.element} as their
320 bindings."""
321 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
322
324 """Set the name by which this component shall be known in the XSD binding."""
325 self.__nameInBinding = name_in_binding
326 return self
327
329 """Override fields in this instance with those from the other.
330
331 Post-extended; description in leaf implementation in
332 ComplexTypeDefinition and SimpleTypeDefinition."""
333 assert self != other
334 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', lambda *args, **kw: self)(other)
335
336 if self.__nameInBinding is None:
337 self.__nameInBinding = other.__nameInBinding
338 return self
339
341 """This class is a mix-in which guarantees that only one instance
342 of the class will be created. It is used to ensure that the
343 ur-type instances are pointer-equivalent even when unpickling.
344 See ComplexTypeDefinition.UrTypeDefinition()."""
346 singleton_property = '_%s__singleton' % (cls.__name__,)
347 if not (singleton_property in cls.__dict__):
348 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
349 return cls.__dict__[singleton_property]
350
352 """Mix-in that supports an optional single annotation that describes the component.
353
354 Most schema components have annotations. The ones that don't are
355 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
356 and L{Schema} support multiple annotations, so do not mix-in this
357 class."""
358
359
360 __annotation = None
361
365
373
375 """Override fields in this instance with those from the other.
376
377 Post-extended; description in leaf implementation in
378 ComplexTypeDefinition and SimpleTypeDefinition."""
379 assert self != other
380 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', lambda *args, **kw: self)(other)
381
382 self.__annotation = other.__annotation
383 return self
384
387
389 """A helper that encapsulates a reference to an anonymous type in a different namespace.
390
391 Normally references to components in other namespaces can be made using
392 the component's name. This is not the case when a namespace derives from
393 a base type in another namespace and needs to reference the attribute or
394 element declarations held in that type. If these declarations are local
395 to the base complex type, they cannot be identified by name. This class
396 provides a pickleable representation for them that behaves rather like an
397 L{pyxb.namespace.ExpandedName} instance in that it can be used to
398 dereference various component types."""
399
400 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
401
402 __namespace = None
403 __anonymousName = None
404 - def __init__ (self, namespace, anonymous_name):
405 """Create a new anonymous reference.
406
407 @param namespace: The namespace in which the component is declared.
408 @type namespace: L{pyxb.namespace.Namespace}
409 @param anonymous_name: A generated name guaranteed to be unique within
410 the namespace. See L{_NamedComponent_mixin._anonymousName}.
411 @type anonymous_name: C{basestring}.
412 """
413 self.__namespace = namespace
414 self.__anonymousName = anonymous_name
415 assert self.__anonymousName is not None
416
417 @classmethod
419 """Return the component referred to by the provided reference,
420 regardless of whether it is a normal or anonymous reference."""
421 if not isinstance(object_reference, _PickledAnonymousReference):
422 assert isinstance(object_reference, tuple)
423 object_reference = pyxb.namespace.ExpandedName(object_reference)
424 return object_reference
425
428
431
435
439
440 typeDefinition = __lookupObject
441 """Return the attribute group definition referenced by this instance, or
442 C{None} if the reference is not to an attribute group definition."""
443
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
563
565 """Return C{True} if this component should be pickled by value in the
566 given namespace.
567
568 When pickling, a declaration component is considered to belong to the
569 namespace if it has a local scope which belongs to the namespace. In
570 that case, the declaration is a clone of something that does not
571 belong to the namespace; but the clone does.
572
573 @see: L{_bindsInNamespace}
574
575 @return: C{False} if the component should be pickled by reference.
576 """
577 if isinstance(self._scope(), ComplexTypeDefinition):
578 return self._scope()._picklesInArchive(archive)
579 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
580 assert not (self._objectOrigin() is None)
581 old_flag = (self.targetNamespace() in archive.namespaces())
582 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
583
584 return new_flag
585
587 """Return C{True} if the binding for this component should be
588 generated in the given namespace.
589
590 This is the case when the component is in the given namespace. It's
591 also the case when the component has no associated namespace (but not
592 an absent namespace). Be aware that cross-namespace inheritance means
593 you will get references to elements in another namespace when
594 generating code for a subclass; that's fine, and those references
595 should not be generated locally.
596 """
597 return self.targetNamespace() in (ns, None)
598
604
606 """Pickling support.
607
608 Normally, we just create a new instance of this class.
609 However, if we're unpickling a reference in a loadable schema,
610 we need to return the existing component instance by looking
611 up the name in the component map of the desired namespace. We
612 can tell the difference because no normal constructors that
613 inherit from this have positional arguments; only invocations
614 by unpickling with a value returned in __getnewargs__ do.
615
616 This does require that the dependent namespace already have
617 been validated (or that it be validated here). That shouldn't
618 be a problem, except for the dependency loop resulting from
619 use of xml:lang in the XMLSchema namespace. For that issue,
620 see pyxb.namespace._XMLSchema.
621 """
622
623 if 0 == len(args):
624 rv = super(_NamedComponent_mixin, cls).__new__(cls)
625 return rv
626 ( object_reference, scope, icls ) = args
627
628 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
629
630
631
632 object_reference.validateComponentModel()
633 if isinstance(scope, (tuple, _PickledAnonymousReference)):
634
635
636 scope_ref = _PickledAnonymousReference.FromPickled(scope)
637 if object_reference.namespace() != scope_ref.namespace():
638 scope_ref.validateComponentModel()
639 assert 'typeDefinition' in scope_ref.namespace().categories()
640 scope_ctd = scope_ref.typeDefinition()
641 if scope_ctd is None:
642 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
643 if issubclass(icls, AttributeDeclaration):
644 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
645 elif issubclass(icls, ElementDeclaration):
646 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
647 else:
648 raise pyxb.IncompleteImplementationError('Scope %s reference lookup of %s not implemented for type %s' % (scope_ref, object_reference, icls))
649 if rv is None:
650 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
651 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
652 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
653 rv = object_reference.typeDefinition()
654 elif issubclass(icls, AttributeGroupDefinition):
655 rv = object_reference.attributeGroupDefinition()
656 elif issubclass(icls, ModelGroupDefinition):
657 rv = object_reference.modelGroupDefinition()
658 elif issubclass(icls, AttributeDeclaration):
659 rv = object_reference.attributeDeclaration()
660 elif issubclass(icls, ElementDeclaration):
661 rv = object_reference.elementDeclaration()
662 elif issubclass(icls, IdentityConstraintDefinition):
663 rv = object_reference.identityConstraintDefinition()
664 else:
665 raise pyxb.IncompleteImplementationError('Reference lookup of %s not implemented for type %s' % (object_reference, icls))
666 if rv is None:
667 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
668 else:
669 raise pyxb.IncompleteImplementationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, scope.targetNamespace(), type(scope), icls))
670 return rv
671
692
694 """Return true iff this and the other component share the same name and target namespace.
695
696 Anonymous components are inherently name inequivalent, except to
697 themselves. This relies on equivalence as defined for
698 pyxb.namespace.ExpandedName, for which None is not equivalent to any
699 non-anonymous name."""
700
701 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
702
704 """Return True iff this and the other component have matching types.
705
706 It appears that name equivalence is used; two complex type definitions
707 with identical structures are not considered equivalent (at least, per
708 XMLSpy).
709 """
710 return (type(self) == type(other)) and self.isNameEquivalent(other)
711
713 """Return True iff this type can serve as a restriction of the other
714 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
715
716 It appears that name equivalence is normally used; two complex type
717 definitions with identical structures are not considered equivalent
718 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
719 that derivation by restriction from the other type is also acceptable.
720 That opens a whole can of worms; see
721 L{ElementDeclaration.isAdaptable}.
722 """
723 this = self
724
725 while this is not None:
726 if this.isTypeEquivalent(other):
727 return True
728 print 'Checking %s against %s' % (this, other)
729 if not (this.isResolved() and other.isResolved()):
730 raise pyxb.IncompleteImplementationError('Oh fudge. Somebody violated the assumptions in ElementDeclaration.isAdaptable.')
731 if isinstance(self, ComplexTypeDefinition):
732 if self.DM_restriction != this.derivationMethod():
733 return False
734 elif isinstance(self, SimpleTypeDefinition):
735 if self._DA_restriction != this._derivationAlternative():
736 return False
737 else:
738 raise pyxb.IncompleteImplementationError('Need derivation consistency check for type %s' % (type(this),))
739 this = this.baseTypeDefinition()
740 if this.isUrTypeDefinition():
741
742
743 break
744 return False
745
752
770
796
798 """Pickling support.
799
800 If this instance is being pickled as a reference, provide the
801 arguments that are necessary so that the unpickler can locate
802 the appropriate component rather than create a duplicate
803 instance."""
804
805 if self.__pickleAsReference():
806 scope = self._scope()
807 if isinstance(self, _ScopedDeclaration_mixin):
808
809
810
811
812
813 if self.SCOPE_global == self.scope():
814 pass
815 elif isinstance(self.scope(), ComplexTypeDefinition):
816 scope = self.scope()._picklingReference()
817 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
818 elif self._scopeIsIndeterminate():
819
820
821 pass
822 else:
823 raise pyxb.IncompleteImplementationError('pickling unrecognized scope %s type %s' % (self.scope(), type(self.scope())))
824 else:
825 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
826 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
827
828 rv = ( self._picklingReference(), scope, self.__class__ )
829 return rv
830 return ()
831
848
857
859 """Mix-in indicating that the component contains a simple-type
860 value that may be constrained."""
861
862 VC_na = 0
863 VC_default = 1
864 VC_fixed = 2
865
866
867
868 __valueConstraint = None
870 """A constraint on the value of the attribute or element.
871
872 Either None, or a pair consisting of a string in the lexical
873 space of the typeDefinition and one of VC_default and
874 VC_fixed."""
875 return self.__valueConstraint
876
885
894
906
908 """Mix-in class for named components that have a scope.
909
910 Scope is important when doing cross-namespace inheritance,
911 e.g. extending or restricting a complex type definition that is
912 from a different namespace. In this case, we will need to retain
913 a reference to the external component when the schema is
914 serialized.
915
916 This is done in the pickling process by including the scope when
917 pickling a component as a reference. The scope is the
918 SCOPE_global if global; otherwise, it is a tuple containing the
919 external namespace URI and the NCName of the complex type
920 definition in that namespace. We assume that the complex type
921 definition has global scope; otherwise, it should not have been
922 possible to extend or restrict it. (Should this be untrue, there
923 are comments in the code about a possible solution.)
924
925 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
926 """
927
928 SCOPE_global = 'global'
929 XSCOPE_indeterminate = 'indeterminate'
930
931 @classmethod
934
935 @classmethod
938
939 @classmethod
942
944 """Return True if this scope currently assigned to this instance is compatible with the given scope.
945
946 If either scope is indeterminate, presume they will ultimately be
947 compatible. Scopes that are equal are compatible, as is a local scope
948 if this already has a global scope."""
949 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
950 return True
951 if self.scope() == scope:
952 return True
953 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
954
955
956
957
959 """The scope for the declaration.
960
961 Valid values are SCOPE_global, or a complex type definition.
962 A value of None means a non-global declaration that is not
963 owned by a complex type definition. These can only appear in
964 attribute group definitions or model group definitions.
965
966 @todo: For declarations in named model groups (viz., local
967 elements that aren't references), the scope needs to be set by
968 the owning complex type.
969 """
970 return self._scope()
971
972
973
974
975
976 __baseDeclaration = None
982
984 """This class represents an abstraction of the set of documents conformant
985 to a particle or particle term.
986
987 The abstraction of a given document is a map from element declarations
988 that can appear at the top level of the document to a boolean that is true
989 iff there could be multiple instances of that element declaration at the
990 top level of a valid document. The abstraction of the set is a list of
991 document abstractions.
992
993 This information is used in binding generation to determine whether a
994 field associated with a tag might need to hold multiple instances.
995 """
996
997 @classmethod
999 """Given two maps, return an updated map indicating the unified
1000 plurality."""
1001 umap = { }
1002 for k in set(map1.keys()).union(map2.keys()):
1003 if k in map1:
1004 umap[k] = (k in map2) or map1[k]
1005 else:
1006 umap[k] = map2[k]
1007 return umap
1008
1010 """Combine all the document abstractions into a single one that covers
1011 all possible documents.
1012
1013 The combined plurality is simply the elemental maximum over all
1014 document abstractions.
1015 """
1016
1017 combined_plurality = { }
1018 for pdm in self:
1019 for (ed, v) in pdm.items():
1020 if isinstance(ed, ElementDeclaration):
1021 assert ed.baseDeclaration() == ed
1022 combined_plurality[ed] = combined_plurality.get(ed, False) or v
1023 elif isinstance(ed, Wildcard):
1024 pass
1025 else:
1026 raise pyxb.LogicError('Unexpected plurality index %s' % (ed,))
1027 return combined_plurality
1028
1054
1055 - def __fromParticle (self, particle):
1056 assert particle.isResolved()
1057 pd = particle.term().pluralityData()
1058
1059
1060 if 0 == particle.maxOccurs():
1061 return
1062
1063
1064
1065 if 1 == particle.maxOccurs():
1066 self.__setFromComponent(particle.term())
1067 return
1068
1069
1070
1071
1072 true_map = {}
1073 pd = _PluralityData(particle.term())
1074 while 0 < len(pd):
1075 pdm = pd.pop()
1076 [ true_map.setdefault(_k, True) for _k in pdm.keys() ]
1077 self.append(true_map)
1078
1098
1102
1104 """Support for components that accept attribute wildcards.
1105
1106 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1107 calculations of the appropriate wildcard are sufficiently complex that
1108 they need to be abstracted out to a mix-in class."""
1109
1110
1111 __attributeWildcard = None
1112
1114 """Return the L{Wildcard} component associated with attributes of this
1115 instance, or C{None} if attribute wildcards are not present in the
1116 instance."""
1117 return self.__attributeWildcard
1118
1120 """Set the attribute wildcard property for this instance."""
1121 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1122 self.__attributeWildcard = attribute_wildcard
1123 return self
1124
1126 """Return the nodes that are relevant for attribute processing.
1127
1128 @param node_list: A sequence of nodes found in a definition content
1129 information item.
1130
1131 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1132 where C{attributes} is the subsequence of C{node_list} that are
1133 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1134 C{attributeWildcard} is a single DOM node with XMLSchema name
1135 C{anyAttribute} (or C{None}, if no such node is present in the list).
1136
1137 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1138 present but does not have the required C{ref} attribute.
1139 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1140 identified.
1141 """
1142
1143 attributes = []
1144 attribute_groups = []
1145 any_attribute = None
1146
1147 for node in node_list:
1148 if Node.ELEMENT_NODE != node.nodeType:
1149 continue
1150 if xsd.nodeIsNamed(node, 'attribute'):
1151
1152 attributes.append(node)
1153 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1154
1155 agd_attr = NodeAttribute(node, 'ref')
1156 if agd_attr is None:
1157 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1158 attribute_groups.append(agd_attr)
1159 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1160 if any_attribute is not None:
1161 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1162 any_attribute = node
1163
1164 return (attributes, attribute_groups, any_attribute)
1165
1166 @classmethod
1167 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1168 """Implement the algorithm as described the
1169 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1170
1171 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1172 associated with any created L{Wildcard} instance
1173 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1174 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1175 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1176 is relevant
1177 """
1178
1179
1180 agd_wildcards = []
1181 for agd in attribute_groups:
1182 assert isinstance(agd, AttributeGroupDefinition)
1183 if agd.attributeWildcard() is not None:
1184 agd_wildcards.append(agd.attributeWildcard())
1185 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1186
1187
1188 if 0 == len(agd_wildcards):
1189 return local_wildcard
1190
1191 if local_wildcard is not None:
1192
1193 return Wildcard(process_contents=local_wildcard.processContents(),
1194 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1195 annotation=local_wildcard.annotation(),
1196 namespace_context=namespace_context)
1197
1198 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1199 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1200 namespace_context=namespace_context)
1201
1202 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1203 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1204 """
1205
1206
1207 __typeDefinition = None
1209 """The simple type definition to which an attribute value must
1210 conform."""
1211 return self.__typeDefinition
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 = NodeAttribute(node, 'name')
1262
1263
1264 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1265 assert cls.SCOPE_global == scope
1266 elif 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 = NodeAttribute(node, 'type')
1277
1278 kw.pop('node', None)
1279 kw['owner'] = rv
1280
1281 st_node = 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 print '**!!**!! 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
1354
1355 __restrictionOf = None
1363
1364
1366 """The attribute declaration for this use.
1367
1368 When the use scope is assigned, the declaration is cloned (if
1369 necessary) so that each declaration corresponds to only one use. We
1370 rely on this in code generation, because the template map for the use
1371 is stored in its declaration."""
1372 return self.__attributeDeclaration
1373 __attributeDeclaration = None
1374
1375
1378
1393
1394 @classmethod
1403
1404
1405 @classmethod
1407 """Create an Attribute Use from the given DOM node.
1408
1409 wxs is a Schema instance within which the attribute use is
1410 being defined.
1411
1412 node is a DOM element. The name must be 'attribute', and the
1413 node must be in the XMLSchema namespace.
1414
1415 scope is the _ScopeDeclaration_mixin context into which any
1416 required anonymous attribute declaration is put. This must be
1417 a complex type definition, or None if this use is in an
1418 attribute group.
1419 """
1420
1421 scope = kw['scope']
1422 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1423 assert xsd.nodeIsNamed(node, 'attribute')
1424 schema = kw['schema']
1425 rv = cls(node=node, **kw)
1426
1427 rv.__use = cls.USE_optional
1428 use = NodeAttribute(node, 'use')
1429 if use is not None:
1430 if 'required' == use:
1431 rv.__use = cls.USE_required
1432 elif 'optional' == use:
1433 rv.__use = cls.USE_optional
1434 elif 'prohibited' == use:
1435 rv.__use = cls.USE_prohibited
1436 else:
1437 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1438
1439 rv._valueConstraintFromDOM(node)
1440
1441 rv.__refAttribute = NodeAttribute(node, 'ref')
1442 if rv.__refAttribute is None:
1443
1444 kw.pop('node', None)
1445 kw['owner'] = rv
1446 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1447 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1448
1449 if not rv.isResolved():
1450 rv._queueForResolution('creation')
1451
1452 return rv
1453
1456
1468
1469
1471 """Attribute uses require their declarations, but only if lax."""
1472 if not include_lax:
1473 return frozenset()
1474 return frozenset([ self.attributeDeclaration() ])
1475
1476
1496
1499
1500
1501 -class ElementDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1502 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1503
1504
1505 __typeDefinition = None
1507 """The simple or complex type to which the element value conforms."""
1508 return self.__typeDefinition
1512
1513 __nillable = False
1515
1516 __identityConstraintDefinitions = None
1520
1521 __substitutionGroupAffiliation = None
1525
1526 SGE_none = 0
1527 SGE_extension = 0x01
1528 SGE_restriction = 0x02
1529 SGE_substitution = 0x04
1530
1531 _SGE_Map = { 'extension' : SGE_extension
1532 , 'restriction' : SGE_restriction }
1533 _DS_Map = _SGE_Map.copy()
1534 _DS_Map.update( { 'substitution' : SGE_substitution } )
1535
1536
1537 __substitutionGroupExclusions = SGE_none
1538
1539
1540 __disallowedSubstitutions = SGE_none
1541
1542 __abstract = False
1544
1546 """Return the plurality information for this component.
1547
1548 An ElementDeclaration produces one instance of a single element."""
1549 return _PluralityData(self)
1550
1552 """Return False, since element declarations are not wildcards."""
1553 return False
1554
1555
1557 """Element declarations depend on the type definition of their
1558 content."""
1559 return frozenset([self.__typeDefinition])
1560
1563
1564
1565 @classmethod
1567 """Create an element declaration from the given DOM node.
1568
1569 wxs is a Schema instance within which the element is being
1570 declared.
1571
1572 scope is the _ScopeDeclaration_mixin context into which the
1573 element declaration is recorded. It can be SCOPE_global, a
1574 complex type definition, or None in the case of elements
1575 declared in a named model group.
1576
1577 node is a DOM element. The name must be 'element', and the
1578 node must be in the XMLSchema namespace."""
1579
1580 scope = kw['scope']
1581 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1582
1583
1584 assert xsd.nodeIsNamed(node, 'element')
1585
1586
1587 name = NodeAttribute(node, 'name')
1588 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1589 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1590 elif NodeAttribute(node, 'ref') is None:
1591
1592 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1593 else:
1594 raise pyxb.SchemaValidationError('Created reference as element declaration')
1595
1596 rv = cls(name=name, node=node, **kw)
1597 rv._annotationFromDOM(node)
1598 rv._valueConstraintFromDOM(node)
1599
1600 rv.__substitutionGroupAttribute = NodeAttribute(node, 'substitutionGroup')
1601
1602 kw.pop('node', None)
1603 kw['owner'] = rv
1604
1605 identity_constraints = []
1606 for cn in node.childNodes:
1607 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1608 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1609 rv.__identityConstraintDefinitions = identity_constraints
1610
1611 rv.__typeDefinition = None
1612 rv.__typeAttribute = NodeAttribute(node, 'type')
1613 simpleType_node = LocateUniqueChild(node, 'simpleType')
1614 complexType_node = LocateUniqueChild(node, 'complexType')
1615 if rv.__typeAttribute is not None:
1616 if (simpleType_node is not None) and (complexType_node is not None):
1617 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1618 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1619 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw)
1620 if (rv.__typeDefinition is None) and (complexType_node is not None):
1621 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw)
1622 if rv.__typeDefinition is None:
1623 if rv.__typeAttribute is None:
1624
1625 for cn in node.childNodes:
1626 if Particle.IsParticleNode(cn):
1627 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1628 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition()
1629 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1630 if not rv.__isResolved:
1631 rv._queueForResolution('creation')
1632
1633 attr_val = NodeAttribute(node, 'nillable')
1634 if attr_val is not None:
1635 rv.__nillable = datatypes.boolean(attr_val)
1636
1637 attr_val = NodeAttribute(node, 'abstract')
1638 if attr_val is not None:
1639 rv.__abstract = datatypes.boolean(attr_val)
1640
1641 schema = kw['schema']
1642 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1643 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1644
1645 return rv
1646
1648 """Determine whether this element declaration is adaptable.
1649
1650 OK, this gets ugly. First, if this declaration isn't resolved, it's
1651 clearly not adaptable.
1652
1653 Now: For it to be adaptable, we must know enough about its type to
1654 verify that it is derivation-consistent with any other uses of the
1655 same name in the same complex type. If the element's type is
1656 resolved, that's good enough.
1657
1658 If the element's type isn't resolved, we're golden as long as
1659 type-equivalent types were used. But it's also allowed for the
1660 derived ctd to use the element name constraining it to a derivation of
1661 the element base type. (Go see namespace
1662 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1663 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1664 have to have the element's type resolved.
1665
1666 Except that if a CTD's content incorporates an element with the same
1667 type as the CTD (i.e., nested), this will never happen, because the
1668 CTD can't get resolved until after it has been resolved.
1669 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1670 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1671 an example).
1672
1673 So, we give the world a break and assume that if the type we're trying
1674 to resolve is the same as the type of an element in that type, then
1675 the element type will be resolved by the point it's needed. In point
1676 of fact, it won't, but we'll only notice that if a CTD contains an
1677 element whose type is a restriction of the CTD. In that case,
1678 isDerivationConsistent will blow chunks and somebody'll have to come
1679 back and finish up this mess.
1680 """
1681
1682 if not self.isResolved():
1683 return False
1684 if self.typeDefinition().isResolved():
1685 return True
1686
1687
1688 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1689 if existing_decl is None:
1690
1691
1692 return True
1693
1694 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1695
1696 return True
1697
1698
1699 print 'WARNING: Require %s to be resolved; might be a loop.' % (self.typeDefinition(),)
1700 return False
1701
1702
1713
1714 __isResolved = False
1717
1718
1741
1746
1747
1748 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1749 __PrivateTransient = set()
1750
1751
1752 __baseTypeDefinition = None
1756
1757 DM_empty = 0
1758 DM_extension = 0x01
1759 DM_restriction = 0x02
1760
1761 _DM_Map = { 'extension' : DM_extension
1762 , 'restriction' : DM_restriction }
1763
1764
1765
1766 __derivationMethod = None
1770
1771
1772 __final = DM_empty
1773
1774
1775 __abstract = False
1777
1778
1779 __attributeUses = None
1781 """A frozenset() of AttributeUse instances."""
1782 return self.__attributeUses
1783
1784
1785
1786 __scopedAttributeDeclarations = None
1794
1795
1796
1797 __scopedElementDeclarations = None
1805
1806 __localScopedDeclarations = None
1808 """Return a list of element and attribute declarations that were
1809 introduced in this definition (i.e., their scope is this CTD).
1810
1811 @note: This specifically returns a list, with element declarations
1812 first, because name binding should privilege the elements over the
1813 attributes. Within elements and attributes, the components are sorted
1814 by expanded name, to ensure consistency across a series of binding
1815 generations.
1816
1817 @keyword reset: If C{False} (default), a cached previous value (if it
1818 exists) will be returned.
1819 """
1820 if reset or (self.__localScopedDeclarations is None):
1821 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1822 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1823 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1824 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1825 self.__localScopedDeclarations = rve
1826 self.__localScopedDeclarations.extend(rva)
1827 return self.__localScopedDeclarations
1828
1830 """Record the given declaration as being locally scoped in
1831 this type."""
1832 assert isinstance(decl, _ScopedDeclaration_mixin)
1833 if isinstance(decl, ElementDeclaration):
1834 scope_map = self.__scopedElementDeclarations
1835 elif isinstance(decl, AttributeDeclaration):
1836 scope_map = self.__scopedAttributeDeclarations
1837 else:
1838 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1839 decl_en = decl.expandedName()
1840 existing_decl = scope_map.setdefault(decl_en, decl)
1841 if decl != existing_decl:
1842 if isinstance(decl, ElementDeclaration):
1843
1844 existing_type = existing_decl.typeDefinition()
1845 pending_type = decl.typeDefinition()
1846 if not pending_type.isDerivationConsistent(existing_type):
1847 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1848 elif isinstance(decl, AttributeDeclaration):
1849 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1850 else:
1851 assert False, 'Unrecognized type %s' % (type(decl),)
1852 decl._baseDeclaration(existing_decl)
1853 return self
1854
1860
1861 CT_EMPTY = 'EMPTY'
1862 CT_SIMPLE = 'SIMPLE'
1863 CT_MIXED = 'MIXED'
1864 CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1865
1866 - def _contentTypeTag (self):
1867 """Return the value of the content type identifier, i.e. one of the
1868 CT_ constants. Return value is None if no content type has been
1869 defined."""
1870 if isinstance(self.__contentType, tuple):
1871 return self.__contentType[0]
1872 return self.__contentType
1873
1875 if isinstance(self.__contentType, tuple):
1876 return self.__contentType[1]
1877 return None
1878
1879
1880 __contentType = None
1881 - def contentType (self):
1882 """Identify the sort of content in this type.
1883
1884 Valid values are:
1885 - C{CT_EMPTY}
1886 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1887 - ( C{CT_MIXED}, a L{Particle} instance )
1888 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1889 """
1890 return self.__contentType
1891
1893 if self.CT_EMPTY == self.contentType():
1894 return 'EMPTY'
1895 ( tag, particle ) = self.contentType()
1896 if self.CT_SIMPLE == tag:
1897 return 'Simple [%s]' % (particle,)
1898 if self.CT_MIXED == tag:
1899 return 'Mixed [%s]' % (particle,)
1900 if self.CT_ELEMENT_ONLY == tag:
1901 return 'Element [%s]' % (particle,)
1902 raise pyxb.LogicError('Unhandled content type')
1903
1904
1905 __prohibitedSubstitutions = DM_empty
1906
1907
1908 __annotations = None
1909
1915
1925
1927 """Override fields in this instance with those from the other.
1928
1929 This method is invoked only by Schema._addNamedComponent, and
1930 then only when a built-in type collides with a schema-defined
1931 type. Material like facets is not (currently) held in the
1932 built-in copy, so the DOM information is copied over to the
1933 built-in STD, which is subsequently re-resolved.
1934
1935 Returns self.
1936 """
1937 assert self != other
1938 assert self.isNameEquivalent(other)
1939 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1940
1941 if not other.isResolved():
1942 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1943 self.__derivationMethod = None
1944
1945 return self
1946
1947 __UrTypeDefinition = None
1948 @classmethod
1950 """Create the ComplexTypeDefinition instance that approximates
1951 the ur-type.
1952
1953 See section 3.4.7.
1954 """
1955
1956
1957
1958
1959
1960
1961
1962 if cls.__UrTypeDefinition is None:
1963
1964 assert schema is not None
1965
1966 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1967
1968 kw = { 'name' : 'anyType',
1969 'schema' : schema,
1970 'namespace_context' : ns_ctx,
1971 'binding_namespace' : schema.targetNamespace(),
1972 'derivation_method' : cls.DM_restriction,
1973 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1974 bi = _UrTypeDefinition(**kw)
1975
1976
1977 bi.__baseTypeDefinition = bi
1978
1979
1980 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1981
1982
1983
1984
1985
1986
1987 kw = { 'namespace_context' : ns_ctx
1988 , 'schema' : schema
1989 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
1990 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
1991 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
1992 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
1993 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
1994
1995
1996 bi.__attributeUses = set()
1997
1998
1999 bi.__final = cls.DM_empty
2000 bi.__prohibitedSubstitutions = cls.DM_empty
2001
2002 bi.__abstract = False
2003
2004
2005 bi.setNameInBinding(bi.name())
2006
2007
2008 bi.__derivationMethod = cls.DM_restriction
2009
2010 cls.__UrTypeDefinition = bi
2011 return cls.__UrTypeDefinition
2012
2014 """Indicate whether this simple type is a built-in type."""
2015 return (self.UrTypeDefinition() == self)
2016
2017
2033
2034
2035 @classmethod
2059
2060 __ckw = None
2061 __anyAttribute = None
2062 __attributeGroupAttributes = None
2063 __usesC1 = None
2064 __usesC1C2 = None
2065 __attributeGroups = None
2066 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2067
2068
2070
2071 if self.__usesC1C2 is None:
2072
2073 uses_c1 = self.__usesC1
2074 uses_c2 = set()
2075 self.__attributeGroups = []
2076 for ag_attr in self.__attributeGroupAttributes:
2077 ag_en = self._namespaceContext().interpretQName(ag_attr)
2078 agd = ag_en.attributeGroupDefinition()
2079 if agd is None:
2080 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2081 if not agd.isResolved():
2082 self._queueForResolution('unresolved attribute group', depends_on=agd)
2083 return self
2084 self.__attributeGroups.append(agd)
2085 uses_c2.update(agd.attributeUses())
2086
2087 uses_c1c2 = uses_c1.union(uses_c2)
2088 for au in uses_c1c2:
2089 if not au.isResolved():
2090 self._queueForResolution('attribute use not resolved')
2091 return self
2092 ad = au.attributeDeclaration()
2093 if not ad.isResolved():
2094 ad_en = ad.expandedName()
2095 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2096 return self
2097
2098 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2099
2100
2101
2102
2103
2104
2105 uses_c3 = set()
2106 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2107
2108
2109 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2110 assert self.__baseTypeDefinition.isResolved()
2111 for au in uses_c3:
2112 if not au.isResolved():
2113 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2114 return self
2115 ad = au.attributeDeclaration()
2116 if not ad.isResolved():
2117 ad_en = ad.expandedName()
2118 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2119 return self
2120 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2121
2122 if self.DM_restriction == method:
2123
2124
2125
2126 for au in self.__usesC1C2:
2127 matching_uses = au.matchingQNameMembers(uses_c3)
2128 assert matching_uses is not None
2129 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2130 for au2 in matching_uses:
2131 assert au2.isResolved()
2132 uses_c3.remove(au2)
2133 au._setRestrictionOf(au2)
2134 else:
2135
2136
2137
2138 assert self.DM_extension == method
2139
2140 use_map = { }
2141 for au in self.__usesC1C2.union(uses_c3):
2142 assert au.isResolved()
2143 ad_en = au.attributeDeclaration().expandedName()
2144 if ad_en in use_map:
2145 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2146 use_map[ad_en] = au
2147
2148
2149
2150 self.__attributeUses = frozenset(use_map.values())
2151 if not self._scopeIsIndeterminate():
2152 for au in self.__attributeUses:
2153 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2154
2155
2156
2157 local_wildcard = None
2158 if self.__anyAttribute is not None:
2159 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2160
2161
2162 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2163
2164
2165 if self.DM_restriction == method:
2166
2167 self._setAttributeWildcard(complete_wildcard)
2168 else:
2169 assert (self.DM_extension == method)
2170 assert self.baseTypeDefinition().isResolved()
2171
2172 base_wildcard = None
2173 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2174 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2175
2176 if base_wildcard is not None:
2177 if complete_wildcard is None:
2178
2179 self._setAttributeWildcard(base_wildcard)
2180 else:
2181
2182 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2183 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2184 base_wildcard.namespaceConstraint()]),
2185 annotation=complete_wildcard.annotation(),
2186 namespace_context=self._namespaceContext()))
2187 else:
2188
2189 self._setAttributeWildcard(complete_wildcard)
2190
2191
2192
2193
2194 del self.__usesC1
2195 del self.__usesC1C2
2196 del self.__attributeGroups
2197 self.__ckw = None
2198
2199
2200
2201
2202 self.__derivationMethod = method
2203 return self
2204
2205 - def __simpleContent (self, method, **kw):
2206
2207 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2208
2209 parent_content_type = self.__baseTypeDefinition.__contentType
2210
2211 if ((type(parent_content_type) == tuple) \
2212 and (self.CT_SIMPLE == parent_content_type[0]) \
2213 and (self.DM_restriction == method)):
2214
2215 assert self.__ctscRestrictionNode is not None
2216 std = self.__ctscClause2STD
2217 if std is None:
2218 std = parent_content_type[1]
2219 assert isinstance(std, SimpleTypeDefinition)
2220 if not std.isResolved():
2221 return None
2222 restriction_node = self.__ctscRestrictionNode
2223 self.__ctscClause2STD = None
2224 self.__ctscRestrictionNode = None
2225 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2226 elif ((type(parent_content_type) == tuple) \
2227 and (self.CT_MIXED == parent_content_type[0]) \
2228 and parent_content_type[1].isEmptiable()):
2229
2230 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2231 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2232 else:
2233
2234 return parent_content_type
2235 else:
2236
2237 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2238 assert False
2239
2240 __ctscClause2STD = None
2241 __ctscRestrictioNode = None
2242
2243 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2244
2245
2246 ckw = kw.copy()
2247 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2248
2249
2250 mixed_attr = None
2251 if content_node is not None:
2252 mixed_attr = NodeAttribute(content_node, 'mixed')
2253 if mixed_attr is None:
2254 mixed_attr = NodeAttribute(type_node, 'mixed')
2255 if mixed_attr is not None:
2256 effective_mixed = datatypes.boolean(mixed_attr)
2257 else:
2258 effective_mixed = False
2259
2260
2261 case_2_1_predicate_count = 0
2262 test_2_1_1 = True
2263 test_2_1_2 = False
2264 test_2_1_3 = False
2265 typedef_node = None
2266 for cn in definition_node_list:
2267 if Node.ELEMENT_NODE != cn.nodeType:
2268 continue
2269 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2270
2271 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2272 if Particle.IsTypedefNode(cn):
2273 typedef_node = cn
2274 test_2_1_1 = False
2275 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2276 and (not HasNonAnnotationChild(cn)):
2277 test_2_1_2 = True
2278 if xsd.nodeIsNamed(cn, 'choice') \
2279 and (not HasNonAnnotationChild(cn)):
2280 mo_attr = NodeAttribute(cn, 'minOccurs')
2281 if ((mo_attr is not None) \
2282 and (0 == datatypes.integer(mo_attr))):
2283 test_2_1_3 = True
2284 satisfied_predicates = 0
2285 if test_2_1_1:
2286 satisfied_predicates += 1
2287 if test_2_1_2:
2288 satisfied_predicates += 1
2289 if test_2_1_3:
2290 satisfied_predicates += 1
2291 if 1 == satisfied_predicates:
2292 if effective_mixed:
2293
2294 assert (typedef_node is None) or test_2_1_2
2295 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2296 effective_content = Particle(m, **ckw)
2297 else:
2298
2299 effective_content = self.CT_EMPTY
2300 else:
2301
2302 assert typedef_node is not None
2303 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2304
2305
2306
2307
2308
2309
2310
2311 self.__effectiveMixed = effective_mixed
2312 self.__effectiveContent = effective_content
2313 self.__ckw = ckw
2314
2315
2316
2317
2318 - def __complexContent (self, method):
2319 ckw = self.__ckw
2320
2321
2322 if self.__effectiveMixed:
2323 ct = self.CT_MIXED
2324 else:
2325 ct = self.CT_ELEMENT_ONLY
2326
2327 if self.DM_restriction == method:
2328
2329 if self.CT_EMPTY == self.__effectiveContent:
2330
2331 content_type = self.CT_EMPTY
2332 else:
2333
2334 content_type = ( ct, self.__effectiveContent )
2335 assert 0 == len(self.__scopedElementDeclarations)
2336
2337
2338
2339
2340 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2341 else:
2342
2343 assert self.DM_extension == method
2344 assert self.__baseTypeDefinition.isResolved()
2345 parent_content_type = self.__baseTypeDefinition.contentType()
2346 if self.CT_EMPTY == self.__effectiveContent:
2347 content_type = parent_content_type
2348 elif self.CT_EMPTY == parent_content_type:
2349
2350 content_type = ( ct, self.__effectiveContent )
2351 else:
2352 assert type(parent_content_type) == tuple
2353 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2354 content_type = ( ct, Particle(m, **ckw) )
2355
2356 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2357 return content_type
2358
2360 """Indicate whether this complex type is fully defined.
2361
2362 All built-in type definitions are resolved upon creation.
2363 Schema-defined type definitionss are held unresolved until the
2364 schema has been completely read, so that references to later
2365 schema-defined types can be resolved. Resolution is performed
2366 after the entire schema has been scanned and type-definition
2367 instances created for all topLevel{Simple,Complex}Types.
2368
2369 If a built-in type definition is also defined in a schema
2370 (which it should be), the built-in definition is kept, with
2371 the schema-related information copied over from the matching
2372 schema-defined type definition. The former then replaces the
2373 latter in the list of type definitions to be resolved. See
2374 Schema._addNamedComponent.
2375 """
2376
2377 return (self.__derivationMethod is not None)
2378
2379
2380
2384
2385 - def __setContentFromDOM (self, node, **kw):
2386 schema = kw.get('schema')
2387 assert schema is not None
2388 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2389 self.__final = schema.finalForNode(node, self._DM_Map)
2390
2391 attr_val = NodeAttribute(node, 'abstract')
2392 if attr_val is not None:
2393 self.__abstract = datatypes.boolean(attr_val)
2394
2395
2396
2397 definition_node_list = node.childNodes
2398 is_complex_content = True
2399 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2400 method = self.DM_restriction
2401
2402
2403
2404
2405 first_elt = LocateFirstChildElement(node)
2406 content_node = None
2407 clause2_std = None
2408 ctsc_restriction_node = None
2409 if first_elt:
2410 have_content = False
2411 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2412 have_content = True
2413 is_complex_content = False
2414 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2415 have_content = True
2416 else:
2417
2418
2419 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2420 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2421 if have_content:
2422
2423 content_node = LocateFirstChildElement(node, require_unique=True)
2424 assert content_node == first_elt
2425
2426
2427
2428 ions = LocateFirstChildElement(content_node, absent_ok=False)
2429 if xsd.nodeIsNamed(ions, 'restriction'):
2430 method = self.DM_restriction
2431 if not is_complex_content:
2432
2433 ctsc_restriction_node = ions
2434 ions_st = LocateUniqueChild(ions,'simpleType')
2435 if ions_st is not None:
2436 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2437 elif xsd.nodeIsNamed(ions, 'extension'):
2438 method = self.DM_extension
2439 else:
2440 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2441 self.__baseAttribute = NodeAttribute(ions, 'base')
2442 if self.__baseAttribute is None:
2443 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2444 self.__baseTypeDefinition = None
2445
2446 definition_node_list = ions.childNodes
2447
2448 self.__pendingDerivationMethod = method
2449 self.__isComplexContent = is_complex_content
2450 self.__ctscRestrictionNode = ctsc_restriction_node
2451 self.__ctscClause2STD = clause2_std
2452
2453 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2454 self.__usesC1 = set()
2455 for cn in attributes:
2456 au = AttributeUse.CreateFromDOM(cn, **kw)
2457 self.__usesC1.add(au)
2458 self.__attributeGroupAttributes = attribute_group_attrs
2459 self.__anyAttribute = any_attribute
2460
2461 if self.__isComplexContent:
2462 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2463
2464
2465
2466 self._annotationFromDOM(node)
2467
2468 if not self.isResolved():
2469 self._queueForResolution('creation')
2470
2471 return self
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2538
2540 """Complex type definitions have no built-in type support."""
2541 return None
2542
2547
2549 """Subclass ensures there is only one ur-type."""
2551 """The ur-type does have a Python class backing it up."""
2552 return datatypes.anyType
2553
2558
2559
2560 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2561 """An XMLSchema U{Attribute Group Definition<http://www.w3.org/TR/xmlschema-1/#cAttribute_Group_Definitions>} component."""
2562 __PrivateTransient = set()
2563
2564
2565 __attributeUses = None
2566
2569
2570
2571
2574
2575 @classmethod
2586
2587 __anyAttribute = None
2588 __attributeGroupAttributes = None
2589 __PrivateTransient.update(['anyAttribute', 'attributeGroupAttributes'])
2590
2591
2592 @classmethod
2630
2631
2632 __isResolved = False
2635
2660
2661
2663 """Attribute group declarations require their uses, but only if lax."""
2664 if not include_lax:
2665 return frozenset()
2666 return frozenset(self.attributeUses())
2667
2670
2672 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2673
2674 __modelGroup = None
2675
2677 """The model group for which this definition provides a name."""
2678 return self.__modelGroup
2679
2680
2681 @classmethod
2683 """Create a Model Group Definition from a DOM element node.
2684
2685 wxs is a Schema instance within which the model group is being
2686 defined.
2687
2688 node is a DOM element. The name must be 'group', and the node
2689 must be in the XMLSchema namespace. The node must have a
2690 'name' attribute, and must not have a 'ref' attribute.
2691 """
2692 assert xsd.nodeIsNamed(node, 'group')
2693
2694 assert NodeAttribute(node, 'ref') is None
2695
2696 name = NodeAttribute(node, 'name')
2697 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2698 rv = cls(name=name, node=node, **kw)
2699 rv._annotationFromDOM(node)
2700
2701 kw.pop('node', None)
2702 kw['owner'] = rv
2703
2704 for cn in node.childNodes:
2705 if Node.ELEMENT_NODE != cn.nodeType:
2706 continue
2707 if ModelGroup.IsGroupMemberNode(cn):
2708 assert not rv.__modelGroup
2709
2710
2711
2712 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2713 assert rv.__modelGroup is not None
2714 return rv
2715
2716
2718 """Model group definitions depend on the contained model group."""
2719 if not include_lax:
2720 return frozenset()
2721 return frozenset([self.__modelGroup])
2722
2725
2726
2727 -class ModelGroup (_SchemaComponent_mixin, _Annotated_mixin):
2728 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2729 C_INVALID = 0
2730 C_ALL = 0x01
2731 C_CHOICE = 0x02
2732 C_SEQUENCE = 0x03
2733
2734
2735
2736 __compositor = C_INVALID
2738
2739 @classmethod
2749
2753
2754
2755
2756 __particles = None
2757 - def particles (self): return self.__particles
2758
2760 """A model group has an unresolvable particle if any of its
2761 particles is unresolvable. Duh."""
2762 for p in self.particles():
2763 if not p.isAdaptable(ctd):
2764 return False
2765 return True
2766
2768 """Return the minimum and maximum of the number of elements that can
2769 appear in a sequence matched by this particle.
2770
2771 See http://www.w3.org/TR/xmlschema-1/#cos-seq-range
2772 """
2773 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2774 sum_minoccurs = 0
2775 sum_maxoccurs = 0
2776 for prt in self.__particles:
2777 (prt_min, prt_max) = prt.effectiveTotalRange()
2778 sum_minoccurs += prt_min
2779 if sum_maxoccurs is not None:
2780 if prt_max is None:
2781 sum_maxoccurs = None
2782 else:
2783 sum_maxoccurs += prt_max
2784 prod_maxoccurs = particle.maxOccurs()
2785 if prod_maxoccurs is not None:
2786 if sum_maxoccurs is None:
2787 prod_maxoccurs = None
2788 else:
2789 prod_maxoccurs *= sum_maxoccurs
2790 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2791 assert self.__compositor == self.C_CHOICE
2792 if 0 == len(self.__particles):
2793 min_minoccurs = 0
2794 max_maxoccurs = 0
2795 else:
2796 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2797 for prt in self.__particles[1:]:
2798 (prt_min, prt_max) = prt.effectiveTotalRange()
2799 if prt_min < min_minoccurs:
2800 min_minoccurs = prt_min
2801 if prt_max is None:
2802 max_maxoccurs = None
2803 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2804 max_maxoccurs = prt_max
2805 min_minoccurs *= particle.minOccurs()
2806 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2807 max_maxoccurs *= particle.maxOccurs()
2808 return (min_minoccurs, max_maxoccurs)
2809
2810
2811
2812
2813 __modelGroupDefinition = None
2815 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2816 return self.__modelGroupDefinition
2817
2818 - def __init__ (self, compositor, particles, *args, **kw):
2819 """Create a new model group.
2820
2821 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2822
2823 particles must be a list of zero or more Particle instances.
2824
2825 scope is the _ScopeDeclaration_mixin context into which new
2826 declarations are recorded. It can be SCOPE_global, a complex
2827 type definition, or None if this is (or is within) a named
2828 model group.
2829
2830 model_group_definition is an instance of ModelGroupDefinition
2831 if this is a named model group. It defaults to None
2832 indicating a local group.
2833 """
2834
2835 super(ModelGroup, self).__init__(*args, **kw)
2836 assert 'scope' in kw
2837 self.__compositor = compositor
2838
2839 self.__particles = particles
2840 self.__modelGroupDefinition = kw.get('model_group_definition')
2841
2843 """Get the plurality data for this model group.
2844 """
2845 return _PluralityData(self)
2846
2848 """Return True if the model includes a wildcard amongst its particles."""
2849 for p in self.particles():
2850 if p.hasWildcardElement():
2851 return True
2852 return False
2853
2854
2856 if not include_lax:
2857 return frozenset()
2858 return frozenset(self.__particles)
2859
2860
2861 @classmethod
2863 """Create a model group from the given DOM node.
2864
2865 wxs is a Schema instance within which the model group is being
2866 defined.
2867
2868 node is a DOM element. The name must be one of ( 'all',
2869 'choice', 'sequence' ), and the node must be in the XMLSchema
2870 namespace.
2871
2872 scope is the _ScopeDeclaration_mxin context that is assigned
2873 to declarations that appear within the model group. It can be
2874 None, indicating no scope defined, or a complex type
2875 definition.
2876 """
2877
2878 scope = kw['scope']
2879 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2880
2881 if xsd.nodeIsNamed(node, 'all'):
2882 compositor = cls.C_ALL
2883 elif xsd.nodeIsNamed(node, 'choice'):
2884 compositor = cls.C_CHOICE
2885 elif xsd.nodeIsNamed(node, 'sequence'):
2886 compositor = cls.C_SEQUENCE
2887 else:
2888 raise pyxb.IncompleteImplementationError('ModelGroup: Got unexpected %s' % (node.nodeName,))
2889 particles = []
2890
2891 kw.pop('owner', None)
2892 for cn in node.childNodes:
2893 if Node.ELEMENT_NODE != cn.nodeType:
2894 continue
2895 if Particle.IsParticleNode(cn):
2896
2897 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2898 elif not xsd.nodeIsNamed(cn, 'annotation'):
2899 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2900 rv = cls(compositor, particles, node=node, **kw)
2901 for p in particles:
2902 p._setOwner(rv)
2903 rv._annotationFromDOM(node)
2904 return rv
2905
2906 @classmethod
2908 return xsd.nodeIsNamed(node, 'all', 'choice', 'sequence')
2909
2911 """Return a list of all ElementDeclarations that are at the
2912 top level of this model group, in the order in which they can
2913 occur."""
2914 element_decls = []
2915 model_groups = [ self ]
2916
2917 while model_groups:
2918 mg = model_groups.pop(0)
2919 for p in mg.particles():
2920 if isinstance(p.term(), ModelGroup):
2921 model_groups.append(p.term())
2922 elif isinstance(p.term(), ElementDeclaration):
2923 element_decls.extend(p.elementDeclarations())
2924 else:
2925 assert p.term() is not None
2926 pass
2927
2928
2929 return element_decls
2930
2931
2943
2953
2954 -class Particle (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2955 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2956
2957
2958 __minOccurs = 1
2959 - def minOccurs (self):
2960 """The minimum number of times the term may appear.
2961
2962 Defaults to 1."""
2963 return self.__minOccurs
2964
2965
2966 __maxOccurs = 1
2967 - def maxOccurs (self):
2968 """Upper limit on number of times the term may appear.
2969
2970 If None, the term may appear any number of times; otherwise,
2971 this is an integral value indicating the maximum number of times
2972 the term may appear. The default value is 1; the value, unless
2973 None, must always be at least minOccurs().
2974 """
2975 return self.__maxOccurs
2976
2977
2978 __term = None
2980 """A reference to a ModelGroup, Wildcard, or ElementDeclaration."""
2981 return self.__term
2982 __pendingTerm = None
2983
2985 assert self.__term is not None
2986 if isinstance(self.__term, ModelGroup):
2987 return self.__term.elementDeclarations()
2988 if isinstance(self.__term, ElementDeclaration):
2989 return [ self.__term ]
2990 if isinstance(self.__term, Wildcard):
2991 return [ ]
2992 raise pyxb.LogicError('Unexpected term type %s' % (self.__term,))
2993
2994 - def pluralityData (self):
2995 """Return the plurality data for this component.
2996
2997 The plurality data for a particle is the plurality data for
2998 its term, with the counts scaled by the effect of
2999 maxOccurs."""
3000 return _PluralityData(self)
3001
3003 """Extend the concept of effective total range to all particles.
3004
3005 See http://www.w3.org/TR/xmlschema-1/#cos-seq-range
3006 """
3007 if isinstance(self.__term, ModelGroup):
3008 return self.__term.effectiveTotalRange(self)
3009 return (self.minOccurs(), self.maxOccurs())
3010
3011 - def isEmptiable (self):
3012 """Return C{True} iff this particle can legitimately match an empty
3013 sequence (no content).
3014
3015 See http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable.
3016 """
3017 return 0 == self.effectiveTotalRange()[0]
3018
3020 """Return True iff this particle has a wildcard in its term.
3021
3022 Note that the wildcard may be in a nested model group."""
3023 return self.term().hasWildcardElement()
3024
3025 - def __init__ (self, term, *args, **kw):
3026 """Create a particle from the given DOM node.
3027
3028 term is a XML Schema Component: one of ModelGroup,
3029 ElementDeclaration, and Wildcard.
3030
3031 The following keyword arguments are processed:
3032
3033 min_occurs is a non-negative integer value with default 1,
3034 denoting the minimum number of terms required by the content
3035 model.
3036
3037 max_occurs is a positive integer value with default 1, or None
3038 indicating unbounded, denoting the maximum number of terms
3039 allowed by the content model.
3040
3041 scope is the _ScopeDeclaration_mxin context that is assigned
3042 to declarations that appear within the particle. It can be
3043 None, indicating no scope defined, or a complex type
3044 definition.
3045 """
3046
3047 super(Particle, self).__init__(*args, **kw)
3048
3049 min_occurs = kw.get('min_occurs', 1)
3050 max_occurs = kw.get('max_occurs', 1)
3051
3052 assert 'scope' in kw
3053 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
3054
3055 if term is not None:
3056 self.__term = term
3057
3058 assert isinstance(min_occurs, (types.IntType, types.LongType))
3059 self.__minOccurs = min_occurs
3060 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
3061 self.__maxOccurs = max_occurs
3062 if self.__maxOccurs is not None:
3063 if self.__minOccurs > self.__maxOccurs:
3064 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3065
3066
3067 - def _resolve (self):
3068 if self.isResolved():
3069 return self
3070 scope = self._scope()
3071
3072
3073 if ModelGroup == self.__resolvableType:
3074 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3075 group_decl = ref_en.modelGroupDefinition()
3076 if group_decl is None:
3077 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
3078
3079 self.__pendingTerm = group_decl.modelGroup()
3080 assert self.__pendingTerm is not None
3081 elif ElementDeclaration == self.__resolvableType:
3082
3083
3084
3085 if self.__refAttribute is not None:
3086 assert self.__pendingTerm is None
3087 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3088 self.__pendingTerm = ref_en.elementDeclaration()
3089 if self.__pendingTerm is None:
3090 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3091 assert self.__pendingTerm is not None
3092
3093
3094
3095
3096 assert self.__pendingTerm is not None
3097 else:
3098 assert False
3099
3100 self.__term = self.__pendingTerm
3101 assert self.__term is not None
3102 return self
3103
3104 - def isResolved (self):
3105 return self.__term is not None
3106
3107
3108 @classmethod
3109 - def CreateFromDOM (cls, node, **kw):
3110 """Create a particle from the given DOM node.
3111
3112 wxs is a Schema instance within which the model group is being
3113 defined.
3114
3115 node is a DOM element. The name must be one of ( 'group',
3116 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3117 must be in the XMLSchema namespace.
3118
3119 scope is the _ScopeDeclaration_mxin context that is assigned
3120 to declarations that appear within the model group. It can be
3121 None, indicating no scope defined, or a complex type
3122 definition.
3123 """
3124 scope = kw['scope']
3125 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3126
3127 kw.update({ 'min_occurs' : 1
3128 , 'max_occurs' : 1
3129 , 'node' : node })
3130
3131 if not Particle.IsParticleNode(node):
3132 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3133 attr_val = NodeAttribute(node, 'minOccurs')
3134 if attr_val is not None:
3135 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3136 attr_val = NodeAttribute(node, 'maxOccurs')
3137 if attr_val is not None:
3138 if 'unbounded' == attr_val:
3139 kw['max_occurs'] = None
3140 else:
3141 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3142
3143 rv = cls(None, **kw)
3144
3145 kw.pop('node', None)
3146 kw['owner'] = rv
3147
3148 rv.__refAttribute = NodeAttribute(node, 'ref')
3149 rv.__pendingTerm = None
3150 rv.__resolvableType = None
3151 if xsd.nodeIsNamed(node, 'group'):
3152
3153
3154
3155 if rv.__refAttribute is None:
3156 raise pyxb.SchemaValidationError('group particle without reference')
3157 rv.__resolvableType = ModelGroup
3158 elif xsd.nodeIsNamed(node, 'element'):
3159 if rv.__refAttribute is None:
3160 schema = kw.get('schema')
3161 assert schema is not None
3162 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3163 incoming_tns = kw.get('target_namespace')
3164 if incoming_tns is not None:
3165 assert incoming_tns == target_namespace
3166 else:
3167 kw['target_namespace'] = target_namespace
3168 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3169 else:
3170
3171
3172
3173 rv.__resolvableType = ElementDeclaration
3174 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3175 elif xsd.nodeIsNamed(node, 'any'):
3176
3177 rv.__term = Wildcard.CreateFromDOM(node=node)
3178 elif ModelGroup.IsGroupMemberNode(node):
3179
3180
3181
3182 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3183 else:
3184 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml(),))
3185
3186 if not rv.isResolved():
3187 rv._queueForResolution('creation')
3188 return rv
3189
3190
3191 - def _bindingRequires_vx (self, include_lax):
3192 if not include_lax:
3193 return frozenset()
3194 return frozenset([ self.__term ])
3195
3196
3197 - def _adaptForScope (self, owner, ctd):
3198
3199 rv = self
3200 assert isinstance(ctd, ComplexTypeDefinition)
3201 maybe_rv = self._clone(owner, ctd._objectOrigin())
3202 term = rv.__term._adaptForScope(maybe_rv, ctd)
3203 do_clone = (self._scope() != ctd) or (rv.__term != term)
3204 if do_clone:
3205 rv = maybe_rv
3206 rv.__term = term
3207 return rv
3208
3209 - def isAdaptable (self, ctd):
3210 """A particle has an unresolvable particle if it cannot be
3211 resolved, or if it has resolved to a term which is a model
3212 group that has an unresolvable particle.
3213 """
3214 if not self.isResolved():
3215 return False
3216 return self.term().isAdaptable(ctd)
3217
3218 @classmethod
3219 - def IsTypedefNode (cls, node):
3220 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3221
3222 @classmethod
3223 - def IsParticleNode (cls, node, *others):
3224 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3225
3226 - def __str__ (self):
3227
3228 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3229
3230
3231
3232 -class Wildcard (_SchemaComponent_mixin, _Annotated_mixin):
3233 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3234
3235 NC_any = '##any'
3236 NC_not = '##other'
3237 NC_targetNamespace = '##targetNamespace'
3238 NC_local = '##local'
3239
3240 __namespaceConstraint = None
3242 """A constraint on the namespace for the wildcard.
3243
3244 Valid values are:
3245 - L{Wildcard.NC_any}
3246 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3247 - set(of_namespaces)
3248
3249 Note that namespace are represented by
3250 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3251 actually define a namespace. Absence of a namespace is represented by
3252 C{None}, both in the "not" pair and in the set.
3253 """
3254 return self.__namespaceConstraint
3255
3256 @classmethod
3258 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3259 assert 0 < len(constraints)
3260 o1 = constraints.pop(0);
3261 while 0 < len(constraints):
3262 o2 = constraints.pop(0);
3263
3264 if (o1 == o2):
3265 continue
3266
3267 if (cls.NC_any == o1) or (cls.NC_any == o2):
3268 o1 = cls.NC_any
3269 continue
3270
3271 if isinstance(o1, set) and isinstance(o2, set):
3272 o1 = o1.union(o2)
3273 continue
3274
3275 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3276 o1 = ( cls.NC_not, None )
3277 continue
3278
3279
3280 c_tuple = None
3281 c_set = None
3282 if isinstance(o1, tuple):
3283 assert isinstance(o2, set)
3284 c_tuple = o1
3285 c_set = o2
3286 else:
3287 assert isinstance(o1, set)
3288 assert isinstance(o2, tuple)
3289 c_tuple = o2
3290 c_set = o1
3291 negated_ns = c_tuple[1]
3292 if negated_ns is not None:
3293
3294 if (negated_ns in c_set) and (None in c_set):
3295 o1 = cls.NC_any
3296 continue
3297
3298 if negated_ns in c_set:
3299 o1 = ( cls.NC_not, None )
3300 continue
3301
3302 if None in c_set:
3303 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3304 o1 = c_tuple
3305 continue
3306
3307 if None in c_set:
3308 o1 = cls.NC_any
3309 else:
3310 o1 = ( cls.NC_not, None )
3311 return o1
3312
3313 @classmethod
3315 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3316 assert 0 < len(constraints)
3317 o1 = constraints.pop(0);
3318 while 0 < len(constraints):
3319 o2 = constraints.pop(0);
3320
3321 if (o1 == o2):
3322 continue
3323
3324 if (cls.NC_any == o1) or (cls.NC_any == o2):
3325 if cls.NC_any == o1:
3326 o1 = o2
3327 continue
3328
3329 if isinstance(o1, set) and isinstance(o2, set):
3330 o1 = o1.intersection(o2)
3331 continue
3332 if isinstance(o1, tuple) and isinstance(o2, tuple):
3333 ns1 = o1[1]
3334 ns2 = o2[1]
3335
3336 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3337 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3338
3339 assert (ns1 is None) or (ns2 is None)
3340 if ns1 is None:
3341 assert ns2 is not None
3342 o1 = ( cls.NC_not, ns2 )
3343 else:
3344 assert ns1 is not None
3345 o1 = ( cls.NC_not, ns1 )
3346 continue
3347
3348
3349
3350 c_tuple = None
3351 c_set = None
3352 if isinstance(o1, tuple):
3353 assert isinstance(o2, set)
3354 c_tuple = o1
3355 c_set = o2
3356 else:
3357 assert isinstance(o1, set)
3358 assert isinstance(o2, tuple)
3359 c_tuple = o2
3360 c_set = o1
3361 negated_ns = c_tuple[1]
3362 if negated_ns in c_set:
3363 c_set.remove(negated_ns)
3364 if None in c_set:
3365 c_set.remove(None)
3366 o1 = c_set
3367 return o1
3368
3369 PC_skip = 'skip'
3370 PC_lax = 'lax'
3371 PC_strict = 'strict'
3372
3373
3374 __processContents = None
3376
3378 """Get the plurality data for this wildcard
3379 """
3380 return _PluralityData(self)
3381
3383 """Return True, since Wildcard components are wildcards."""
3384 return True
3385
3391
3394
3395
3397 """Wildcards are scope-independent; return self"""
3398 return self
3399
3400
3401 @classmethod
3403 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3404 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3405 nc = NodeAttribute(node, 'namespace')
3406 if nc is None:
3407 namespace_constraint = cls.NC_any
3408 else:
3409 if cls.NC_any == nc:
3410 namespace_constraint = cls.NC_any
3411 elif cls.NC_not == nc:
3412 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3413 else:
3414 ncs = set()
3415 for ns_uri in nc.split():
3416 if cls.NC_local == ns_uri:
3417 ncs.add(None)
3418 elif cls.NC_targetNamespace == ns_uri:
3419 ncs.add(namespace_context.targetNamespace())
3420 else:
3421 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3422 namespace_constraint = frozenset(ncs)
3423
3424 pc = NodeAttribute(node, 'processContents')
3425 if pc is None:
3426 process_contents = cls.PC_strict
3427 else:
3428 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3429 process_contents = pc
3430 else:
3431 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3432
3433 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3434 rv._annotationFromDOM(node)
3435 return rv
3436
3437
3438 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3439 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3440
3441 ICC_KEY = 0x01
3442 ICC_KEYREF = 0x02
3443 ICC_UNIQUE = 0x04
3444
3445 __identityConstraintCategory = None
3447
3448 __selector = None
3450
3451 __fields = None
3453
3454 __referencedKey = None
3455
3456 __annotations = None
3458
3459
3460 @classmethod
3462 name = NodeAttribute(node, 'name')
3463 scope = kw['scope']
3464 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3465 rv = cls(name=name, node=node, **kw)
3466
3467 kw.pop('node', None)
3468 kw['owner'] = rv
3469
3470
3471 rv.__isResolved = True
3472 icc = None
3473 if xsd.nodeIsNamed(node, 'key'):
3474 icc = rv.ICC_KEY
3475 elif xsd.nodeIsNamed(node, 'keyref'):
3476 icc = rv.ICC_KEYREF
3477 rv.__referAttribute = NodeAttribute(node, 'refer')
3478 if rv.__referAttribute is None:
3479 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3480 rv.__isResolved = False
3481 elif xsd.nodeIsNamed(node, 'unique'):
3482 icc = rv.ICC_UNIQUE
3483 else:
3484 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml(),))
3485 rv.__icc = icc
3486
3487 cn = LocateUniqueChild(node, 'selector')
3488 rv.__selector = NodeAttribute(cn, 'xpath')
3489 if rv.__selector is None:
3490 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3491
3492 rv.__fields = []
3493 for cn in LocateMatchingChildren(node, 'field'):
3494 xp_attr = NodeAttribute(cn, 'xpath')
3495 if xp_attr is None:
3496 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3497 rv.__fields.append(xp_attr)
3498
3499 rv._annotationFromDOM(node)
3500 rv.__annotations = []
3501 if rv.annotation() is not None:
3502 rv.__annotations.append(rv)
3503
3504 for cn in node.childNodes:
3505 if (Node.ELEMENT_NODE != cn.nodeType):
3506 continue
3507 an = None
3508 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3509 an = LocateUniqueChild(cn, 'annotation')
3510 elif xsd.nodeIsNamed(cn, 'annotation'):
3511 an = cn
3512 if an is not None:
3513 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3514
3515 rv.__identityConstraintCategory = icc
3516 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3517 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3518
3519 if not rv.isResolved():
3520 rv._queueForResolution('creation')
3521 return rv
3522
3523 __isResolved = False
3526
3527
3542
3543
3545 """Constraint definitions that are by reference require the referenced constraint."""
3546 rv = set()
3547 if include_lax and (self.__referencedKey is not None):
3548 rv.add(self.__referencedKey)
3549 return frozenset(rv)
3550
3551
3552
3553
3554 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3555 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3556 __systemIdentifier = None
3558
3559 __publicIdentifier = None
3561
3562
3563 @classmethod
3573
3576 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3577
3578 __applicationInformation = None
3581
3582 __userInformation = None
3585
3586
3588 application_information = kw.pop('application_information', None)
3589 user_information = kw.pop('user_information', None)
3590 super(Annotation, self).__init__(**kw)
3591 if (user_information is not None) and (not isinstance(user_information, list)):
3592 user_information = [ unicode(user_information) ]
3593 if (application_information is not None) and (not isinstance(application_information, list)):
3594 application_information = [ unicode(application_information) ]
3595 self.__userInformation = user_information
3596 self.__applicationInformation = application_information
3597
3598
3599
3600
3601
3602
3603
3604
3605 __attributes = None
3606
3607
3608 @classmethod
3610 rv = cls(node=node, **kw)
3611
3612
3613
3614
3615
3616 assert xsd.nodeIsNamed(node, 'annotation')
3617 app_info = []
3618 user_info = []
3619 for cn in node.childNodes:
3620 if xsd.nodeIsNamed(cn, 'appinfo'):
3621 app_info.append(cn)
3622 elif xsd.nodeIsNamed(cn, 'documentation'):
3623 user_info.append(cn)
3624 else:
3625 pass
3626 if 0 < len(app_info):
3627 rv.__applicationInformation = app_info
3628 if 0 < len(user_info):
3629 rv.__userInformation = user_info
3630
3631 return rv
3632
3633 __RemoveMultiQuote_re = re.compile('""+')
3634 - def asDocString (self, encoding='ascii', error='xmlcharrefreplace'):
3635 """Return the text in a form suitable for embedding in a
3636 triple-double-quoted docstring.
3637
3638 Any sequence of two or more double quotes is replaced by a sequence of
3639 single quotes that is the same length. Following this, spaces are
3640 added at the start and the end as necessary to ensure a double quote
3641 does not appear in those positions."""
3642 rv = self.text().encode(encoding, error)
3643 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3644 if rv.startswith('"'):
3645 rv = ' ' + rv
3646 if rv.endswith('"'):
3647 rv = rv + ' '
3648 return rv
3649
3651 if self.__userInformation is None:
3652 return ''
3653 text = []
3654
3655
3656 for dn in self.__userInformation:
3657 for cn in dn.childNodes:
3658 if Node.TEXT_NODE == cn.nodeType:
3659 text.append(cn.data)
3660 return ''.join(text)
3661
3663 """Return the catenation of all user information elements in the
3664 annotation as a single unicode string. Returns the empty string if
3665 there are no user information elements."""
3666 return self.text()
3667 text = []
3668 if not self.__userInformation:
3669 return ''
3670
3671
3672 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3673 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3674
3675
3676
3677
3678 __baseTypeDefinition = None
3681
3682
3683
3684
3685
3686
3687 __facets = None
3691
3692
3693 __fundamentalFacets = None
3695 """A frozenset of instances of facets.FundamentallFacet."""
3696 return self.__fundamentalFacets
3697
3698 STD_empty = 0
3699 STD_extension = 0x01
3700 STD_list = 0x02
3701 STD_restriction = 0x04
3702 STD_union = 0x08
3703
3704 _STD_Map = { 'extension' : STD_extension
3705 , 'list' : STD_list
3706 , 'restriction' : STD_restriction
3707 , 'union' : STD_union }
3708
3709
3710 __final = STD_empty
3711 @classmethod
3713 """Convert a final value to a string."""
3714 tags = []
3715 if final_value & cls.STD_extension:
3716 tags.append('extension')
3717 if final_value & cls.STD_list:
3718 tags.append('list')
3719 if final_value & cls.STD_restriction:
3720 tags.append('restriction')
3721 if final_value & cls.STD_union:
3722 tags.append('union')
3723 return ' '.join(tags)
3724
3725 VARIETY_absent = 0x01
3726 VARIETY_atomic = 0x02
3727 VARIETY_list = 0x03
3728 VARIETY_union = 0x04
3729
3730
3731 _DA_empty = 'none specified'
3732 _DA_restriction = 'restriction'
3733 _DA_list = 'list'
3734 _DA_union = 'union'
3735
3738 __derivationAlternative = None
3739
3740
3741
3742 __variety = None
3745 @classmethod
3757
3758
3759 __primitiveTypeDefinition = None
3767
3768
3769 __itemTypeDefinition = None
3776
3777
3778 __memberTypeDefinitions = None
3785
3786
3816
3817
3818
3819
3820
3821 __domNode = None
3822
3823
3824
3825 __isBuiltin = False
3826
3827
3828
3829
3833
3835 """Extend base class unpickle support to retain link between
3836 this instance and the Python class that it describes.
3837
3838 This is because the pythonSupport value is a class reference,
3839 not an instance reference, so it wasn't deserialized, and its
3840 class member link was never set.
3841 """
3842 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3843 super_fn(state)
3844 if self.__pythonSupport is not None:
3845 self.__pythonSupport._SimpleTypeDefinition(self)
3846
3874
3876 """Override fields in this instance with those from the other.
3877
3878 This method is invoked only by Schema._addNamedComponent, and
3879 then only when a built-in type collides with a schema-defined
3880 type. Material like facets is not (currently) held in the
3881 built-in copy, so the DOM information is copied over to the
3882 built-in STD, which is subsequently re-resolved.
3883
3884 Returns self.
3885 """
3886 assert self != other
3887 assert self.isNameEquivalent(other)
3888 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3889
3890
3891 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3892 assert other.__domNode is not None
3893 self.__domNode = other.__domNode
3894
3895
3896 if other.__pythonSupport is not None:
3897
3898 self.__pythonSupport = other.__pythonSupport
3899
3900
3901 self.__variety = None
3902 return self
3903
3905 """Indicate whether this simple type is a built-in type."""
3906 return self.__isBuiltin
3907
3908 __SimpleUrTypeDefinition = None
3909 @classmethod
3945
3946 @classmethod
3982
3983 @classmethod
4014
4015 @classmethod
4046
4047 @classmethod
4074
4075 @classmethod
4077 """(Placeholder) Create a union simple type in the target namespace.
4078
4079 This function has not been implemented."""
4080 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4081
4083 simple_type_child = None
4084 for cn in body.childNodes:
4085 if (Node.ELEMENT_NODE == cn.nodeType):
4086 if not xsd.nodeIsNamed(cn, 'simpleType'):
4087 if other_elts_ok:
4088 continue
4089 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4090 assert not simple_type_child
4091 simple_type_child = cn
4092 if simple_type_child is None:
4093 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4094 return simple_type_child
4095
4096
4097
4098
4099
4100
4101
4102
4112
4119
4120 __localMemberTypes = None
4130
4142
4144 """Create facets for varieties that can take facets that are undeclared.
4145
4146 This means unions, which per section 4.1.2.3 of
4147 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4148 pattern restrictions."""
4149 if self.VARIETY_union != variety:
4150 return self
4151 self.__facets.setdefault(facets.CF_pattern)
4152 self.__facets.setdefault(facets.CF_enumeration)
4153 return self
4154
4156 """Identify the facets and properties for this stype.
4157
4158 This method simply identifies the facets that apply to this
4159 specific type, and records property values. Only
4160 explicitly-associated facets and properties are stored; others
4161 from base types will also affect this type. The information
4162 is taken from the applicationInformation children of the
4163 definition's annotation node, if any. If there is no support
4164 for the XMLSchema_hasFacetAndProperty namespace, this is a
4165 no-op.
4166
4167 Upon return, self.__facets is a map from the class for an
4168 associated fact to None, and self.__fundamentalFacets is a
4169 frozenset of instances of FundamentalFacet.
4170
4171 The return value is self.
4172 """
4173 self.__facets = { }
4174 self.__fundamentalFacets = frozenset()
4175 if self.annotation() is None:
4176 return self.__defineDefaultFacets(variety)
4177 app_info = self.annotation().applicationInformation()
4178 if app_info is None:
4179 return self.__defineDefaultFacets(variety)
4180 facet_map = { }
4181 fundamental_facets = set()
4182 seen_facets = set()
4183 for ai in app_info:
4184 for cn in ai.childNodes:
4185 if Node.ELEMENT_NODE != cn.nodeType:
4186 continue
4187 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4188 facet_name = NodeAttribute(cn, 'name')
4189 if facet_name is None:
4190 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4191 if facet_name in seen_facets:
4192 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4193 seen_facets.add(facet_name)
4194 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4195
4196 facet_map[facet_class] = None
4197 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4198 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4199 if 0 < len(facet_map):
4200 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4201 self.__facets = facet_map
4202 assert type(self.__facets) == types.DictType
4203 if 0 < len(fundamental_facets):
4204 self.__fundamentalFacets = frozenset(fundamental_facets)
4205 return self
4206
4207
4258
4273
4274
4275
4276
4278 assert self.__variety is None
4279 if self.__baseTypeDefinition is None:
4280 assert self.__baseAttribute is not None
4281 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4282 base_type = base_en.typeDefinition()
4283 if not isinstance(base_type, SimpleTypeDefinition):
4284 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4285 self.__baseTypeDefinition = base_type
4286
4287
4288
4289 assert self.__baseTypeDefinition != self
4290 if not self.__baseTypeDefinition.isResolved():
4291 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4292 return self
4293 if variety is None:
4294
4295
4296 variety = self.__baseTypeDefinition.__variety
4297 assert variety is not None
4298
4299 if self.VARIETY_absent == variety:
4300
4301
4302 pass
4303 elif self.VARIETY_atomic == variety:
4304
4305
4306
4307 ptd = self
4308 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4309 ptd = ptd.__baseTypeDefinition
4310
4311 self.__primitiveTypeDefinition = ptd
4312 elif self.VARIETY_list == variety:
4313 if self._DA_list == alternative:
4314 if self.__itemTypeAttribute is not None:
4315 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4316 self.__itemTypeDefinition = it_en.typeDefinition()
4317 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4318 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4319 elif self._DA_restriction == alternative:
4320 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4321 else:
4322 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4323 elif self.VARIETY_union == variety:
4324 if self._DA_union == alternative:
4325
4326
4327
4328
4329 if self.__memberTypeDefinitions is None:
4330 mtd = []
4331
4332
4333 if self.__memberTypesAttribute is not None:
4334 for mn in self.__memberTypesAttribute.split():
4335
4336 mn_en = self._namespaceContext().interpretQName(mn)
4337 std = mn_en.typeDefinition()
4338 if std is None:
4339 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4340
4341 assert isinstance(std, SimpleTypeDefinition)
4342 mtd.append(std)
4343
4344 mtd.extend(self.__localMemberTypes)
4345 self.__memberTypeDefinitions = mtd
4346 assert None not in self.__memberTypeDefinitions
4347
4348
4349
4350
4351
4352
4353 mtd = []
4354 for mt in self.__memberTypeDefinitions:
4355 assert isinstance(mt, SimpleTypeDefinition)
4356 if not mt.isResolved():
4357 self._queueForResolution('member type not resolved', depends_on=mt)
4358 return self
4359 if self.VARIETY_union == mt.variety():
4360 mtd.extend(mt.memberTypeDefinitions())
4361 else:
4362 mtd.append(mt)
4363 elif self._DA_restriction == alternative:
4364 assert self.__baseTypeDefinition
4365
4366 assert self.__baseTypeDefinition.isResolved()
4367 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4368 assert mtd is not None
4369 else:
4370 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4371
4372 self.__memberTypeDefinitions = mtd[:]
4373 else:
4374 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4375
4376
4377
4378 self.__processHasFacetAndProperty(variety)
4379 self.__updateFacets(body)
4380
4381 self.__derivationAlternative = alternative
4382 self.__variety = variety
4383 self.__domNode = None
4384
4385 return self
4386
4388 """Indicate whether this simple type is fully defined.
4389
4390 Type resolution for simple types means that the corresponding
4391 schema component fields have been set. Specifically, that
4392 means variety, baseTypeDefinition, and the appropriate
4393 additional fields depending on variety. See _resolve() for
4394 more information.
4395 """
4396
4397 return (self.__variety is not None)
4398
4399
4401 """Attempt to resolve the type.
4402
4403 Type resolution for simple types means that the corresponding
4404 schema component fields have been set. Specifically, that
4405 means variety, baseTypeDefinition, and the appropriate
4406 additional fields depending on variety.
4407
4408 All built-in STDs are resolved upon creation. Schema-defined
4409 STDs are held unresolved until the schema has been completely
4410 read, so that references to later schema-defined STDs can be
4411 resolved. Resolution is performed after the entire schema has
4412 been scanned and STD instances created for all
4413 topLevelSimpleTypes.
4414
4415 If a built-in STD is also defined in a schema (which it should
4416 be for XMLSchema), the built-in STD is kept, with the
4417 schema-related information copied over from the matching
4418 schema-defined STD. The former then replaces the latter in
4419 the list of STDs to be resolved.
4420
4421 Types defined by restriction have the same variety as the type
4422 they restrict. If a simple type restriction depends on an
4423 unresolved type, this method simply queues it for resolution
4424 in a later pass and returns.
4425 """
4426 if self.__variety is not None:
4427 return self
4428
4429 assert self.__domNode
4430 node = self.__domNode
4431
4432 kw = { 'owner' : self
4433 , 'schema' : self._schema() }
4434
4435 bad_instance = False
4436
4437
4438 candidate = LocateUniqueChild(node, 'list')
4439 if candidate:
4440 self.__initializeFromList(candidate, **kw)
4441
4442 candidate = LocateUniqueChild(node, 'restriction')
4443 if candidate:
4444 if self.__variety is None:
4445 self.__initializeFromRestriction(candidate, **kw)
4446 else:
4447 bad_instance = True
4448
4449 candidate = LocateUniqueChild(node, 'union')
4450 if candidate:
4451 if self.__variety is None:
4452 self.__initializeFromUnion(candidate, **kw)
4453 else:
4454 bad_instance = True
4455
4456 if self.__baseTypeDefinition is None:
4457 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4458
4459 if self._schema() is not None:
4460 self.__final = self._schema().finalForNode(node, self._STD_Map)
4461
4462
4463 if bad_instance:
4464 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4465
4466 return self
4467
4468
4469 @classmethod
4485
4486
4487
4488
4489 __pythonSupport = None
4490
4500
4503
4508
4511
4514
4516 """Subclass ensures there is only one simple ur-type."""
4517 pass
4518
4626
4627 -class Schema (_SchemaComponent_mixin):
4628 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4629
4632
4633
4634 __annotations = None
4635
4636
4637
4638 __pastProlog = False
4639
4641 """URI or path to where the schema can be found.
4642
4643 For schema created by a user, the location should be provided to the
4644 constructor using the C{schema_location} keyword. In the case of
4645 imported or included schema, the including schema's location is used
4646 as the base URI for determining the absolute URI of the included
4647 schema from its (possibly relative) location value. For files,
4648 the scheme and authority portions are generally absent, as is often
4649 the abs_path part."""
4650 return self.__location
4651 __location = None
4652
4655 __locationTag = None
4656
4659 __signature = None
4660
4663 __generationUID = None
4664
4667 __originRecord = None
4668
4670 """The targetNamespace of a componen.
4671
4672 This is None, or a reference to a Namespace in which the
4673 component is declared (either as a global or local to one of
4674 the namespace's complex type definitions). This is immutable
4675 after creation.
4676 """
4677 return self.__targetNamespace
4678 __targetNamespace = None
4679
4681 """Default namespace of the schema.
4682
4683 Will be None unless the schema has an 'xmlns' attribute. The
4684 value must currently be provided as a keyword parameter to the
4685 constructor. """
4686 return self.__defaultNamespace
4687 __defaultNamespace = None
4688
4691 __referencedNamespaces = None
4692
4695 __importEIIs = None
4696
4699 __importedSchema = None
4702 __includedSchema = None
4703
4704 _QUALIFIED = "qualified"
4705 _UNQUALIFIED = "unqualified"
4706
4707
4708 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4709 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4710 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4711 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4712 , pyxb.namespace.ExpandedName(None, 'id') : None
4713 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4714 , pyxb.namespace.ExpandedName(None, 'version') : None
4715 , pyxb.namespace.XML.createExpandedName('lang') : None
4716 }
4717
4722
4724 """Override the schema attributes with values from the given map."""
4725 self.__attributeMap.update(attr_map)
4726 return self
4727
4729 """Return True iff the schema has an attribute with the given (nc)name."""
4730 if isinstance(attr_name, basestring):
4731 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4732 return self.__attributeMap.has_key(attr_name)
4733
4735 """Return the schema attribute value associated with the given (nc)name.
4736
4737 @param attr_name: local name for the attribute in the schema element.
4738 @return: the value of the corresponding attribute, or C{None} if it
4739 has not been defined and has no default.
4740 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4741 """
4742 if isinstance(attr_name, basestring):
4743 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4744 return self.__attributeMap[attr_name]
4745
4746 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4747 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4748 'identityConstraintDefinition' )
4749
4752 __uriContentArchiveDirectory = None
4753
4796
4797 __TopLevelComponentMap = {
4798 'element' : ElementDeclaration,
4799 'attribute' : AttributeDeclaration,
4800 'notation' : NotationDeclaration,
4801 'simpleType' : SimpleTypeDefinition,
4802 'complexType' : ComplexTypeDefinition,
4803 'group' : ModelGroupDefinition,
4804 'attributeGroup' : AttributeGroupDefinition
4805 }
4806
4807 @classmethod
4812
4813 @classmethod
4815 """Create a schema from a schema location.
4816
4817 Reads an XML document from the schema location and creates a schema
4818 using it. All keyword parameters are passed to L{CreateFromDOM}.
4819
4820 @keyword schema_location: A file path or a URI. If this is a relative
4821 URI and C{parent_uri} is present, the actual location will be
4822 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4823 @keyword parent_uri: The context within which schema_location will be
4824 normalized, if necessary.
4825 @keyword absolute_schema_location: A file path or URI. This value is
4826 not normalized, and supersedes C{schema_location}.
4827 """
4828 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4829 kw['location_base'] = kw['schema_location'] = schema_location
4830 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4831 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4832 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4833
4834 @classmethod
4837
4838 @classmethod
4839 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4840 """Take the root element of the document, and scan its attributes under
4841 the assumption it is an XMLSchema schema element. That means
4842 recognize namespace declarations and process them. Also look for
4843 and set the default namespace. All other attributes are passed up
4844 to the parent class for storage."""
4845
4846
4847
4848 including_context = kw.get('including_context')
4849
4850 root_node = node
4851 if Node.DOCUMENT_NODE == node.nodeType:
4852 root_node = root_node.documentElement
4853 if Node.ELEMENT_NODE != root_node.nodeType:
4854 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4855
4856 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4857 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4858 parent_context=namespace_context,
4859 including_context=including_context)
4860
4861 tns = ns_ctx.targetNamespace()
4862 if tns is None:
4863 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4864 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4865 schema.__namespaceData = ns_ctx
4866
4867 if schema.targetNamespace() != ns_ctx.targetNamespace():
4868 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4869
4870
4871 for ai in range(root_node.attributes.length):
4872 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4873
4874
4875 if not xsd.nodeIsNamed(root_node, 'schema'):
4876 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4877
4878 for cn in root_node.childNodes:
4879 if Node.ELEMENT_NODE == cn.nodeType:
4880 rv = schema.__processTopLevelNode(cn)
4881 if rv is None:
4882 print 'Unrecognized: %s %s' % (cn.nodeName, cn.toxml())
4883 elif Node.TEXT_NODE == cn.nodeType:
4884
4885
4886 text = cn.data.strip()
4887 if text:
4888 print 'Ignored text: %s' % (text,)
4889 elif Node.COMMENT_NODE == cn.nodeType:
4890
4891 pass
4892 else:
4893
4894
4895
4896
4897
4898
4899
4900 print 'Ignoring non-element: %s' % (cn,)
4901
4902
4903
4904
4905 return schema
4906
4907 _SA_All = '#all'
4908
4910 ebv = NodeAttribute(dom_node, attr)
4911 if ebv is None:
4912 ebv = self.schemaAttribute('%sDefault' % (attr,))
4913 rv = 0
4914 if ebv == self._SA_All:
4915 for v in candidate_map.values():
4916 rv += v
4917 else:
4918 for candidate in ebv.split():
4919 rv += candidate_map.get(candidate, 0)
4920 return rv
4921
4923 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4924
4925 A value of '#all' means enable every options; otherwise, the attribute
4926 value should be a list of tokens, for which the corresponding value
4927 will be added to the return value.
4928
4929 @param dom_node: the node from which the "block" attribute will be retrieved
4930 @type dom_node: C{xml.dom.Node}
4931 @param candidate_map: map from strings to bitmask values
4932 """
4933 return self.__ebvForNode('block', dom_node, candidate_map)
4934
4936 """Return a bit mask indicating a set of options read from the node's
4937 "final" attribute or the schema's "finalDefault" attribute.
4938
4939 A value of '#all' means enable every options; otherwise, the attribute
4940 value should be a list of tokens, for which the corresponding value
4941 will be added to the return value.
4942
4943 @param dom_node: the node from which the "final" attribute will be retrieved
4944 @type dom_node: C{xml.dom.Node}
4945 @param candidate_map: map from strings to bitmask values
4946 """
4947 return self.__ebvForNode('final', dom_node, candidate_map)
4948
4950 """Determine the target namespace for a local attribute or element declaration.
4951
4952 Look at the node's C{form} attribute, or if none the schema's
4953 C{attributeFormDefault} or C{elementFormDefault} value. If the
4954 resulting value is C{"qualified"} and the parent schema has a
4955 non-absent target namespace, return it to use as the declaration
4956 target namespace. Otherwise, return None to indicate that the
4957 declaration has no namespace.
4958
4959 @param dom_node: The node defining an element or attribute declaration
4960 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4961 @return: L{pyxb.namespace.Namespace} or None
4962 """
4963
4964 form_type = NodeAttribute(dom_node, 'form')
4965 if form_type is None:
4966 if declaration_type == ElementDeclaration:
4967 form_type = self.schemaAttribute('elementFormDefault')
4968 elif declaration_type == AttributeDeclaration:
4969 form_type = self.schemaAttribute('attributeFormDefault')
4970 else:
4971 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4972 tns = None
4973 if (self._QUALIFIED == form_type):
4974 tns = self.targetNamespace()
4975 if tns.isAbsentNamespace():
4976 tns = None
4977 else:
4978 if (self._UNQUALIFIED != form_type):
4979 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4980 return tns
4981
4983 """Throw a SchemaValidationException referencing the given
4984 node if we have passed the sequence point representing the end
4985 of prolog elements."""
4986
4987 if self.__pastProlog:
4988 print '%s past prolog' % (object.__str__(self),)
4989 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4990
4992 self.__requireInProlog(node.nodeName)
4993
4994 abs_uri = pyxb.utils.utility.NormalizeLocation(NodeAttribute(node, 'schemaLocation'), self.__location)
4995
4996 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
4997 if not has_schema:
4998 kw = { 'absolute_schema_location': abs_uri,
4999 'including_context': self.__namespaceData,
5000 'generation_uid': self.generationUID(),
5001 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
5002 }
5003 try:
5004 schema_instance = self.CreateFromLocation(**kw)
5005 except Exception, e:
5006 print 'INCLUDE %s caught: %s' % (abs_uri, e)
5007
5008 raise
5009
5010
5011
5012
5013 if schema_instance:
5014 if self.targetNamespace() != schema_instance.targetNamespace():
5015 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
5016 self.__includedSchema.add(schema_instance)
5017 return node
5018
5038
5042
5046
5070
5074
5076 tns = self.targetNamespace()
5077 assert tns is not None
5078 if not isinstance(nc, _NamedComponent_mixin):
5079 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
5080 if nc.isAnonymous():
5081 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
5082 if isinstance(nc, _ScopedDeclaration_mixin):
5083 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
5084
5085 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5086 return self.__addTypeDefinition(nc)
5087 if isinstance(nc, AttributeDeclaration):
5088 return self.__addAttributeDeclaration(nc)
5089 if isinstance(nc, AttributeGroupDefinition):
5090 return self.__addAttributeGroupDefinition(nc)
5091 if isinstance(nc, ModelGroupDefinition):
5092 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5093 if isinstance(nc, ElementDeclaration):
5094 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5095 if isinstance(nc, NotationDeclaration):
5096 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5097 if isinstance(nc, IdentityConstraintDefinition):
5098 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5099 raise pyxb.IncompleteImplementationError('No support to record named component of type %s' % (nc.__class__,))
5100
5120
5137
5154
5156 return 'SCH[%s]' % (self.location(),)
5157
5160 """Add to the schema the definitions of the built-in types of XMLSchema.
5161 This should only be invoked by L{pyxb.namespace} when the built-in
5162 namespaces are initialized. """
5163
5164
5165 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5166 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5167 assert td.isResolved()
5168
5169 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5170 assert td.isResolved()
5171
5172 pts_std_map = {}
5173 ns_ctx = namespace.initialNamespaceContext()
5174 for dtc in datatypes._PrimitiveDatatypes:
5175 name = dtc.__name__.rstrip('_')
5176 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5177 assert td.isResolved()
5178 assert dtc.SimpleTypeDefinition() == td
5179 pts_std_map.setdefault(dtc, td)
5180 for dtc in datatypes._DerivedDatatypes:
5181 name = dtc.__name__.rstrip('_')
5182 parent_std = pts_std_map[dtc.XsdSuperType()]
5183 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5184 assert td.isResolved()
5185 assert dtc.SimpleTypeDefinition() == td
5186 pts_std_map.setdefault(dtc, td)
5187 for dtc in datatypes._ListDatatypes:
5188 list_name = dtc.__name__.rstrip('_')
5189 element_name = dtc._ItemType.__name__.rstrip('_')
5190 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5191 assert element_std is not None
5192 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5193 assert td.isResolved()
5194 global _PastAddBuiltInTypes
5195 _PastAddBuiltInTypes = True
5196
5197 return schema
5198
5199 import sys
5200 import pyxb.namespace.builtin
5201 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5202
5203
5204
5205
5206