1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Classes corresponding to W3C XML Schema components.
17
18 Class names and behavior should conform to the schema components described in
19 U{XML Schema Part 1: Structures<http://www.w3.org/TR/xmlschema-1/>}.
20 References to sections in the documentation of this module generally refers to
21 that document.
22
23 Each class has a C{CreateFromDOM} class method that creates an instance and
24 initializes it from a DOM node. Only the L{Wildcard}, L{Particle}, and
25 L{ModelGroup} components are created from non-DOM sources. However, the
26 requirements on DOM interface are restricted to attributes, child nodes, and
27 basic fields, though all these must support namespaces.
28
29 @group Mixins: *_mixin
30 @group Ur Type Specializations: *UrType*
31 @group Utilities: _ImportElementInformationItem
32
33 """
34
35 import pyxb
36 import pyxb.xmlschema
37 from xml.dom import Node
38 import types
39 import re
40 import logging
41
42 import pyxb.namespace.archive
43 import pyxb.namespace.resolution
44
45 from pyxb.binding import basis
46 from pyxb.binding import datatypes
47 from pyxb.binding import facets
48 from pyxb.utils import domutils
49 import pyxb.utils.utility
50 import copy
51 import urlparse
52 import os.path
53
54 _log = logging.getLogger(__name__)
55
56
57 _PastAddBuiltInTypes = False
58
59
60 from pyxb.namespace import XMLSchema as xsd
61
62 -class _SchemaComponent_mixin (pyxb.namespace._ComponentDependency_mixin,
63 pyxb.namespace.archive._ArchivableObject_mixin,
64 pyxb.utils.utility.PrivateTransient_mixin,
65 pyxb.utils.utility.Locatable_mixin):
66 """A mix-in that marks the class as representing a schema component.
67
68 This exists so that we can determine the owning schema for any
69 component we encounter. This is normally done at construction
70 time by passing a C{schema=val} parameter to the constructor.
71 """
72
73
74
75 __PrivateTransient = set()
76
78 """The namespace context for this schema.
79
80 This defines where it looks things up, where it puts things it
81 creates, the in-scope namespace declarations, etc. Must be defined
82 for anything that does any sort of QName interpretation. The value is
83 generally a reference to a namespace context associated with the DOM
84 element node corresponding to this component."""
85 if self.__namespaceContext is None:
86 raise pyxb.LogicError('Attempt to access missing namespace context for %s' % (self,))
87 return self.__namespaceContext
89
90
91 self.schemaOrderSortKey()
92 self.__namespaceContext = None
93 return self
94 __namespaceContext = None
95 __PrivateTransient.add('namespaceContext')
96
97
98
99
100
101 __nameInBinding = None
102
103
104
105 __owner = None
106 __PrivateTransient.add('owner')
107
108
109 __ownedComponents = None
110 __PrivateTransient.add('ownedComponent')
111
113 """The context into which declarations in or subordinate to this nodeare placed."""
114 return self.__scope
115 __scope = None
116
120
124
126 """Set the scope of this instance after construction.
127
128 This should only be invoked on cloned declarations being incorporated
129 into a complex type definition. Note that the source of the clone may
130 be any scope: indeterminate if from a model (attribute) group
131 definition; global if a reference to a global component; or ctd if
132 inherited from a complex base type."""
133 assert self.__cloneSource is not None
134 assert isinstance(self, _ScopedDeclaration_mixin)
135 assert isinstance(ctd, ComplexTypeDefinition)
136 self.__scope = ctd
137 return self
138
140 """Initialize portions of a component.
141
142 @keyword scope: The scope in which the component is defined
143
144 @keyword namespace_context: The NamespaceContext to use within this component
145
146 @keyword node: If no C{namespace_context} is provided, a DOM node must
147 be provided from which a namespace context can be identified.
148
149 @keyword owner: Reference to the component that owns this one (the
150 immediately enclosing component). Is C{None} in the case of top-level
151 components.
152
153 @keyword schema: Reference to the L{Schema} component to which the
154 component belongs. Required for every component except L{Schema},
155 L{Annotation}, and L{Wildcard}.
156 """
157
158 self.__ownedComponents = set()
159 self.__scope = kw.get('scope')
160 self.__namespaceContext = kw.get('namespace_context')
161 node = kw.get('node')
162 owner = kw.get('owner')
163 if self.__namespaceContext is None:
164 if node is None:
165 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node')
166 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
167 if self.__namespaceContext is None:
168 raise pyxb.LogicError('No namespace_context for schema component')
169
170 super(_SchemaComponent_mixin, self).__init__(*args, **kw)
171
172 self._namespaceContext().targetNamespace()._associateComponent(self)
173
174 self._setOwner(owner)
175 if isinstance(node, pyxb.utils.utility.Locatable_mixin):
176 self._setLocation(node._location())
177 elif isinstance(owner, pyxb.utils.utility.Locatable_mixin):
178 self._setLocation(owner._location())
179
180 schema = kw.get('schema')
181 if schema is not None:
182 self._setObjectOrigin(schema.originRecord())
183 else:
184 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),)
185
186 if isinstance(self, ComplexTypeDefinition):
187 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
188
190 """Dissociate this component from its owning namespace.
191
192 This should only be done whwen there are no other references to the
193 component, and you want to ensure it does not appear in the model."""
194 self._namespaceContext().targetNamespace()._replaceComponent(self, None)
195 return self
196
198 """Set the owner of this component.
199
200 If C{owner} is C{None}, this has no effect. Otherwise, the
201 component's current owner must be either C{None} or the same as the
202 input C{owner}."""
203
204 if owner is not None:
205 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner)
206 self.__owner = owner
207 owner.__ownedComponents.add(self)
208 return self
209
212
213
214 __cloneSource = None
215 __PrivateTransient.add('cloneSource')
216
218 """The source component from which this is a clone.
219
220 Returns C{None} if this is not a clone."""
221 return self.__cloneSource
222
223
224 __clones = None
225 __PrivateTransient.add('clones')
226
228 """The set of instances cloned from this component.
229
230 Returns None if no instances have been cloned from this."""
231 return self.__clones
232
259
260 - def _clone (self, owner, origin):
284
289
294
296 """Return the name of this component, as best it can be determined.
297
298 For example, ModelGroup instances will be named by their
299 ModelGroupDefinition, if available. Returns None if no name can be
300 inferred."""
301 if isinstance(self, _NamedComponent_mixin):
302 return self.name()
303 if isinstance(self, ModelGroup):
304 agd = self.modelGroupDefinition()
305 if agd is not None:
306 return agd.name()
307 return None
308
310 """Return the name by which this component is known in the generated
311 binding.
312
313 @note: To support builtin datatypes, type definitions with an
314 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class
315 initialize their binding name from the class name when the support
316 association is created. As long as no built-in datatype conflicts
317 with a language keyword, this should be fine."""
318 return self.__nameInBinding
319
321 """Return C{True} iff this is a component which has a user-visible
322 Python construct which serves as its binding.
323
324 Type definitions have classes as their bindings. Global element
325 declarations have instances of L{pyxb.binding.basis.element} as their
326 bindings."""
327 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
328
330 """Set the name by which this component shall be known in the XSD binding."""
331 self.__nameInBinding = name_in_binding
332 return self
333
335 """Override fields in this instance with those from the other.
336
337 Post-extended; description in leaf implementation in
338 ComplexTypeDefinition and SimpleTypeDefinition."""
339 assert self != other
340 self_fn = lambda *_args, **_kw: self
341 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', self_fn)(other)
342
343 if self.__nameInBinding is None:
344 self.__nameInBinding = other.__nameInBinding
345 return self
346
348 """A key to be used when sorting components for binding generation.
349
350 This is a tuple comprising the namespace URI, schema location, and
351 line and column of the component definition within the schema. The
352 purpose is to ensure consistent order of binding components in
353 generated code, to simplify maintenance involving the generated
354 sources.
355
356 To support Python 3 values that are C{None} are replaced with the
357 default value for whatever type belongs in the corresponding
358 position: (uri:str, locbase:str, locline:int, loccol:int) """
359 if self.__schemaOrderSortKey is None:
360 ns = None
361 if isinstance(self, _NamedComponent_mixin):
362 ns = self.bindingNamespace()
363 if ns is None:
364 ns = self._namespaceContext().targetNamespace()
365 elif isinstance(self, _ParticleTree_mixin):
366 ns = self._namespaceContext().targetNamespace()
367 ns_uri = ''
368 if (ns is not None) and (ns.uri() is not None):
369 ns_uri = ns.uri()
370 key_elts = [ns_uri]
371 loc = self._location()
372 v = ''
373 if (loc is not None) and (loc.locationBase is not None):
374 v = loc.locationBase
375 key_elts.append(v)
376 v = 0
377 if (loc is not None) and (loc.lineNumber is not None):
378 v = loc.lineNumber
379 key_elts.append(v)
380 v = 0
381 if (loc is not None) and (loc.columnNumber is not None):
382 v = loc.columnNumber
383 key_elts.append(v)
384 self.__schemaOrderSortKey = tuple(key_elts)
385 return self.__schemaOrderSortKey
386 __schemaOrderSortKey = None
387
389 """A sort key matching preferred content order.
390
391 This is an ordinal (integer) used to control which candidate
392 transitions are attempted first when testing symbols against the
393 content automaton state.
394
395 @note: The value associated with a node (especially a L{ModelGroup} or
396 L{Particle} will be different for different complex types, and is
397 valid only during generation of the automata code for a given type."""
398 assert self.__facStateSortKey is not None
399 return self.__facStateSortKey
400
402 """Set the automata state sort key.
403
404 @param key: the ordinal used for sorting."""
405 self.__facStateSortKey = key
406 __facStateSortKey = None
407 __PrivateTransient.add('facStateSortKey')
408
409 -class _ParticleTree_mixin (pyxb.cscRoot):
410 - def _walkParticleTree (self, visit, arg):
411 """Mix-in supporting walks of L{Particle} trees.
412
413 This invokes a provided function on each node in a tree defining the
414 content model of a particle, both on the way down the tree and on the
415 way back up. A standard implementation would be::
416
417 def _walkParticleTree (self, visit, arg):
418 visit(self, True, arg)
419 self.__term.walkParticleTree(visit, arg)
420 visit(self, False, arg)
421
422 @param visit: A callable with parameters C{node, entering, arg} where
423 C{node} is an instance of a class inheriting L{_ParticleTree_mixin},
424 C{entering} indicates tree transition status, and C{arg} is a
425 caller-provided state parameter. C{entering} is C{True} if C{node}
426 has particle children and the call is before they are visited;
427 C{None} if the C{node} has no particle children; and C{False} if
428 C{node} has particle children and they have been visited.
429
430 @param arg: The caller-provided state parameter to be passed along
431 with the node and entry/exit status in the invocation of C{visit}.
432 """
433 raise NotImplementedError('%s._walkParticleTree' % (self.__class__.__name__,))
434
436 """This class is a mix-in which guarantees that only one instance
437 of the class will be created. It is used to ensure that the
438 ur-type instances are pointer-equivalent even when unpickling.
439 See ComplexTypeDefinition.UrTypeDefinition()."""
441 singleton_property = '_%s__singleton' % (cls.__name__,)
442 if not (singleton_property in cls.__dict__):
443 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
444 return cls.__dict__[singleton_property]
445
447 """Mix-in that supports an optional single annotation that describes the component.
448
449 Most schema components have annotations. The ones that don't are
450 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
451 and L{Schema} support multiple annotations, so do not mix-in this
452 class."""
453
454
455 __annotation = None
456
460
468
470 """Override fields in this instance with those from the other.
471
472 Post-extended; description in leaf implementation in
473 ComplexTypeDefinition and SimpleTypeDefinition."""
474 assert self != other
475 self_fn = lambda *_args, **_kw: self
476 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', self_fn)(other)
477
478 self.__annotation = other.__annotation
479 return self
480
483
485 """A helper that encapsulates a reference to an anonymous type in a different namespace.
486
487 Normally references to components in other namespaces can be made using
488 the component's name. This is not the case when a namespace derives from
489 a base type in another namespace and needs to reference the attribute or
490 element declarations held in that type. If these declarations are local
491 to the base complex type, they cannot be identified by name. This class
492 provides a pickleable representation for them that behaves rather like an
493 L{pyxb.namespace.ExpandedName} instance in that it can be used to
494 dereference various component types."""
495
496 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
497
498 __namespace = None
499 __anonymousName = None
500 - def __init__ (self, namespace, anonymous_name):
501 """Create a new anonymous reference.
502
503 @param namespace: The namespace in which the component is declared.
504 @type namespace: L{pyxb.namespace.Namespace}
505 @param anonymous_name: A generated name guaranteed to be unique within
506 the namespace. See L{_NamedComponent_mixin._anonymousName}.
507 @type anonymous_name: C{basestring}.
508 """
509 self.__namespace = namespace
510 self.__anonymousName = anonymous_name
511 assert self.__anonymousName is not None
512
513 @classmethod
515 """Return the component referred to by the provided reference,
516 regardless of whether it is a normal or anonymous reference."""
517 if not isinstance(object_reference, _PickledAnonymousReference):
518 assert isinstance(object_reference, tuple)
519 object_reference = pyxb.namespace.ExpandedName(object_reference)
520 return object_reference
521
524
527
531
534
535 typeDefinition = __lookupObject
536 attributeGroupDefinition = __lookupObject
537 modelGroupDefinition = __lookupObject
538 attributeDeclaration = __lookupObject
539 elementDeclaration = __lookupObject
540 identityConstraintDefinition = __lookupObject
541 notationDeclaration = __lookupObject
542
546
548 """Mix-in to hold the name and targetNamespace of a component.
549
550 The name may be None, indicating an anonymous component. The
551 targetNamespace is never None, though it could be an empty namespace. The
552 name and targetNamespace values are immutable after creation.
553
554 This class overrides the pickling behavior: when pickling a Namespace,
555 objects that do not belong to that namespace are pickled as references,
556 not as values. This ensures the uniqueness of objects when multiple
557 namespace definitions are pre-loaded.
558
559 This class must follow L{_SchemaComponent_mixin} in the MRO.
560 """
561
562 __PrivateTransient = set()
563
565 """Name of the component within its scope or namespace.
566
567 This is an NCName. The value isNone if the component is
568 anonymous. The attribute is immutable after the component is
569 created creation."""
570 return self.__name
571 __name = None
572
574 """Return true iff this instance is locally scoped (has no name)."""
575 return self.__name is None
576
601 __anonymousName = None
602
604 """The targetNamespace of a component.
605
606 This is None, or a reference to a Namespace in which the
607 component is declared (either as a global or local to one of
608 the namespace's complex type definitions). This is immutable
609 after creation.
610 """
611 return self.__targetNamespace
612 __targetNamespace = None
613
615 """The namespace in which this component's binding is placed."""
616 return self.__bindingNamespace
619 __bindingNamespace = None
620
622 """A map from template keys to component-specific values.
623
624 This is used in code generation to maintain unique names for accessor
625 methods, identifiers, keys, and other characteristics associated with
626 the code generated in support of the binding for this component."""
627 return self.__templateMap
628 __templateMap = None
629
630 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
631
637
639 """Return the schema component from which this component was defined.
640
641 Needed so we can distinguish components that came from different
642 locations, since that imposes an external order dependency on them and
643 on cross-namespace inclusions.
644
645 @note: This characteristic is removed when the component is stored in
646 a namespace archive."""
647 return self.__schema
648 __schema = None
649 __PrivateTransient.add('schema')
650
656
658 """Return C{True} if this component should be pickled by value in the
659 given namespace.
660
661 When pickling, a declaration component is considered to belong to the
662 namespace if it has a local scope which belongs to the namespace. In
663 that case, the declaration is a clone of something that does not
664 belong to the namespace; but the clone does.
665
666 @see: L{_bindsInNamespace}
667
668 @return: C{False} if the component should be pickled by reference.
669 """
670 if isinstance(self._scope(), ComplexTypeDefinition):
671 return self._scope()._picklesInArchive(archive)
672 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
673 assert not (self._objectOrigin() is None)
674 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
675 return new_flag
676
678 """Return C{True} if the binding for this component should be
679 generated in the given namespace.
680
681 This is the case when the component is in the given namespace. It's
682 also the case when the component has no associated namespace (but not
683 an absent namespace). Be aware that cross-namespace inheritance means
684 you will get references to elements in another namespace when
685 generating code for a subclass; that's fine, and those references
686 should not be generated locally.
687 """
688 return self.targetNamespace() in (ns, None)
689
695
697 """Pickling support.
698
699 Normally, we just create a new instance of this class.
700 However, if we're unpickling a reference in a loadable schema,
701 we need to return the existing component instance by looking
702 up the name in the component map of the desired namespace. We
703 can tell the difference because no normal constructors that
704 inherit from this have positional arguments; only invocations
705 by unpickling with a value returned in __getnewargs__ do.
706
707 This does require that the dependent namespace already have
708 been validated (or that it be validated here). That shouldn't
709 be a problem, except for the dependency loop resulting from
710 use of xml:lang in the XMLSchema namespace. For that issue,
711 see pyxb.namespace._XMLSchema.
712 """
713
714 if 0 == len(args):
715 rv = super(_NamedComponent_mixin, cls).__new__(cls)
716 return rv
717 ( object_reference, scope, icls ) = args
718
719 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
720
721
722
723 object_reference.validateComponentModel()
724 rv = None
725 if isinstance(scope, (tuple, _PickledAnonymousReference)):
726
727
728 scope_ref = _PickledAnonymousReference.FromPickled(scope)
729 if object_reference.namespace() != scope_ref.namespace():
730 scope_ref.validateComponentModel()
731 assert 'typeDefinition' in scope_ref.namespace().categories()
732 scope_ctd = scope_ref.typeDefinition()
733 if scope_ctd is None:
734 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
735 if issubclass(icls, AttributeDeclaration):
736 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
737 elif issubclass(icls, ElementDeclaration):
738 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
739 if rv is None:
740 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
741 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
742 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
743 rv = object_reference.typeDefinition()
744 elif issubclass(icls, AttributeGroupDefinition):
745 rv = object_reference.attributeGroupDefinition()
746 elif issubclass(icls, ModelGroupDefinition):
747 rv = object_reference.modelGroupDefinition()
748 elif issubclass(icls, AttributeDeclaration):
749 rv = object_reference.attributeDeclaration()
750 elif issubclass(icls, ElementDeclaration):
751 rv = object_reference.elementDeclaration()
752 elif issubclass(icls, IdentityConstraintDefinition):
753 rv = object_reference.identityConstraintDefinition()
754 if rv is None:
755 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
756 if rv is None:
757 raise pyxb.SchemaValidationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, (scope is None and "<unknown>" or scope.targetNamespace()), type(scope), icls))
758 return rv
759
780
782 """Return true iff this and the other component share the same name and target namespace.
783
784 Anonymous components are inherently name inequivalent, except to
785 themselves. This relies on equivalence as defined for
786 pyxb.namespace.ExpandedName, for which None is not equivalent to any
787 non-anonymous name."""
788
789 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
790
792 """Return True iff this and the other component have matching types.
793
794 It appears that name equivalence is used; two complex type definitions
795 with identical structures are not considered equivalent (at least, per
796 XMLSpy).
797 """
798 return (type(self) == type(other)) and self.isNameEquivalent(other)
799
801 """Return True iff this type can serve as a restriction of the other
802 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
803
804 It appears that name equivalence is normally used; two complex type
805 definitions with identical structures are not considered equivalent
806 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
807 that derivation by restriction from the other type is also acceptable.
808 That opens a whole can of worms; see
809 L{ElementDeclaration.isAdaptable}.
810 """
811 this = self
812
813 while this is not None:
814 if this.isTypeEquivalent(other):
815 return True
816
817 assert this.isResolved() and other.isResolved()
818 if isinstance(self, ComplexTypeDefinition):
819 if self.DM_restriction != this.derivationMethod():
820 return False
821 else:
822 assert isinstance(self, SimpleTypeDefinition)
823 if self._DA_restriction != this._derivationAlternative():
824 return False
825 if not this.baseTypeDefinition().isDerivationConsistent(other):
826 return False
827 this = this.baseTypeDefinition()
828 return False
829
835
853
878
880 """Pickling support.
881
882 If this instance is being pickled as a reference, provide the
883 arguments that are necessary so that the unpickler can locate
884 the appropriate component rather than create a duplicate
885 instance."""
886
887 if self.__pickleAsReference():
888 scope = self._scope()
889 if isinstance(self, _ScopedDeclaration_mixin):
890
891
892
893
894
895 if self.SCOPE_global == self.scope():
896 pass
897 elif isinstance(self.scope(), ComplexTypeDefinition):
898 scope = self.scope()._picklingReference()
899 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
900 else:
901 assert self._scopeIsIndeterminate()
902
903
904 else:
905 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
906 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
907
908 rv = ( self._picklingReference(), scope, self.__class__ )
909 return rv
910 return ()
911
928
938
940 """Mix-in indicating that the component contains a simple-type
941 value that may be constrained."""
942
943 VC_na = 0
944 VC_default = 1
945 VC_fixed = 2
946
947
948
949 __valueConstraint = None
951 """A constraint on the value of the attribute or element.
952
953 Either None, or a pair consisting of a string in the lexical
954 space of the typeDefinition and one of VC_default and
955 VC_fixed."""
956 return self.__valueConstraint
957
966
975
992
994 """Mix-in class for named components that have a scope.
995
996 Scope is important when doing cross-namespace inheritance,
997 e.g. extending or restricting a complex type definition that is
998 from a different namespace. In this case, we will need to retain
999 a reference to the external component when the schema is
1000 serialized.
1001
1002 This is done in the pickling process by including the scope when
1003 pickling a component as a reference. The scope is the
1004 SCOPE_global if global; otherwise, it is a tuple containing the
1005 external namespace URI and the NCName of the complex type
1006 definition in that namespace. We assume that the complex type
1007 definition has global scope; otherwise, it should not have been
1008 possible to extend or restrict it. (Should this be untrue, there
1009 are comments in the code about a possible solution.)
1010
1011 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
1012 """
1013
1014 SCOPE_global = 'global'
1015 XSCOPE_indeterminate = 'indeterminate'
1016
1017 @classmethod
1020
1021 @classmethod
1024
1025 @classmethod
1028
1030 """Return True if this scope currently assigned to this instance is compatible with the given scope.
1031
1032 If either scope is indeterminate, presume they will ultimately be
1033 compatible. Scopes that are equal are compatible, as is a local scope
1034 if this already has a global scope."""
1035 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
1036 return True
1037 if self.scope() == scope:
1038 return True
1039 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
1040
1041
1042
1043
1045 """The scope for the declaration.
1046
1047 Valid values are SCOPE_global, or a complex type definition.
1048 A value of None means a non-global declaration that is not
1049 owned by a complex type definition. These can only appear in
1050 attribute group definitions or model group definitions.
1051
1052 @todo: For declarations in named model groups (viz., local
1053 elements that aren't references), the scope needs to be set by
1054 the owning complex type.
1055 """
1056 return self._scope()
1057
1058
1059
1060
1061
1062 __baseDeclaration = None
1068
1070 """Support for components that accept attribute wildcards.
1071
1072 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1073 calculations of the appropriate wildcard are sufficiently complex that
1074 they need to be abstracted out to a mix-in class."""
1075
1076
1077 __attributeWildcard = None
1078
1080 """Return the L{Wildcard} component associated with attributes of this
1081 instance, or C{None} if attribute wildcards are not present in the
1082 instance."""
1083 return self.__attributeWildcard
1084
1086 """Set the attribute wildcard property for this instance."""
1087 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1088 self.__attributeWildcard = attribute_wildcard
1089 return self
1090
1092 """Return the nodes that are relevant for attribute processing.
1093
1094 @param node_list: A sequence of nodes found in a definition content
1095 information item.
1096
1097 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1098 where C{attributes} is the subsequence of C{node_list} that are
1099 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1100 C{attributeWildcard} is a single DOM node with XMLSchema name
1101 C{anyAttribute} (or C{None}, if no such node is present in the list).
1102
1103 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1104 present but does not have the required C{ref} attribute.
1105 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1106 identified.
1107 """
1108
1109 attributes = []
1110 attribute_groups = []
1111 any_attribute = None
1112
1113 for node in node_list:
1114 if Node.ELEMENT_NODE != node.nodeType:
1115 continue
1116 if xsd.nodeIsNamed(node, 'attribute'):
1117
1118 attributes.append(node)
1119 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1120
1121 agd_en = domutils.NodeAttributeQName(node, 'ref')
1122 if agd_en is None:
1123 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1124 attribute_groups.append(agd_en)
1125 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1126 if any_attribute is not None:
1127 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1128 any_attribute = node
1129
1130 return (attributes, attribute_groups, any_attribute)
1131
1132 @classmethod
1133 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1134 """Implement the algorithm as described the
1135 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1136
1137 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1138 associated with any created L{Wildcard} instance
1139 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1140 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1141 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1142 is relevant
1143 """
1144
1145
1146 agd_wildcards = []
1147 for agd in attribute_groups:
1148 assert isinstance(agd, AttributeGroupDefinition)
1149 if agd.attributeWildcard() is not None:
1150 agd_wildcards.append(agd.attributeWildcard())
1151 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1152
1153
1154 if 0 == len(agd_wildcards):
1155 return local_wildcard
1156
1157 if local_wildcard is not None:
1158
1159 return Wildcard(process_contents=local_wildcard.processContents(),
1160 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1161 annotation=local_wildcard.annotation(),
1162 namespace_context=namespace_context)
1163
1164 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1165 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1166 namespace_context=namespace_context)
1167
1168 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1169 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1170 """
1171
1172
1173 __typeDefinition = None
1175 """The simple type definition to which an attribute value must
1176 conform."""
1177 return self.__typeDefinition
1178
1179
1180 __typeExpandedName = None
1181
1185
1190
1191 @classmethod
1204
1205
1206 @classmethod
1208 """Create an attribute declaration from the given DOM node.
1209
1210 wxs is a Schema instance within which the attribute is being
1211 declared.
1212
1213 node is a DOM element. The name must be one of ( 'all',
1214 'choice', 'sequence' ), and the node must be in the XMLSchema
1215 namespace.
1216
1217 scope is the _ScopeDeclaration_mxin context into which the
1218 attribute declaration is placed. It can be SCOPE_global, a
1219 complex type definition, or XSCOPE_indeterminate if this is an
1220 anonymous declaration within an attribute group. It is a
1221 required parameter for this function.
1222 """
1223
1224 scope = kw['scope']
1225 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1226
1227
1228 assert xsd.nodeIsNamed(node, 'attribute')
1229
1230 name = domutils.NodeAttribute(node, 'name')
1231
1232
1233 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1234 assert cls.SCOPE_global == scope
1235 elif domutils.NodeAttribute(node, 'ref') is None:
1236
1237 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1238 else:
1239 raise pyxb.SchemaValidationError('Internal attribute declaration by reference')
1240
1241 rv = cls(name=name, node=node, **kw)
1242 rv._annotationFromDOM(node)
1243 rv._valueConstraintFromDOM(node)
1244
1245 rv.__typeExpandedName = domutils.NodeAttributeQName(node, 'type')
1246
1247 kw.pop('node', None)
1248 kw['owner'] = rv
1249
1250 st_node = domutils.LocateUniqueChild(node, 'simpleType')
1251 if st_node is not None:
1252 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw)
1253 elif rv.__typeExpandedName is None:
1254 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition()
1255
1256 if rv.__typeDefinition is None:
1257 rv._queueForResolution('creation')
1258 return rv
1259
1262
1263
1278
1280 """Override fields in this instance with those from the other.
1281
1282 This method is invoked only by Schema._addNamedComponent, and
1283 then only when a built-in type collides with a schema-defined
1284 type. Material like facets is not (currently) held in the
1285 built-in copy, so the DOM information is copied over to the
1286 built-in STD, which is subsequently re-resolved.
1287
1288 Returns self.
1289 """
1290 assert self != other
1291 assert self.name() is not None
1292 assert self.isNameEquivalent(other)
1293 super(AttributeDeclaration, self)._updateFromOther_csc(other)
1294
1295
1296
1297 if not other.isResolved():
1298 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID():
1299
1300 _log.warning('Not destroying builtin %s: %s', self.expandedName(), self.__typeDefinition)
1301 else:
1302 self.__typeDefinition = None
1303 return self
1304
1305
1307 """Attribute declarations require their type."""
1308 return frozenset([ self.__typeDefinition ])
1309
1310 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1311 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component."""
1312
1313
1314
1315 __use = None
1316
1317 USE_required = 0x01
1318 USE_optional = 0x02
1319 USE_prohibited = 0x04
1320
1323
1326
1327
1328 __refExpandedName = None
1329
1330 __restrictionOf = None
1338
1339
1341 """The attribute declaration for this use.
1342
1343 When the use scope is assigned, the declaration is cloned (if
1344 necessary) so that each declaration corresponds to only one use. We
1345 rely on this in code generation, because the template map for the use
1346 is stored in its declaration."""
1347 return self.__attributeDeclaration
1348 __attributeDeclaration = None
1349
1350
1353
1368
1369 @classmethod
1378
1379
1380 @classmethod
1382 """Create an Attribute Use from the given DOM node.
1383
1384 wxs is a Schema instance within which the attribute use is
1385 being defined.
1386
1387 node is a DOM element. The name must be 'attribute', and the
1388 node must be in the XMLSchema namespace.
1389
1390 scope is the _ScopeDeclaration_mixin context into which any
1391 required anonymous attribute declaration is put. This must be
1392 a complex type definition, or None if this use is in an
1393 attribute group.
1394 """
1395
1396 scope = kw['scope']
1397 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1398 assert xsd.nodeIsNamed(node, 'attribute')
1399 schema = kw['schema']
1400 rv = cls(node=node, **kw)
1401
1402 rv.__use = cls.USE_optional
1403 use = domutils.NodeAttribute(node, 'use')
1404 if use is not None:
1405 if 'required' == use:
1406 rv.__use = cls.USE_required
1407 elif 'optional' == use:
1408 rv.__use = cls.USE_optional
1409 elif 'prohibited' == use:
1410 rv.__use = cls.USE_prohibited
1411 else:
1412 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1413
1414 rv._valueConstraintFromDOM(node)
1415
1416 rv.__refExpandedName = domutils.NodeAttributeQName(node, 'ref')
1417 if rv.__refExpandedName is None:
1418
1419 kw.pop('node', None)
1420 kw['owner'] = rv
1421 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1422 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1423
1424 if not rv.isResolved():
1425 rv._queueForResolution('creation')
1426
1427 return rv
1428
1431
1442
1443
1445 """Attribute uses require their declarations, but only if lax."""
1446 if not include_lax:
1447 return frozenset()
1448 return frozenset([ self.attributeDeclaration() ])
1449
1450
1470
1473
1474
1475 -class ElementDeclaration (_ParticleTree_mixin, _SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1476 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1477
1478
1479 __typeDefinition = None
1481 """The simple or complex type to which the element value conforms."""
1482 return self.__typeDefinition
1506
1507 __substitutionGroupExpandedName = None
1508
1509 __typeExpandedName = None
1510
1511 __nillable = False
1514
1515 __identityConstraintDefinitions = None
1519
1520 __substitutionGroupAffiliation = None
1524
1525 SGE_none = 0
1526 SGE_extension = 0x01
1527 SGE_restriction = 0x02
1528 SGE_substitution = 0x04
1529
1530 _SGE_Map = { 'extension' : SGE_extension
1531 , 'restriction' : SGE_restriction }
1532 _DS_Map = _SGE_Map.copy()
1533 _DS_Map.update( { 'substitution' : SGE_substitution } )
1534
1535
1536 __substitutionGroupExclusions = SGE_none
1537
1538
1539 __disallowedSubstitutions = SGE_none
1540
1541 __abstract = False
1544
1546 """Return False, since element declarations are not wildcards."""
1547 return False
1548
1549
1551 """Element declarations depend on the type definition of their
1552 content."""
1553 return frozenset([self.__typeDefinition])
1554
1557
1558
1559 @classmethod
1561 """Create an element declaration from the given DOM node.
1562
1563 wxs is a Schema instance within which the element is being
1564 declared.
1565
1566 scope is the _ScopeDeclaration_mixin context into which the
1567 element declaration is recorded. It can be SCOPE_global, a
1568 complex type definition, or None in the case of elements
1569 declared in a named model group.
1570
1571 node is a DOM element. The name must be 'element', and the
1572 node must be in the XMLSchema namespace."""
1573
1574 scope = kw['scope']
1575 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1576
1577
1578 assert xsd.nodeIsNamed(node, 'element')
1579
1580
1581 name = domutils.NodeAttribute(node, 'name')
1582 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1583 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1584 elif domutils.NodeAttribute(node, 'ref') is None:
1585
1586 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1587 else:
1588 raise pyxb.SchemaValidationError('Created reference as element declaration')
1589
1590 rv = cls(name=name, node=node, **kw)
1591 rv._annotationFromDOM(node)
1592 rv._valueConstraintFromDOM(node)
1593
1594 rv.__substitutionGroupExpandedName = domutils.NodeAttributeQName(node, 'substitutionGroup')
1595
1596 kw.pop('node', None)
1597 kw['owner'] = rv
1598
1599 identity_constraints = []
1600 for cn in node.childNodes:
1601 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1602 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1603 rv.__identityConstraintDefinitions = identity_constraints
1604
1605 rv.__typeDefinition = None
1606 rv.__typeExpandedName = domutils.NodeAttributeQName(node, 'type')
1607 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1608 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1609 if rv.__typeExpandedName is not None:
1610 if (simpleType_node is not None) and (complexType_node is not None):
1611 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1612 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1613 rv._typeDefinition(SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw))
1614 if (rv.__typeDefinition is None) and (complexType_node is not None):
1615 rv._typeDefinition(ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw))
1616 if rv.__typeDefinition is None:
1617 if rv.__typeExpandedName is None:
1618
1619 for cn in node.childNodes:
1620 if Particle.IsParticleNode(cn):
1621 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1622 rv._typeDefinition(ComplexTypeDefinition.UrTypeDefinition())
1623 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupExpandedName is None)
1624 if not rv.__isResolved:
1625 rv._queueForResolution('creation')
1626
1627 attr_val = domutils.NodeAttribute(node, 'nillable')
1628 if attr_val is not None:
1629 rv.__nillable = datatypes.boolean(attr_val)
1630
1631 attr_val = domutils.NodeAttribute(node, 'abstract')
1632 if attr_val is not None:
1633 rv.__abstract = datatypes.boolean(attr_val)
1634
1635 schema = kw['schema']
1636 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1637 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1638
1639 return rv
1640
1642 """Determine whether this element declaration is adaptable.
1643
1644 OK, this gets ugly. First, if this declaration isn't resolved, it's
1645 clearly not adaptable.
1646
1647 Now: For it to be adaptable, we must know enough about its type to
1648 verify that it is derivation-consistent with any other uses of the
1649 same name in the same complex type. If the element's type is
1650 resolved, that's good enough.
1651
1652 If the element's type isn't resolved, we're golden as long as
1653 type-equivalent types were used. But it's also allowed for the
1654 derived ctd to use the element name constraining it to a derivation of
1655 the element base type. (Go see namespace
1656 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1657 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1658 have to have the element's type resolved.
1659
1660 Except that if a CTD's content incorporates an element with the same
1661 type as the CTD (i.e., nested), this will never happen, because the
1662 CTD can't get resolved until after it has been resolved.
1663 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1664 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1665 an example).
1666
1667 So, we give the world a break and assume that if the type we're trying
1668 to resolve is the same as the type of an element in that type, then
1669 the element type will be resolved by the point it's needed. In point
1670 of fact, it won't, but we'll only notice that if a CTD contains an
1671 element whose type is a restriction of the CTD. In that case,
1672 isDerivationConsistent will blow chunks and somebody'll have to come
1673 back and finish up this mess.
1674 """
1675
1676 if not self.isResolved():
1677 return False
1678 if self.typeDefinition().isResolved():
1679 return True
1680
1681
1682 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1683 if existing_decl is None:
1684
1685
1686 return True
1687
1688 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1689
1690 return True
1691
1692
1693 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1694 return False
1695
1696
1706
1707 __isResolved = False
1710
1711
1732
1733 - def _walkParticleTree (self, visit, arg):
1734 visit(self, None, arg)
1735
1740
1741
1742 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1743 __PrivateTransient = set()
1744
1745
1746 __baseTypeDefinition = None
1750
1751 DM_empty = 0
1752 DM_extension = 0x01
1753 DM_restriction = 0x02
1754
1755 _DM_Map = { 'extension' : DM_extension
1756 , 'restriction' : DM_restriction }
1757
1758
1759
1760 __derivationMethod = None
1764
1765
1766 __final = DM_empty
1767
1768
1769 __abstract = False
1772
1773
1774 __attributeUses = None
1776 """A frozenset() of AttributeUse instances."""
1777 return self.__attributeUses
1778
1779
1780
1781 __scopedAttributeDeclarations = None
1783 """Find an attribute declaration with the given name that is local to this type.
1784
1785 Returns None if there is no such local attribute declaration."""
1786 if self.__scopedAttributeDeclarations is None:
1787 return None
1788 return self.__scopedAttributeDeclarations.get(expanded_name)
1789
1790
1791
1792 __scopedElementDeclarations = None
1794 """Find an element declaration with the given name that is local to this type.
1795
1796 Returns None if there is no such local element declaration."""
1797 if self.__scopedElementDeclarations is None:
1798 return None
1799 return self.__scopedElementDeclarations.get(expanded_name)
1800
1801 __localScopedDeclarations = None
1823
1825 """Record the given declaration as being locally scoped in
1826 this type."""
1827 assert isinstance(decl, _ScopedDeclaration_mixin)
1828 if isinstance(decl, ElementDeclaration):
1829 scope_map = self.__scopedElementDeclarations
1830 elif isinstance(decl, AttributeDeclaration):
1831 scope_map = self.__scopedAttributeDeclarations
1832 else:
1833 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1834 decl_en = decl.expandedName()
1835 existing_decl = scope_map.setdefault(decl_en, decl)
1836 if decl != existing_decl:
1837 if isinstance(decl, ElementDeclaration):
1838
1839 existing_type = existing_decl.typeDefinition()
1840 pending_type = decl.typeDefinition()
1841 if not pending_type.isDerivationConsistent(existing_type):
1842 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1843 elif isinstance(decl, AttributeDeclaration):
1844 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1845 else:
1846 assert False, 'Unrecognized type %s' % (type(decl),)
1847 decl._baseDeclaration(existing_decl)
1848 return self
1849
1855
1856 CT_EMPTY = 'EMPTY'
1857 CT_SIMPLE = 'SIMPLE'
1858 CT_MIXED = 'MIXED'
1859 CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1860
1861 - def _contentTypeTag (self):
1862 """Return the value of the content type identifier, i.e. one of the
1863 CT_ constants. Return value is None if no content type has been
1864 defined."""
1865 if isinstance(self.__contentType, tuple):
1866 return self.__contentType[0]
1867 return self.__contentType
1868
1870 if isinstance(self.__contentType, tuple):
1871 return self.__contentType[1]
1872 return None
1873
1874
1875 __contentType = None
1876 - def contentType (self):
1877 """Identify the sort of content in this type.
1878
1879 Valid values are:
1880 - C{CT_EMPTY}
1881 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1882 - ( C{CT_MIXED}, a L{Particle} instance )
1883 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1884 """
1885 return self.__contentType
1886
1888 if self.CT_EMPTY == self.contentType():
1889 return 'EMPTY'
1890 ( tag, particle ) = self.contentType()
1891 if self.CT_SIMPLE == tag:
1892 return 'Simple [%s]' % (particle,)
1893 if self.CT_MIXED == tag:
1894 return 'Mixed [%s]' % (particle,)
1895 if self.CT_ELEMENT_ONLY == tag:
1896 return 'Element [%s]' % (particle,)
1897 raise pyxb.LogicError('Unhandled content type')
1898
1899
1900 __prohibitedSubstitutions = DM_empty
1901
1902
1903 __annotations = None
1904
1910
1920
1922 """Override fields in this instance with those from the other.
1923
1924 This method is invoked only by Schema._addNamedComponent, and
1925 then only when a built-in type collides with a schema-defined
1926 type. Material like facets is not (currently) held in the
1927 built-in copy, so the DOM information is copied over to the
1928 built-in STD, which is subsequently re-resolved.
1929
1930 Returns self.
1931 """
1932 assert self != other
1933 assert self.isNameEquivalent(other)
1934 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1935
1936 if not other.isResolved():
1937 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1938 self.__derivationMethod = None
1939
1940 return self
1941
1942 __UrTypeDefinition = None
1943 @classmethod
1945 """Create the ComplexTypeDefinition instance that approximates
1946 the ur-type.
1947
1948 See section 3.4.7.
1949 """
1950
1951
1952
1953
1954
1955
1956
1957 if cls.__UrTypeDefinition is None:
1958
1959 assert schema is not None
1960
1961 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1962
1963 kw = { 'name' : 'anyType',
1964 'schema' : schema,
1965 'namespace_context' : ns_ctx,
1966 'binding_namespace' : schema.targetNamespace(),
1967 'derivation_method' : cls.DM_restriction,
1968 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1969 bi = _UrTypeDefinition(**kw)
1970
1971
1972 bi.__baseTypeDefinition = bi
1973
1974
1975 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1976
1977
1978
1979
1980
1981
1982 kw = { 'namespace_context' : ns_ctx
1983 , 'schema' : schema
1984 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
1985 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
1986 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
1987 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
1988 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
1989
1990
1991 bi.__attributeUses = set()
1992
1993
1994 bi.__final = cls.DM_empty
1995 bi.__prohibitedSubstitutions = cls.DM_empty
1996
1997 bi.__abstract = False
1998
1999
2000 bi.setNameInBinding(bi.name())
2001
2002
2003 bi.__derivationMethod = cls.DM_restriction
2004
2005 cls.__UrTypeDefinition = bi
2006 return cls.__UrTypeDefinition
2007
2009 """Indicate whether this simple type is a built-in type."""
2010 return (self.UrTypeDefinition() == self)
2011
2012
2028
2029
2030 @classmethod
2054
2055 __baseExpandedName = None
2056
2057 __ckw = None
2058 __anyAttribute = None
2059 __attributeGroupNames = None
2060 __usesC1 = None
2061 __usesC1C2 = None
2062 __attributeGroups = None
2063 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupNames', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2064
2065
2067
2068 if self.__usesC1C2 is None:
2069
2070 uses_c1 = self.__usesC1
2071 uses_c2 = set()
2072 self.__attributeGroups = []
2073 for ag_en in self.__attributeGroupNames:
2074 agd = ag_en.attributeGroupDefinition()
2075 if agd is None:
2076 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2077 if not agd.isResolved():
2078 self._queueForResolution('unresolved attribute group', depends_on=agd)
2079 return self
2080 self.__attributeGroups.append(agd)
2081 uses_c2.update(agd.attributeUses())
2082
2083 uses_c1c2 = uses_c1.union(uses_c2)
2084 for au in uses_c1c2:
2085 if not au.isResolved():
2086 self._queueForResolution('attribute use not resolved')
2087 return self
2088 ad = au.attributeDeclaration()
2089 if not ad.isResolved():
2090 ad_en = ad.expandedName()
2091 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2092 return self
2093
2094 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2095
2096
2097
2098
2099
2100
2101 uses_c3 = set()
2102 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2103
2104
2105 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2106 assert self.__baseTypeDefinition.isResolved()
2107 for au in uses_c3:
2108 if not au.isResolved():
2109 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2110 return self
2111 ad = au.attributeDeclaration()
2112 if not ad.isResolved():
2113 ad_en = ad.expandedName()
2114 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2115 return self
2116 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2117
2118 if self.DM_restriction == method:
2119
2120
2121
2122 for au in self.__usesC1C2:
2123 matching_uses = au.matchingQNameMembers(uses_c3)
2124 assert matching_uses is not None
2125 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2126 for au2 in matching_uses:
2127 assert au2.isResolved()
2128 uses_c3.remove(au2)
2129 au._setRestrictionOf(au2)
2130 else:
2131
2132
2133
2134 assert self.DM_extension == method
2135
2136 use_map = { }
2137 for au in self.__usesC1C2.union(uses_c3):
2138 assert au.isResolved()
2139 ad_en = au.attributeDeclaration().expandedName()
2140 if ad_en in use_map:
2141 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2142 use_map[ad_en] = au
2143
2144
2145
2146 self.__attributeUses = frozenset(use_map.itervalues())
2147 if not self._scopeIsIndeterminate():
2148 for au in self.__attributeUses:
2149 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2150
2151
2152
2153 local_wildcard = None
2154 if self.__anyAttribute is not None:
2155 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2156
2157
2158 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2159
2160
2161 if self.DM_restriction == method:
2162
2163 self._setAttributeWildcard(complete_wildcard)
2164 else:
2165 assert (self.DM_extension == method)
2166 assert self.baseTypeDefinition().isResolved()
2167
2168 base_wildcard = None
2169 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2170 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2171
2172 if base_wildcard is not None:
2173 if complete_wildcard is None:
2174
2175 self._setAttributeWildcard(base_wildcard)
2176 else:
2177
2178 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2179 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2180 base_wildcard.namespaceConstraint()]),
2181 annotation=complete_wildcard.annotation(),
2182 namespace_context=self._namespaceContext()))
2183 else:
2184
2185 self._setAttributeWildcard(complete_wildcard)
2186
2187
2188
2189
2190 del self.__usesC1
2191 del self.__usesC1C2
2192 del self.__attributeGroups
2193 self.__ckw = None
2194
2195
2196
2197
2198 self.__derivationMethod = method
2199 return self
2200
2201 - def __simpleContent (self, method, **kw):
2202
2203 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2204
2205 parent_content_type = self.__baseTypeDefinition.__contentType
2206 if ((type(parent_content_type) == tuple) \
2207 and (self.CT_SIMPLE == parent_content_type[0]) \
2208 and (self.DM_restriction == method)):
2209
2210 assert self.__ctscRestrictionNode is not None
2211 std = self.__ctscClause2STD
2212 if std is None:
2213 std = parent_content_type[1]
2214 assert isinstance(std, SimpleTypeDefinition)
2215 if not std.isResolved():
2216 return None
2217 restriction_node = self.__ctscRestrictionNode
2218 self.__ctscClause2STD = None
2219 self.__ctscRestrictionNode = None
2220 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2221 if ((type(parent_content_type) == tuple) \
2222 and (self.CT_MIXED == parent_content_type[0]) \
2223 and parent_content_type[1].isEmptiable()):
2224
2225 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2226 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2227
2228 return parent_content_type
2229
2230 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2231
2232 __ctscClause2STD = None
2233 __ctscRestrictionNode = None
2234 __PrivateTransient.update(['ctscRestrictionNode' ])
2235 __effectiveMixed = None
2236 __effectiveContent = None
2237 __pendingDerivationMethod = None
2238 __isComplexContent = None
2239 - def _isComplexContent (self):
2241 __ctscRestrictionMode = None
2242 __contentStyle = None
2243
2244 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2245
2246
2247 ckw = kw.copy()
2248 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2249
2250
2251 mixed_attr = None
2252 if content_node is not None:
2253 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2254 if mixed_attr is None:
2255 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2256 if mixed_attr is not None:
2257 effective_mixed = datatypes.boolean(mixed_attr)
2258 else:
2259 effective_mixed = False
2260
2261
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 domutils.HasNonAnnotationChild(cn)):
2277 test_2_1_2 = True
2278 if xsd.nodeIsNamed(cn, 'choice') \
2279 and (not domutils.HasNonAnnotationChild(cn)):
2280 mo_attr = domutils.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 - def __complexContent (self, method):
2316 ckw = self.__ckw
2317
2318
2319 if self.__effectiveMixed:
2320 ct = self.CT_MIXED
2321 else:
2322 ct = self.CT_ELEMENT_ONLY
2323
2324 if self.DM_restriction == method:
2325
2326 if self.CT_EMPTY == self.__effectiveContent:
2327
2328 content_type = self.CT_EMPTY
2329 else:
2330
2331 content_type = ( ct, self.__effectiveContent )
2332 assert 0 == len(self.__scopedElementDeclarations)
2333
2334
2335
2336
2337 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2338 else:
2339
2340 assert self.DM_extension == method
2341 assert self.__baseTypeDefinition.isResolved()
2342 parent_content_type = self.__baseTypeDefinition.contentType()
2343 if self.CT_EMPTY == self.__effectiveContent:
2344 content_type = parent_content_type
2345 elif self.CT_EMPTY == parent_content_type:
2346
2347 content_type = ( ct, self.__effectiveContent )
2348 else:
2349 assert type(parent_content_type) == tuple
2350 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2351 content_type = ( ct, Particle(m, **ckw) )
2352
2353 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2354 return content_type
2355
2357 """Indicate whether this complex type is fully defined.
2358
2359 All built-in type definitions are resolved upon creation.
2360 Schema-defined type definitionss are held unresolved until the
2361 schema has been completely read, so that references to later
2362 schema-defined types can be resolved. Resolution is performed
2363 after the entire schema has been scanned and type-definition
2364 instances created for all topLevel{Simple,Complex}Types.
2365
2366 If a built-in type definition is also defined in a schema
2367 (which it should be), the built-in definition is kept, with
2368 the schema-related information copied over from the matching
2369 schema-defined type definition. The former then replaces the
2370 latter in the list of type definitions to be resolved. See
2371 Schema._addNamedComponent.
2372 """
2373
2374 return (self.__derivationMethod is not None)
2375
2376
2377
2381
2382 - def __setContentFromDOM (self, node, **kw):
2383 schema = kw.get('schema')
2384 assert schema is not None
2385 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2386 self.__final = schema.finalForNode(node, self._DM_Map)
2387
2388 attr_val = domutils.NodeAttribute(node, 'abstract')
2389 if attr_val is not None:
2390 self.__abstract = datatypes.boolean(attr_val)
2391
2392
2393
2394 definition_node_list = node.childNodes
2395 is_complex_content = True
2396 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2397 method = self.DM_restriction
2398
2399
2400
2401
2402 first_elt = domutils.LocateFirstChildElement(node)
2403 content_node = None
2404 clause2_std = None
2405 ctsc_restriction_node = None
2406 if first_elt:
2407 have_content = False
2408 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2409 have_content = True
2410 is_complex_content = False
2411 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2412 have_content = True
2413 else:
2414
2415
2416 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2417 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2418 if have_content:
2419
2420 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2421 assert content_node == first_elt
2422
2423
2424
2425 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2426 if xsd.nodeIsNamed(ions, 'restriction'):
2427 method = self.DM_restriction
2428 if not is_complex_content:
2429
2430 ctsc_restriction_node = ions
2431 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2432 if ions_st is not None:
2433 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2434 elif xsd.nodeIsNamed(ions, 'extension'):
2435 method = self.DM_extension
2436 else:
2437 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2438 self.__baseExpandedName = domutils.NodeAttributeQName(ions, 'base')
2439 if self.__baseExpandedName is None:
2440 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2441 self.__baseTypeDefinition = None
2442
2443 definition_node_list = ions.childNodes
2444
2445 self.__pendingDerivationMethod = method
2446 self.__isComplexContent = is_complex_content
2447 self.__ctscRestrictionNode = ctsc_restriction_node
2448 self.__ctscClause2STD = clause2_std
2449
2450 (attributes, attribute_group_names, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2451 self.__usesC1 = set()
2452 for cn in attributes:
2453 au = AttributeUse.CreateFromDOM(cn, **kw)
2454 self.__usesC1.add(au)
2455 self.__attributeGroupNames = attribute_group_names
2456 self.__anyAttribute = any_attribute
2457
2458 if self.__isComplexContent:
2459 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2460
2461
2462
2463 self._annotationFromDOM(node)
2464
2465 if not self.isResolved():
2466 self._queueForResolution('creation')
2467
2468 return self
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2533
2535 """Complex type definitions have no built-in type support."""
2536 return None
2537
2542
2544 """Subclass ensures there is only one ur-type."""
2546 """The ur-type does have a Python class backing it up."""
2547 return datatypes.anyType
2548
2553
2554
2555 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2556 """An XMLSchema U{Attribute Group Definition<http://www.w3.org/TR/xmlschema-1/#cAttribute_Group_Definitions>} component."""
2557 __PrivateTransient = set()
2558
2559
2560 __attributeUses = None
2561
2564
2565
2566
2569
2570 @classmethod
2581
2582 __anyAttribute = None
2583 __attributeGroupNames = None
2584 __PrivateTransient.update(['anyAttribute', 'attributeGroupNames'])
2585
2586
2587 @classmethod
2623
2624
2625 __isResolved = False
2628
2652
2653
2655 """Attribute group declarations require their uses, but only if lax."""
2656 if not include_lax:
2657 return frozenset()
2658 return frozenset(self.attributeUses())
2659
2662
2664 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2665
2666 __modelGroup = None
2667
2669 """The model group for which this definition provides a name."""
2670 return self.__modelGroup
2671
2672
2673 @classmethod
2675 """Create a Model Group Definition from a DOM element node.
2676
2677 wxs is a Schema instance within which the model group is being
2678 defined.
2679
2680 node is a DOM element. The name must be 'group', and the node
2681 must be in the XMLSchema namespace. The node must have a
2682 'name' attribute, and must not have a 'ref' attribute.
2683 """
2684 assert xsd.nodeIsNamed(node, 'group')
2685
2686 assert domutils.NodeAttribute(node, 'ref') is None
2687
2688 name = domutils.NodeAttribute(node, 'name')
2689 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2690 rv = cls(name=name, node=node, **kw)
2691 rv._annotationFromDOM(node)
2692
2693 kw.pop('node', None)
2694 kw['owner'] = rv
2695
2696 for cn in node.childNodes:
2697 if Node.ELEMENT_NODE != cn.nodeType:
2698 continue
2699 if ModelGroup.IsGroupMemberNode(cn):
2700 assert not rv.__modelGroup
2701
2702
2703
2704 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2705 assert rv.__modelGroup is not None
2706 return rv
2707
2708
2710 """Model group definitions depend on the contained model group."""
2711 if not include_lax:
2712 return frozenset()
2713 return frozenset([self.__modelGroup])
2714
2717
2718
2719 -class ModelGroup (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
2720 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2721 C_INVALID = 0
2722 C_ALL = 0x01
2723 C_CHOICE = 0x02
2724 C_SEQUENCE = 0x03
2725
2726
2727
2728 __compositor = C_INVALID
2731
2732 @classmethod
2742
2746
2747
2748
2749 __particles = None
2750 - def particles (self):
2751 return self.__particles
2752
2754 """A model group has an unresolvable particle if any of its
2755 particles is unresolvable. Duh."""
2756 for p in self.particles():
2757 if not p.isAdaptable(ctd):
2758 return False
2759 return True
2760
2762 """Return the minimum and maximum of the number of elements that can
2763 appear in a sequence matched by this particle.
2764
2765 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2766 """
2767 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2768 sum_minoccurs = 0
2769 sum_maxoccurs = 0
2770 for prt in self.__particles:
2771 (prt_min, prt_max) = prt.effectiveTotalRange()
2772 sum_minoccurs += prt_min
2773 if sum_maxoccurs is not None:
2774 if prt_max is None:
2775 sum_maxoccurs = None
2776 else:
2777 sum_maxoccurs += prt_max
2778 prod_maxoccurs = particle.maxOccurs()
2779 if prod_maxoccurs is not None:
2780 if sum_maxoccurs is None:
2781 prod_maxoccurs = None
2782 else:
2783 prod_maxoccurs *= sum_maxoccurs
2784 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2785 assert self.__compositor == self.C_CHOICE
2786 if 0 == len(self.__particles):
2787 min_minoccurs = 0
2788 max_maxoccurs = 0
2789 else:
2790 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2791 for prt in self.__particles[1:]:
2792 (prt_min, prt_max) = prt.effectiveTotalRange()
2793 if prt_min < min_minoccurs:
2794 min_minoccurs = prt_min
2795 if prt_max is None:
2796 max_maxoccurs = None
2797 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2798 max_maxoccurs = prt_max
2799 min_minoccurs *= particle.minOccurs()
2800 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2801 max_maxoccurs *= particle.maxOccurs()
2802 return (min_minoccurs, max_maxoccurs)
2803
2804
2805
2806
2807 __modelGroupDefinition = None
2809 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2810 return self.__modelGroupDefinition
2811
2812 - def __init__ (self, compositor, particles, *args, **kw):
2813 """Create a new model group.
2814
2815 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2816
2817 particles must be a list of zero or more Particle instances.
2818
2819 scope is the _ScopeDeclaration_mixin context into which new
2820 declarations are recorded. It can be SCOPE_global, a complex
2821 type definition, or None if this is (or is within) a named
2822 model group.
2823
2824 model_group_definition is an instance of ModelGroupDefinition
2825 if this is a named model group. It defaults to None
2826 indicating a local group.
2827 """
2828
2829 super(ModelGroup, self).__init__(*args, **kw)
2830 assert 'scope' in kw
2831 self.__compositor = compositor
2832 self.__particles = particles
2833 self.__modelGroupDefinition = kw.get('model_group_definition')
2834
2836 """Return True if the model includes a wildcard amongst its particles."""
2837 for p in self.particles():
2838 if p.hasWildcardElement():
2839 return True
2840 return False
2841
2842
2844 if not include_lax:
2845 return frozenset()
2846 return frozenset(self.__particles)
2847
2848
2849 @classmethod
2851 """Create a model group from the given DOM node.
2852
2853 wxs is a Schema instance within which the model group is being
2854 defined.
2855
2856 node is a DOM element. The name must be one of ( 'all',
2857 'choice', 'sequence' ), and the node must be in the XMLSchema
2858 namespace.
2859
2860 scope is the _ScopeDeclaration_mxin context that is assigned
2861 to declarations that appear within the model group. It can be
2862 None, indicating no scope defined, or a complex type
2863 definition.
2864 """
2865
2866 scope = kw['scope']
2867 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2868
2869 if xsd.nodeIsNamed(node, 'all'):
2870 compositor = cls.C_ALL
2871 elif xsd.nodeIsNamed(node, 'choice'):
2872 compositor = cls.C_CHOICE
2873 else:
2874 assert xsd.nodeIsNamed(node, 'sequence')
2875 compositor = cls.C_SEQUENCE
2876 particles = []
2877
2878 kw.pop('owner', None)
2879 for cn in node.childNodes:
2880 if Node.ELEMENT_NODE != cn.nodeType:
2881 continue
2882 if Particle.IsParticleNode(cn):
2883
2884 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2885 elif not xsd.nodeIsNamed(cn, 'annotation'):
2886 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2887 rv = cls(compositor, particles, node=node, **kw)
2888 for p in particles:
2889 p._setOwner(rv)
2890 rv._annotationFromDOM(node)
2891 return rv
2892
2893 @classmethod
2896
2897
2908
2909 - def _walkParticleTree (self, visit, arg):
2910 visit(self, True, arg)
2911 for p in self.particles():
2912 p._walkParticleTree(visit, arg)
2913 visit(self, False, arg)
2914
2924
2925 -class Particle (_ParticleTree_mixin, _SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2926 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2927
2928
2929 __minOccurs = 1
2930 - def minOccurs (self):
2931 """The minimum number of times the term may appear.
2932
2933 Defaults to 1."""
2934 return self.__minOccurs
2935
2936
2937 __maxOccurs = 1
2938 - def maxOccurs (self):
2939 """Upper limit on number of times the term may appear.
2940
2941 If None, the term may appear any number of times; otherwise,
2942 this is an integral value indicating the maximum number of times
2943 the term may appear. The default value is 1; the value, unless
2944 None, must always be at least minOccurs().
2945 """
2946 return self.__maxOccurs
2947
2948
2949 __term = None
2951 """A reference to a ModelGroup, Wildcard, or ElementDeclaration."""
2952 return self.__term
2953 __pendingTerm = None
2954
2955 __refExpandedName = None
2956 __resolvableType = None
2957
2959 """Extend the concept of effective total range to all particles.
2960
2961 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
2962 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
2963 """
2964 if isinstance(self.__term, ModelGroup):
2965 return self.__term.effectiveTotalRange(self)
2966 return (self.minOccurs(), self.maxOccurs())
2967
2968 - def isEmptiable (self):
2969 """Return C{True} iff this particle can legitimately match an empty
2970 sequence (no content).
2971
2972 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
2973 """
2974 return 0 == self.effectiveTotalRange()[0]
2975
2977 """Return True iff this particle has a wildcard in its term.
2978
2979 Note that the wildcard may be in a nested model group."""
2980 return self.term().hasWildcardElement()
2981
2982 - def __init__ (self, term, *args, **kw):
2983 """Create a particle from the given DOM node.
2984
2985 term is a XML Schema Component: one of ModelGroup,
2986 ElementDeclaration, and Wildcard.
2987
2988 The following keyword arguments are processed:
2989
2990 min_occurs is a non-negative integer value with default 1,
2991 denoting the minimum number of terms required by the content
2992 model.
2993
2994 max_occurs is a positive integer value with default 1, or None
2995 indicating unbounded, denoting the maximum number of terms
2996 allowed by the content model.
2997
2998 scope is the _ScopeDeclaration_mxin context that is assigned
2999 to declarations that appear within the particle. It can be
3000 None, indicating no scope defined, or a complex type
3001 definition.
3002 """
3003
3004 super(Particle, self).__init__(*args, **kw)
3005
3006 min_occurs = kw.get('min_occurs', 1)
3007 max_occurs = kw.get('max_occurs', 1)
3008
3009 assert 'scope' in kw
3010 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
3011
3012 if term is not None:
3013 self.__term = term
3014
3015 assert isinstance(min_occurs, (types.IntType, types.LongType))
3016 self.__minOccurs = min_occurs
3017 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
3018 self.__maxOccurs = max_occurs
3019 if self.__maxOccurs is not None:
3020 if self.__minOccurs > self.__maxOccurs:
3021 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3022
3023
3024 - def _resolve (self):
3025 if self.isResolved():
3026 return self
3027
3028
3029 if ModelGroup == self.__resolvableType:
3030 group_decl = self.__refExpandedName.modelGroupDefinition()
3031 if group_decl is None:
3032 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (self.__refExpandedName,))
3033
3034 self.__pendingTerm = group_decl.modelGroup()
3035 assert self.__pendingTerm is not None
3036 elif ElementDeclaration == self.__resolvableType:
3037
3038
3039
3040 if self.__refExpandedName is not None:
3041 assert self.__pendingTerm is None
3042 self.__pendingTerm = self.__refExpandedName.elementDeclaration()
3043 if self.__pendingTerm is None:
3044 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (self.__refExpandedName,))
3045 assert self.__pendingTerm is not None
3046
3047
3048
3049
3050 assert self.__pendingTerm is not None
3051 else:
3052 assert False
3053
3054 self.__term = self.__pendingTerm
3055 assert self.__term is not None
3056
3057 return self
3058
3059 - def isResolved (self):
3060 return self.__term is not None
3061
3062
3063 @classmethod
3064 - def CreateFromDOM (cls, node, **kw):
3065 """Create a particle from the given DOM node.
3066
3067 wxs is a Schema instance within which the model group is being
3068 defined.
3069
3070 node is a DOM element. The name must be one of ( 'group',
3071 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3072 must be in the XMLSchema namespace.
3073
3074 scope is the _ScopeDeclaration_mxin context that is assigned
3075 to declarations that appear within the model group. It can be
3076 None, indicating no scope defined, or a complex type
3077 definition.
3078 """
3079 scope = kw['scope']
3080 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3081
3082 kw.update({ 'min_occurs' : 1
3083 , 'max_occurs' : 1
3084 , 'node' : node })
3085
3086 if not Particle.IsParticleNode(node):
3087 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3088 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3089 if attr_val is not None:
3090 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3091 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3092 if attr_val is not None:
3093 if 'unbounded' == attr_val:
3094 kw['max_occurs'] = None
3095 else:
3096 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3097
3098 rv = cls(None, **kw)
3099
3100 kw.pop('node', None)
3101 kw['owner'] = rv
3102
3103 rv.__refExpandedName = domutils.NodeAttributeQName(node, 'ref')
3104 rv.__pendingTerm = None
3105 rv.__resolvableType = None
3106 if xsd.nodeIsNamed(node, 'group'):
3107
3108
3109
3110 if rv.__refExpandedName is None:
3111 raise pyxb.SchemaValidationError('group particle without reference')
3112 rv.__resolvableType = ModelGroup
3113 elif xsd.nodeIsNamed(node, 'element'):
3114 if rv.__refExpandedName is None:
3115 schema = kw.get('schema')
3116 assert schema is not None
3117 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3118 incoming_tns = kw.get('target_namespace')
3119 if incoming_tns is not None:
3120 assert incoming_tns == target_namespace
3121 else:
3122 kw['target_namespace'] = target_namespace
3123 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3124 else:
3125
3126
3127
3128 for tag in ('nillable', 'default', 'fixed', 'form', 'block', 'type'):
3129 av = domutils.NodeAttribute(node, tag)
3130 if av is not None:
3131 raise pyxb.SchemaValidationError('element with "ref" cannot have "%s"' % (tag,))
3132 rv.__resolvableType = ElementDeclaration
3133 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3134 elif xsd.nodeIsNamed(node, 'any'):
3135
3136 rv.__term = Wildcard.CreateFromDOM(node=node)
3137 elif ModelGroup.IsGroupMemberNode(node):
3138
3139
3140
3141 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3142 else:
3143 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3144
3145 if not rv.isResolved():
3146 rv._queueForResolution('creation')
3147 return rv
3148
3149
3150 - def _bindingRequires_vx (self, include_lax):
3151 if not include_lax:
3152 return frozenset()
3153 return frozenset([ self.__term ])
3154
3155
3156 - def _adaptForScope (self, owner, ctd):
3157 rv = self
3158 assert isinstance(ctd, ComplexTypeDefinition)
3159 maybe_rv = self._clone(owner, ctd._objectOrigin())
3160 term = rv.__term._adaptForScope(maybe_rv, ctd)
3161 do_clone = (self._scope() != ctd) or (rv.__term != term)
3162 if do_clone:
3163 rv = maybe_rv
3164 rv.__term = term
3165 return rv
3166
3167 - def isAdaptable (self, ctd):
3168 """A particle has an unresolvable particle if it cannot be
3169 resolved, or if it has resolved to a term which is a model
3170 group that has an unresolvable particle.
3171 """
3172 if not self.isResolved():
3173 return False
3174 return self.term().isAdaptable(ctd)
3175
3176 - def walkParticleTree (self, visit, arg):
3177 """The entry-point to walk a particle tree defining a content model.
3178
3179 See L{_ParticleTree_mixin._walkParticleTree}."""
3180 self._walkParticleTree(visit, arg)
3181
3182 - def _walkParticleTree (self, visit, arg):
3183 visit(self, True, arg)
3184 self.__term._walkParticleTree(visit, arg)
3185 visit(self, False, arg)
3186
3187 @classmethod
3188 - def IsTypedefNode (cls, node):
3189 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3190
3191 @classmethod
3192 - def IsParticleNode (cls, node, *others):
3193 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3194
3195 - def __str__ (self):
3196
3197 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3198
3199
3200
3201 -class Wildcard (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
3202 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3203
3204 NC_any = '##any'
3205 NC_not = '##other'
3206 NC_targetNamespace = '##targetNamespace'
3207 NC_local = '##local'
3208
3209 __namespaceConstraint = None
3211 """A constraint on the namespace for the wildcard.
3212
3213 Valid values are:
3214 - L{Wildcard.NC_any}
3215 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3216 - set(of_namespaces)
3217
3218 Note that namespace are represented by
3219 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3220 actually define a namespace. Absence of a namespace is represented by
3221 C{None}, both in the "not" pair and in the set.
3222 """
3223 return self.__namespaceConstraint
3224
3225 @classmethod
3227 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3228 assert 0 < len(constraints)
3229 o1 = constraints.pop(0)
3230 while 0 < len(constraints):
3231 o2 = constraints.pop(0)
3232
3233 if (o1 == o2):
3234 continue
3235
3236 if (cls.NC_any == o1) or (cls.NC_any == o2):
3237 o1 = cls.NC_any
3238 continue
3239
3240 if isinstance(o1, set) and isinstance(o2, set):
3241 o1 = o1.union(o2)
3242 continue
3243
3244 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3245 o1 = ( cls.NC_not, None )
3246 continue
3247
3248
3249 c_tuple = None
3250 c_set = None
3251 if isinstance(o1, tuple):
3252 assert isinstance(o2, set)
3253 c_tuple = o1
3254 c_set = o2
3255 else:
3256 assert isinstance(o1, set)
3257 assert isinstance(o2, tuple)
3258 c_tuple = o2
3259 c_set = o1
3260 negated_ns = c_tuple[1]
3261 if negated_ns is not None:
3262
3263 if (negated_ns in c_set) and (None in c_set):
3264 o1 = cls.NC_any
3265 continue
3266
3267 if negated_ns in c_set:
3268 o1 = ( cls.NC_not, None )
3269 continue
3270
3271 if None in c_set:
3272 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3273 o1 = c_tuple
3274 continue
3275
3276 if None in c_set:
3277 o1 = cls.NC_any
3278 else:
3279 o1 = ( cls.NC_not, None )
3280 return o1
3281
3282 @classmethod
3284 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3285 assert 0 < len(constraints)
3286 o1 = constraints.pop(0)
3287 while 0 < len(constraints):
3288 o2 = constraints.pop(0)
3289
3290 if (o1 == o2):
3291 continue
3292
3293 if (cls.NC_any == o1) or (cls.NC_any == o2):
3294 if cls.NC_any == o1:
3295 o1 = o2
3296 continue
3297
3298 if isinstance(o1, set) and isinstance(o2, set):
3299 o1 = o1.intersection(o2)
3300 continue
3301 if isinstance(o1, tuple) and isinstance(o2, tuple):
3302 ns1 = o1[1]
3303 ns2 = o2[1]
3304
3305 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3306 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3307
3308 assert (ns1 is None) or (ns2 is None)
3309 if ns1 is None:
3310 assert ns2 is not None
3311 o1 = ( cls.NC_not, ns2 )
3312 else:
3313 assert ns1 is not None
3314 o1 = ( cls.NC_not, ns1 )
3315 continue
3316
3317
3318
3319 c_tuple = None
3320 c_set = None
3321 if isinstance(o1, tuple):
3322 assert isinstance(o2, set)
3323 c_tuple = o1
3324 c_set = o2
3325 else:
3326 assert isinstance(o1, set)
3327 assert isinstance(o2, tuple)
3328 c_tuple = o2
3329 c_set = o1
3330 negated_ns = c_tuple[1]
3331 if negated_ns in c_set:
3332 c_set.remove(negated_ns)
3333 if None in c_set:
3334 c_set.remove(None)
3335 o1 = c_set
3336 return o1
3337
3338 PC_skip = 'skip'
3339 PC_lax = 'lax'
3340 PC_strict = 'strict'
3341
3342
3343 __processContents = None
3344 - def processContents (self):
3345 return self.__processContents
3346
3348 """Return True, since Wildcard components are wildcards."""
3349 return True
3350
3356
3359
3360 - def _walkParticleTree (self, visit, arg):
3361 visit(self, None, arg)
3362
3363
3365 """Wildcards are scope-independent; return self"""
3366 return self
3367
3368
3369 @classmethod
3371 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3372 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3373 nc = domutils.NodeAttribute(node, 'namespace')
3374 if nc is None:
3375 namespace_constraint = cls.NC_any
3376 else:
3377 if cls.NC_any == nc:
3378 namespace_constraint = cls.NC_any
3379 elif cls.NC_not == nc:
3380 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3381 else:
3382 ncs = set()
3383 for ns_uri in nc.split():
3384 if cls.NC_local == ns_uri:
3385 ncs.add(None)
3386 elif cls.NC_targetNamespace == ns_uri:
3387 ncs.add(namespace_context.targetNamespace())
3388 else:
3389 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3390 namespace_constraint = frozenset(ncs)
3391
3392 pc = domutils.NodeAttribute(node, 'processContents')
3393 if pc is None:
3394 process_contents = cls.PC_strict
3395 else:
3396 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3397 process_contents = pc
3398 else:
3399 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3400
3401 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3402 rv._annotationFromDOM(node)
3403 return rv
3404
3405
3406 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3407 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3408
3409 ICC_KEY = 0x01
3410 ICC_KEYREF = 0x02
3411 ICC_UNIQUE = 0x04
3412
3413 __identityConstraintCategory = None
3416
3417 __selector = None
3420
3421 __fields = None
3424
3425 __referencedKey = None
3426 __referAttribute = None
3427 __icc = None
3428
3429 __annotations = None
3432
3433
3434 @classmethod
3436 name = domutils.NodeAttribute(node, 'name')
3437 scope = kw['scope']
3438 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3439 rv = cls(name=name, node=node, **kw)
3440
3441 kw.pop('node', None)
3442 kw['owner'] = rv
3443
3444
3445 rv.__isResolved = True
3446 icc = None
3447 if xsd.nodeIsNamed(node, 'key'):
3448 icc = rv.ICC_KEY
3449 elif xsd.nodeIsNamed(node, 'keyref'):
3450 icc = rv.ICC_KEYREF
3451 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3452 if rv.__referAttribute is None:
3453 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3454 rv.__isResolved = False
3455 elif xsd.nodeIsNamed(node, 'unique'):
3456 icc = rv.ICC_UNIQUE
3457 else:
3458 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3459 rv.__icc = icc
3460
3461 cn = domutils.LocateUniqueChild(node, 'selector')
3462 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3463 if rv.__selector is None:
3464 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3465
3466 rv.__fields = []
3467 for cn in domutils.LocateMatchingChildren(node, 'field'):
3468 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3469 if xp_attr is None:
3470 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3471 rv.__fields.append(xp_attr)
3472
3473 rv._annotationFromDOM(node)
3474 rv.__annotations = []
3475 if rv.annotation() is not None:
3476 rv.__annotations.append(rv)
3477
3478 for cn in node.childNodes:
3479 if (Node.ELEMENT_NODE != cn.nodeType):
3480 continue
3481 an = None
3482 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3483 an = domutils.LocateUniqueChild(cn, 'annotation')
3484 elif xsd.nodeIsNamed(cn, 'annotation'):
3485 an = cn
3486 if an is not None:
3487 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3488
3489 rv.__identityConstraintCategory = icc
3490 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3491 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3492
3493 if not rv.isResolved():
3494 rv._queueForResolution('creation')
3495 return rv
3496
3497 __isResolved = False
3500
3501
3516
3517
3519 """Constraint definitions that are by reference require the referenced constraint."""
3520 rv = set()
3521 if include_lax and (self.__referencedKey is not None):
3522 rv.add(self.__referencedKey)
3523 return frozenset(rv)
3524
3525
3526
3527
3528 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3529 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3530 __systemIdentifier = None
3533
3534 __publicIdentifier = None
3537
3538
3539 @classmethod
3549
3550
3553
3556 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3557
3558 __applicationInformation = None
3561
3562 __userInformation = None
3565
3566
3568 application_information = kw.pop('application_information', None)
3569 user_information = kw.pop('user_information', None)
3570 super(Annotation, self).__init__(**kw)
3571 if (user_information is not None) and (not isinstance(user_information, list)):
3572 user_information = [ unicode(user_information) ]
3573 if (application_information is not None) and (not isinstance(application_information, list)):
3574 application_information = [ unicode(application_information) ]
3575 self.__userInformation = user_information
3576 self.__applicationInformation = application_information
3577
3578
3579
3580
3581
3582
3583
3584
3585 __attributes = None
3586
3587
3588 @classmethod
3612
3613 __RemoveMultiQuote_re = re.compile('""+')
3615 """Return the text in a form suitable for embedding in a
3616 triple-double-quoted docstring.
3617
3618 Any sequence of two or more double quotes is replaced by a sequence of
3619 single quotes that is the same length. Following this, spaces are
3620 added at the start and the end as necessary to ensure a double quote
3621 does not appear in those positions."""
3622 rv = self.text()
3623 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3624 if rv.startswith('"'):
3625 rv = ' ' + rv
3626 if rv.endswith('"'):
3627 rv = rv + ' '
3628 return rv
3629
3631 if self.__userInformation is None:
3632 return ''
3633 text = []
3634
3635
3636 for dn in self.__userInformation:
3637 for cn in dn.childNodes:
3638 if Node.TEXT_NODE == cn.nodeType:
3639 text.append(cn.data)
3640 return ''.join(text)
3641
3643 """Return the catenation of all user information elements in the
3644 annotation as a single unicode string. Returns the empty string if
3645 there are no user information elements."""
3646 return self.text()
3647
3648
3649 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3650 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3651
3652
3653
3654
3655 __baseTypeDefinition = None
3658
3659 __memberTypes = None
3660 __itemTypeExpandedName = None
3661 __baseExpandedName = None
3662 __memberTypesExpandedNames = None
3663 __localFacets = None
3664
3665
3666
3667
3668
3669
3670 __facets = None
3674
3675
3676 __fundamentalFacets = None
3678 """A frozenset of instances of facets.FundamentallFacet."""
3679 return self.__fundamentalFacets
3680
3681 STD_empty = 0
3682 STD_extension = 0x01
3683 STD_list = 0x02
3684 STD_restriction = 0x04
3685 STD_union = 0x08
3686
3687 _STD_Map = { 'extension' : STD_extension
3688 , 'list' : STD_list
3689 , 'restriction' : STD_restriction
3690 , 'union' : STD_union }
3691
3692
3693 __final = STD_empty
3694 @classmethod
3696 """Convert a final value to a string."""
3697 tags = []
3698 if final_value & cls.STD_extension:
3699 tags.append('extension')
3700 if final_value & cls.STD_list:
3701 tags.append('list')
3702 if final_value & cls.STD_restriction:
3703 tags.append('restriction')
3704 if final_value & cls.STD_union:
3705 tags.append('union')
3706 return ' '.join(tags)
3707
3708 VARIETY_absent = 0x01
3709 VARIETY_atomic = 0x02
3710 VARIETY_list = 0x03
3711 VARIETY_union = 0x04
3712
3713
3714 _DA_empty = 'none specified'
3715 _DA_restriction = 'restriction'
3716 _DA_list = 'list'
3717 _DA_union = 'union'
3718
3721 __derivationAlternative = None
3722
3723
3724
3725 __variety = None
3728 @classmethod
3740
3741
3742 __primitiveTypeDefinition = None
3749
3750
3751 __itemTypeDefinition = None
3757
3758
3759 __memberTypeDefinitions = None
3765
3766
3795
3796
3797
3798
3799
3800 __domNode = None
3801
3802
3803
3804 __isBuiltin = False
3805
3806
3807
3808
3812
3814 """Extend base class unpickle support to retain link between
3815 this instance and the Python class that it describes.
3816
3817 This is because the pythonSupport value is a class reference,
3818 not an instance reference, so it wasn't deserialized, and its
3819 class member link was never set.
3820 """
3821 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3822 super_fn(state)
3823 if self.__pythonSupport is not None:
3824 self.__pythonSupport._SimpleTypeDefinition(self)
3825
3853
3855 """Override fields in this instance with those from the other.
3856
3857 This method is invoked only by Schema._addNamedComponent, and
3858 then only when a built-in type collides with a schema-defined
3859 type. Material like facets is not (currently) held in the
3860 built-in copy, so the DOM information is copied over to the
3861 built-in STD, which is subsequently re-resolved.
3862
3863 Returns self.
3864 """
3865 assert self != other
3866 assert self.isNameEquivalent(other)
3867 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3868
3869
3870 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3871 assert other.__domNode is not None
3872 self.__domNode = other.__domNode
3873
3874
3875 if other.__pythonSupport is not None:
3876
3877 self.__pythonSupport = other.__pythonSupport
3878
3879
3880 self.__variety = None
3881 return self
3882
3884 """Indicate whether this simple type is a built-in type."""
3885 return self.__isBuiltin
3886
3887 __SimpleUrTypeDefinition = None
3888 @classmethod
3925
3926 @classmethod
3961
3962 @classmethod
3994
3995 @classmethod
4027
4028 @classmethod
4055
4056 @classmethod
4058 """(Placeholder) Create a union simple type in the target namespace.
4059
4060 This function has not been implemented."""
4061 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4062
4064 simple_type_child = None
4065 for cn in body.childNodes:
4066 if (Node.ELEMENT_NODE == cn.nodeType):
4067 if not xsd.nodeIsNamed(cn, 'simpleType'):
4068 if other_elts_ok:
4069 continue
4070 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4071 assert not simple_type_child
4072 simple_type_child = cn
4073 if simple_type_child is None:
4074 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4075 return simple_type_child
4076
4077
4078
4079
4080
4081
4082
4083
4093
4100
4101 __localMemberTypes = None
4115
4126
4128 """Create facets for varieties that can take facets that are undeclared.
4129
4130 This means unions, which per section 4.1.2.3 of
4131 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4132 pattern restrictions."""
4133 if self.VARIETY_union != variety:
4134 return self
4135 self.__facets.setdefault(facets.CF_pattern)
4136 self.__facets.setdefault(facets.CF_enumeration)
4137 return self
4138
4140 """Identify the facets and properties for this stype.
4141
4142 This method simply identifies the facets that apply to this
4143 specific type, and records property values. Only
4144 explicitly-associated facets and properties are stored; others
4145 from base types will also affect this type. The information
4146 is taken from the applicationInformation children of the
4147 definition's annotation node, if any. If there is no support
4148 for the XMLSchema_hasFacetAndProperty namespace, this is a
4149 no-op.
4150
4151 Upon return, self.__facets is a map from the class for an
4152 associated fact to None, and self.__fundamentalFacets is a
4153 frozenset of instances of FundamentalFacet.
4154
4155 The return value is self.
4156 """
4157 self.__facets = { }
4158 self.__fundamentalFacets = frozenset()
4159 if self.annotation() is None:
4160 return self.__defineDefaultFacets(variety)
4161 app_info = self.annotation().applicationInformation()
4162 if app_info is None:
4163 return self.__defineDefaultFacets(variety)
4164 facet_map = { }
4165 fundamental_facets = set()
4166 seen_facets = set()
4167 for ai in app_info:
4168 for cn in ai.childNodes:
4169 if Node.ELEMENT_NODE != cn.nodeType:
4170 continue
4171 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4172 facet_name = domutils.NodeAttribute(cn, 'name')
4173 if facet_name is None:
4174 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4175 if facet_name in seen_facets:
4176 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4177 seen_facets.add(facet_name)
4178 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4179
4180 facet_map[facet_class] = None
4181 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4182 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4183 if 0 < len(facet_map):
4184 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4185 self.__facets = facet_map
4186 assert type(self.__facets) == types.DictType
4187 if 0 < len(fundamental_facets):
4188 self.__fundamentalFacets = frozenset(fundamental_facets)
4189 return self
4190
4191
4242
4257
4258
4259
4260
4262 assert self.__variety is None
4263 if self.__baseTypeDefinition is None:
4264 assert self.__baseExpandedName is not None
4265 base_type = self.__baseExpandedName.typeDefinition()
4266 if not isinstance(base_type, SimpleTypeDefinition):
4267 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (self.__baseExpandedName,))
4268 self.__baseTypeDefinition = base_type
4269
4270
4271
4272 assert self.__baseTypeDefinition != self
4273 if not self.__baseTypeDefinition.isResolved():
4274 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4275 return self
4276 if variety is None:
4277
4278
4279 variety = self.__baseTypeDefinition.__variety
4280 assert variety is not None
4281
4282 if self.VARIETY_absent == variety:
4283
4284
4285 pass
4286 elif self.VARIETY_atomic == variety:
4287
4288
4289
4290 ptd = self
4291 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4292 ptd = ptd.__baseTypeDefinition
4293
4294 self.__primitiveTypeDefinition = ptd
4295 elif self.VARIETY_list == variety:
4296 if self._DA_list == alternative:
4297 if self.__itemTypeExpandedName is not None:
4298 self.__itemTypeDefinition = self.__itemTypeExpandedName.typeDefinition()
4299 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4300 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (self.__itemTypeExpandedName,))
4301 elif self._DA_restriction == alternative:
4302 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4303 else:
4304 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4305 elif self.VARIETY_union == variety:
4306 if self._DA_union == alternative:
4307
4308
4309
4310
4311 if self.__memberTypeDefinitions is None:
4312 mtd = []
4313
4314
4315 if self.__memberTypesExpandedNames is not None:
4316 for mn_en in self.__memberTypesExpandedNames:
4317
4318 std = mn_en.typeDefinition()
4319 if std is None:
4320 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4321
4322 assert isinstance(std, SimpleTypeDefinition)
4323 mtd.append(std)
4324
4325 mtd.extend(self.__localMemberTypes)
4326 self.__memberTypeDefinitions = mtd
4327 assert None not in self.__memberTypeDefinitions
4328
4329
4330
4331
4332
4333
4334 mtd = []
4335 for mt in self.__memberTypeDefinitions:
4336 assert isinstance(mt, SimpleTypeDefinition)
4337 if not mt.isResolved():
4338 self._queueForResolution('member type not resolved', depends_on=mt)
4339 return self
4340 if self.VARIETY_union == mt.variety():
4341 mtd.extend(mt.memberTypeDefinitions())
4342 else:
4343 mtd.append(mt)
4344 elif self._DA_restriction == alternative:
4345 assert self.__baseTypeDefinition
4346
4347 assert self.__baseTypeDefinition.isResolved()
4348 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4349 assert mtd is not None
4350 else:
4351 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4352
4353 self.__memberTypeDefinitions = mtd[:]
4354 else:
4355 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4356
4357
4358
4359 self.__processHasFacetAndProperty(variety)
4360 self.__updateFacets(body)
4361
4362 self.__derivationAlternative = alternative
4363 self.__variety = variety
4364 self.__domNode = None
4365 return self
4366
4368 """Indicate whether this simple type is fully defined.
4369
4370 Type resolution for simple types means that the corresponding
4371 schema component fields have been set. Specifically, that
4372 means variety, baseTypeDefinition, and the appropriate
4373 additional fields depending on variety. See _resolve() for
4374 more information.
4375 """
4376
4377 return (self.__variety is not None)
4378
4379
4381 """Attempt to resolve the type.
4382
4383 Type resolution for simple types means that the corresponding
4384 schema component fields have been set. Specifically, that
4385 means variety, baseTypeDefinition, and the appropriate
4386 additional fields depending on variety.
4387
4388 All built-in STDs are resolved upon creation. Schema-defined
4389 STDs are held unresolved until the schema has been completely
4390 read, so that references to later schema-defined STDs can be
4391 resolved. Resolution is performed after the entire schema has
4392 been scanned and STD instances created for all
4393 topLevelSimpleTypes.
4394
4395 If a built-in STD is also defined in a schema (which it should
4396 be for XMLSchema), the built-in STD is kept, with the
4397 schema-related information copied over from the matching
4398 schema-defined STD. The former then replaces the latter in
4399 the list of STDs to be resolved.
4400
4401 Types defined by restriction have the same variety as the type
4402 they restrict. If a simple type restriction depends on an
4403 unresolved type, this method simply queues it for resolution
4404 in a later pass and returns.
4405 """
4406 if self.__variety is not None:
4407 return self
4408 assert self.__domNode
4409 node = self.__domNode
4410
4411 kw = { 'owner' : self
4412 , 'schema' : self._schema() }
4413
4414 bad_instance = False
4415
4416
4417 candidate = domutils.LocateUniqueChild(node, 'list')
4418 if candidate:
4419 self.__initializeFromList(candidate, **kw)
4420
4421 candidate = domutils.LocateUniqueChild(node, 'restriction')
4422 if candidate:
4423 if self.__variety is None:
4424 self.__initializeFromRestriction(candidate, **kw)
4425 else:
4426 bad_instance = True
4427
4428 candidate = domutils.LocateUniqueChild(node, 'union')
4429 if candidate:
4430 if self.__variety is None:
4431 self.__initializeFromUnion(candidate, **kw)
4432 else:
4433 bad_instance = True
4434
4435 if self.__baseTypeDefinition is None:
4436 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4437
4438 if self._schema() is not None:
4439 self.__final = self._schema().finalForNode(node, self._STD_Map)
4440
4441
4442 if bad_instance:
4443 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4444
4445 return self
4446
4447
4448 @classmethod
4464
4465
4466
4467
4468 __pythonSupport = None
4469
4479
4482
4487
4490
4493
4495 """Subclass ensures there is only one simple ur-type."""
4496 pass
4497
4603
4604 -class Schema (_SchemaComponent_mixin):
4605 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4606
4609
4610
4611 __annotations = None
4612
4613
4614
4615 __pastProlog = False
4616
4618 """URI or path to where the schema can be found.
4619
4620 For schema created by a user, the location should be provided to the
4621 constructor using the C{schema_location} keyword. In the case of
4622 imported or included schema, the including schema's location is used
4623 as the base URI for determining the absolute URI of the included
4624 schema from its (possibly relative) location value. For files,
4625 the scheme and authority portions are generally absent, as is often
4626 the abs_path part."""
4627 return self.__location
4628 __location = None
4629
4632 __locationTag = None
4633
4636 __signature = None
4637
4640 __generationUID = None
4641
4644 __originRecord = None
4645
4647 """The targetNamespace of a componen.
4648
4649 This is None, or a reference to a Namespace in which the
4650 component is declared (either as a global or local to one of
4651 the namespace's complex type definitions). This is immutable
4652 after creation.
4653 """
4654 return self.__targetNamespace
4655 __targetNamespace = None
4656
4658 """Default namespace of the schema.
4659
4660 Will be None unless the schema has an 'xmlns' attribute. The
4661 value must currently be provided as a keyword parameter to the
4662 constructor. """
4663 return self.__defaultNamespace
4664 __defaultNamespace = None
4665
4668 __referencedNamespaces = None
4669
4670 __namespaceData = None
4671
4674 __importEIIs = None
4675
4678 __importedSchema = None
4681 __includedSchema = None
4682
4683 _QUALIFIED = "qualified"
4684 _UNQUALIFIED = "unqualified"
4685
4686
4687 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4688 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4689 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4690 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4691 , pyxb.namespace.ExpandedName(None, 'id') : None
4692 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4693 , pyxb.namespace.ExpandedName(None, 'version') : None
4694 , pyxb.namespace.XML.createExpandedName('lang') : None
4695 }
4696
4701
4703 """Override the schema attributes with values from the given map."""
4704 self.__attributeMap.update(attr_map)
4705 return self
4706
4708 """Return True iff the schema has an attribute with the given (nc)name."""
4709 if isinstance(attr_name, basestring):
4710 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4711 return attr_name in self.__attributeMap
4712
4714 """Return the schema attribute value associated with the given (nc)name.
4715
4716 @param attr_name: local name for the attribute in the schema element.
4717 @return: the value of the corresponding attribute, or C{None} if it
4718 has not been defined and has no default.
4719 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4720 """
4721 if isinstance(attr_name, basestring):
4722 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4723 return self.__attributeMap[attr_name]
4724
4725 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4726 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4727 'identityConstraintDefinition' )
4728
4731 __uriContentArchiveDirectory = None
4732
4774
4775 __TopLevelComponentMap = {
4776 'element' : ElementDeclaration,
4777 'attribute' : AttributeDeclaration,
4778 'notation' : NotationDeclaration,
4779 'simpleType' : SimpleTypeDefinition,
4780 'complexType' : ComplexTypeDefinition,
4781 'group' : ModelGroupDefinition,
4782 'attributeGroup' : AttributeGroupDefinition
4783 }
4784
4785 @classmethod
4790
4791 @classmethod
4793 """Create a schema from a schema location.
4794
4795 Reads an XML document from the schema location and creates a schema
4796 using it. All keyword parameters are passed to L{CreateFromDOM}.
4797
4798 @keyword schema_location: A file path or a URI. If this is a relative
4799 URI and C{parent_uri} is present, the actual location will be
4800 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4801 @keyword parent_uri: The context within which schema_location will be
4802 normalized, if necessary.
4803 @keyword absolute_schema_location: A file path or URI. This value is
4804 not normalized, and supersedes C{schema_location}.
4805 """
4806 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4807 kw['location_base'] = kw['schema_location'] = schema_location
4808 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4809 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4810 return cls.CreateFromDocument(pyxb.utils.utility.DataFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4811
4812 @classmethod
4815
4816 @classmethod
4817 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4818 """Take the root element of the document, and scan its attributes under
4819 the assumption it is an XMLSchema schema element. That means
4820 recognize namespace declarations and process them. Also look for
4821 and set the default namespace. All other attributes are passed up
4822 to the parent class for storage."""
4823
4824
4825
4826 including_context = kw.get('including_context')
4827
4828 root_node = node
4829 if Node.DOCUMENT_NODE == node.nodeType:
4830 root_node = root_node.documentElement
4831 if Node.ELEMENT_NODE != root_node.nodeType:
4832 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4833
4834 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4835 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4836 parent_context=namespace_context,
4837 including_context=including_context)
4838
4839 tns = ns_ctx.targetNamespace()
4840 if tns is None:
4841 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4842 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4843 schema.__namespaceData = ns_ctx
4844
4845 if schema.targetNamespace() != ns_ctx.targetNamespace():
4846 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4847
4848
4849 for ai in range(root_node.attributes.length):
4850 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4851
4852
4853 if not xsd.nodeIsNamed(root_node, 'schema'):
4854 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4855
4856 for cn in root_node.childNodes:
4857 if Node.ELEMENT_NODE == cn.nodeType:
4858 rv = schema.__processTopLevelNode(cn)
4859 if rv is None:
4860 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4861 elif Node.TEXT_NODE == cn.nodeType:
4862
4863
4864 text = cn.data.strip()
4865 if text:
4866 _log.info('Ignored text: %s', text)
4867 elif Node.COMMENT_NODE == cn.nodeType:
4868 pass
4869 else:
4870
4871
4872
4873
4874
4875
4876
4877 _log.info('Ignoring non-element: %s', cn)
4878
4879
4880
4881
4882 return schema
4883
4884 _SA_All = '#all'
4885
4887 ebv = domutils.NodeAttribute(dom_node, attr)
4888 if ebv is None:
4889 ebv = self.schemaAttribute('%sDefault' % (attr,))
4890 rv = 0
4891 if ebv == self._SA_All:
4892 for v in candidate_map.itervalues():
4893 rv += v
4894 else:
4895 for candidate in ebv.split():
4896 rv += candidate_map.get(candidate, 0)
4897 return rv
4898
4900 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4901
4902 A value of '#all' means enable every options; otherwise, the attribute
4903 value should be a list of tokens, for which the corresponding value
4904 will be added to the return value.
4905
4906 @param dom_node: the node from which the "block" attribute will be retrieved
4907 @type dom_node: C{xml.dom.Node}
4908 @param candidate_map: map from strings to bitmask values
4909 """
4910 return self.__ebvForNode('block', dom_node, candidate_map)
4911
4913 """Return a bit mask indicating a set of options read from the node's
4914 "final" attribute or the schema's "finalDefault" attribute.
4915
4916 A value of '#all' means enable every options; otherwise, the attribute
4917 value should be a list of tokens, for which the corresponding value
4918 will be added to the return value.
4919
4920 @param dom_node: the node from which the "final" attribute will be retrieved
4921 @type dom_node: C{xml.dom.Node}
4922 @param candidate_map: map from strings to bitmask values
4923 """
4924 return self.__ebvForNode('final', dom_node, candidate_map)
4925
4927 """Determine the target namespace for a local attribute or element declaration.
4928
4929 Look at the node's C{form} attribute, or if none the schema's
4930 C{attributeFormDefault} or C{elementFormDefault} value. If the
4931 resulting value is C{"qualified"} and the parent schema has a
4932 non-absent target namespace, return it to use as the declaration
4933 target namespace. Otherwise, return None to indicate that the
4934 declaration has no namespace.
4935
4936 @param dom_node: The node defining an element or attribute declaration
4937 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4938 @return: L{pyxb.namespace.Namespace} or None
4939 """
4940
4941 form_type = domutils.NodeAttribute(dom_node, 'form')
4942 if form_type is None:
4943 if declaration_type == ElementDeclaration:
4944 form_type = self.schemaAttribute('elementFormDefault')
4945 elif declaration_type == AttributeDeclaration:
4946 form_type = self.schemaAttribute('attributeFormDefault')
4947 else:
4948 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4949 tns = None
4950 if (self._QUALIFIED == form_type):
4951 tns = self.targetNamespace()
4952 if tns.isAbsentNamespace():
4953 tns = None
4954 else:
4955 if (self._UNQUALIFIED != form_type):
4956 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4957 return tns
4958
4960 """Throw a SchemaValidationException referencing the given
4961 node if we have passed the sequence point representing the end
4962 of prolog elements."""
4963
4964 if self.__pastProlog:
4965 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4966
4968 self.__requireInProlog(node.nodeName)
4969
4970 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
4971 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
4972 if not has_schema:
4973 kw = { 'absolute_schema_location': abs_uri,
4974 'including_context': self.__namespaceData,
4975 'generation_uid': self.generationUID(),
4976 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
4977 }
4978 try:
4979 schema_instance = self.CreateFromLocation(**kw)
4980 except pyxb.SchemaUniquenessError as e:
4981 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
4982 except Exception as e:
4983 _log.exception('INCLUDE %s caught', abs_uri)
4984 raise
4985 if schema_instance:
4986 if self.targetNamespace() != schema_instance.targetNamespace():
4987 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
4988 self.__includedSchema.add(schema_instance)
4989 return node
4990
5008
5012
5016
5040
5044
5046 tns = self.targetNamespace()
5047 assert tns is not None
5048 if not isinstance(nc, _NamedComponent_mixin):
5049 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
5050 if nc.isAnonymous():
5051 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
5052 if isinstance(nc, _ScopedDeclaration_mixin):
5053 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
5054 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5055 return self.__addTypeDefinition(nc)
5056 if isinstance(nc, AttributeDeclaration):
5057 return self.__addAttributeDeclaration(nc)
5058 if isinstance(nc, AttributeGroupDefinition):
5059 return self.__addAttributeGroupDefinition(nc)
5060 if isinstance(nc, ModelGroupDefinition):
5061 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5062 if isinstance(nc, ElementDeclaration):
5063 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5064 if isinstance(nc, NotationDeclaration):
5065 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5066 if isinstance(nc, IdentityConstraintDefinition):
5067 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5068 assert False, 'No support to record named component of type %s' % (nc.__class__,)
5069
5089
5106
5123
5125 return 'SCH[%s]' % (self.location(),)
5126
5129 """Add to the schema the definitions of the built-in types of XMLSchema.
5130 This should only be invoked by L{pyxb.namespace} when the built-in
5131 namespaces are initialized. """
5132
5133
5134 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5135 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5136 assert td.isResolved()
5137
5138 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5139 assert td.isResolved()
5140
5141 pts_std_map = {}
5142 for dtc in datatypes._PrimitiveDatatypes:
5143 name = dtc.__name__.rstrip('_')
5144 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5145 assert td.isResolved()
5146 assert dtc.SimpleTypeDefinition() == td
5147 pts_std_map.setdefault(dtc, td)
5148 for dtc in datatypes._DerivedDatatypes:
5149 name = dtc.__name__.rstrip('_')
5150 parent_std = pts_std_map[dtc.XsdSuperType()]
5151 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5152 assert td.isResolved()
5153 assert dtc.SimpleTypeDefinition() == td
5154 pts_std_map.setdefault(dtc, td)
5155 for dtc in datatypes._ListDatatypes:
5156 list_name = dtc.__name__.rstrip('_')
5157 element_name = dtc._ItemType.__name__.rstrip('_')
5158 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5159 assert element_std is not None
5160 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5161 assert td.isResolved()
5162 global _PastAddBuiltInTypes
5163 _PastAddBuiltInTypes = True
5164
5165 return schema
5166
5167 import sys
5168 import pyxb.namespace.builtin
5169 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5170
5171
5172
5173
5174