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