| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2 # Copyright 2009-2012, Peter A. Bigot
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain a
6 # copy of the License at:
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
14 # under the License.
15
16 """Classes corresponding to W3C XML Schema components.
17
18 Class names and behavior should conform to the schema components described in
19 U{XML Schema Part 1: Structures<http://www.w3.org/TR/xmlschema-1/>}.
20 References to sections in the documentation of this module generally refers to
21 that document.
22
23 Each class has a C{CreateFromDOM} class method that creates an instance and
24 initializes it from a DOM node. Only the L{Wildcard}, L{Particle}, and
25 L{ModelGroup} components are created from non-DOM sources. However, the
26 requirements on DOM interface are restricted to attributes, child nodes, and
27 basic fields, though all these must support namespaces.
28
29 @group Mixins: *_mixin
30 @group Ur Type Specializations: *UrType*
31 @group Utilities: _PluralityData, _ImportElementInformationItem
32
33 """
34
35 import pyxb
36 import pyxb.xmlschema
37 from xml.dom import Node
38 import types
39 import re
40 import logging
41
42 import pyxb.namespace.archive
43 import pyxb.namespace.resolution
44
45 from pyxb.binding import basis
46 from pyxb.binding import datatypes
47 from pyxb.binding import facets
48 from pyxb.utils import domutils
49 import pyxb.utils.utility
50 import copy
51 import urlparse
52 import os.path
53
54 _log = logging.getLogger(__name__)
55
56 # Flag indicating that the built in types have been registered
57 _PastAddBuiltInTypes = False
58
59 # Make it easier to check node names in the XMLSchema namespace
60 from pyxb.namespace import XMLSchema as xsd
61
62 -class _SchemaComponent_mixin (pyxb.namespace._ComponentDependency_mixin,
63 pyxb.namespace.archive._ArchivableObject_mixin,
64 pyxb.utils.utility.PrivateTransient_mixin,
65 pyxb.utils.utility.Locatable_mixin):
66 """A mix-in that marks the class as representing a schema component.
67
68 This exists so that we can determine the owning schema for any
69 component we encounter. This is normally done at construction
70 time by passing a C{schema=val} parameter to the constructor.
71 """
72
73 # This class suppports transient instance variables. These variables are
74 # added to the set of transients at the point of declaration in the class.
75 __PrivateTransient = set()
76
78 """The namespace context for this schema.
79
80 This defines where it looks things up, where it puts things it
81 createas, the in-scope namespace declarations, etc. Must be defined
82 for anything that does any sort of QName interpretation. The value is
83 generally a reference to a namespace context associated with the DOM
84 element node corresponding to this component."""
85 if self.__namespaceContext is None:
86 raise pyxb.LogicError('Attempt to access missing namespace context for %s' % (self,))
87 return self.__namespaceContext
91 __namespaceContext = None
92 __PrivateTransient.add('namespaceContext')
93
94 # The name by which this component is known within the binding module.
95 # This is in component rather than _NamedComponent_mixin because some
96 # unnamed components (like ModelGroup and Wildcard) have Python objects to
97 # represent them, so need a binding-level name.
98 __nameInBinding = None
99
100 # The schema component that owns this. If C{None}, the component is owned
101 # directly by the schema.
102 __owner = None
103 __PrivateTransient.add('owner')
104
105 # The schema components owned by this component.
106 __ownedComponents = None
107 __PrivateTransient.add('ownedComponent')
108
110 """The context into which declarations in or subordinate to this nodeare placed."""
111 return self.__scope
112 __scope = None
113
115 """Return True iff nobody has defined a scope for this node."""
116 return _ScopedDeclaration_mixin.ScopeIsIndeterminate(self._scope())
117
119 """Return True iff this component has global scope."""
120 return _ScopedDeclaration_mixin.ScopeIsGlobal(self._scope())
121
123 """Set the scope of this instance after construction.
124
125 This should only be invoked on cloned declarations being incorporated
126 into a complex type definition. Note that the source of the clone may
127 be any scope: indeterminate if from a model (attribute) group
128 definition; global if a reference to a global component; or ctd if
129 inherited from a complex base type."""
130 assert self.__cloneSource is not None
131 assert isinstance(self, _ScopedDeclaration_mixin)
132 assert isinstance(ctd, ComplexTypeDefinition)
133 self.__scope = ctd
134 return self
135
137 """Initialize portions of a component.
138
139 @keyword scope: The scope in which the component is defined
140
141 @keyword namespace_context: The NamespaceContext to use within this component
142
143 @keyword node: If no C{namespace_context} is provided, a DOM node must
144 be provided from which a namespace context can be identified.
145
146 @keyword owner: Reference to the component that owns this one (the
147 immediately enclosing component). Is C{None} in the case of top-level
148 components.
149
150 @keyword schema: Reference to the L{Schema} component to which the
151 component belongs. Required for every component except L{Schema},
152 L{Annotation}, and L{Wildcard}.
153 """
154
155 self.__ownedComponents = set()
156 self.__scope = kw.get('scope')
157 self.__namespaceContext = kw.get('namespace_context')
158 node = kw.get('node')
159 if self.__namespaceContext is None:
160 if node is None:
161 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node')
162 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
163 if self.__namespaceContext is None:
164 raise pyxb.LogicError('No namespace_context for schema component')
165
166 super(_SchemaComponent_mixin, self).__init__(*args, **kw)
167
168 if isinstance(node, pyxb.utils.utility.Locatable_mixin):
169 self._setLocation(node._location())
170
171 self._namespaceContext().targetNamespace()._associateComponent(self)
172
173 self._setOwner(kw.get('owner'))
174
175 schema = kw.get('schema')
176 if schema is not None:
177 self._setObjectOrigin(schema.originRecord())
178 else:
179 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),)
180
181 if isinstance(self, ComplexTypeDefinition):
182 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
183
184
186 """Dissociate this component from its owning namespace.
187
188 This should only be done whwen there are no other references to the
189 component, and you want to ensure it does not appear in the model."""
190 self._namespaceContext().targetNamespace()._replaceComponent(self, None)
191 return self
192
194 """Set the owner of this component.
195
196 If C{owner} is C{None}, this has no effect. Otherwise, the
197 component's current owner must be either C{None} or the same as the
198 input C{owner}."""
199
200 if owner is not None:
201 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner)
202 self.__owner = owner
203 owner.__ownedComponents.add(self)
204 return self
205
207 return self.__owner
208
209 # A reference to the instance from which this instance was cloned.
210 __cloneSource = None
211 __PrivateTransient.add('cloneSource')
212
214 """The source component from which this is a clone.
215
216 Returns C{None} if this is not a clone."""
217 return self.__cloneSource
218
219 # A set of references to all instances that are clones of this one.
220 __clones = None
221 __PrivateTransient.add('clones')
222
224 """The set of instances cloned from this component.
225
226 Returns None if no instances have been cloned from this."""
227 return self.__clones
228
230 """Virtual method to clear whatever attributes should be reset in a
231 cloned component.
232
233 This instance should be an instance created by copy.copy().
234
235 The implementation in this class clears the owner and dependency
236 relations.
237
238 Returns C{self}.
239 """
240 assert self.__cloneSource is not None
241 owner = kw['owner']
242 self.__nameInBinding = None
243 self.__owner = owner
244 assert not (isinstance(self, ComplexTypeDefinition) and isinstance(owner, Schema))
245 self.__ownedComponents = set()
246 self.__clones = None
247 owner._namespaceContext().targetNamespace()._associateComponent(self)
248 if self.__namespaceContext is None:
249 # When cloning imported components, loan them the owner's
250 # namespace context, only so that their cloned children can be
251 # associated with the same namespace.
252 self.__namespaceContext = owner._namespaceContext()
253 self_fn = lambda *_args, **_kw: self
254 return getattr(super(_SchemaComponent_mixin, self), '_resetClone_csc', self_fn)(**kw)
255
257 """Create a copy of this instance suitable for adoption by some other
258 component.
259
260 This is used for creating a locally-scoped declaration from a
261 declaration in a named model or attribute group."""
262
263 # We only care about cloning declarations, and they should
264 # have an unassigned scope. However, we do clone
265 # non-declarations that contain cloned declarations.
266 #assert (not isinstance(self, _ScopedDeclaration_mixin)) or self._scopeIsIndeterminate()
267 if isinstance(self, pyxb.namespace.resolution._Resolvable_mixin):
268 assert self.isResolved()
269
270 assert owner is not None
271 that = copy.copy(self)
272 that.__cloneSource = self
273 if self.__clones is None:
274 self.__clones = set()
275 self.__clones.add(that)
276 that._resetClone_csc(owner=owner, origin=origin)
277 if isinstance(that, pyxb.namespace.resolution._Resolvable_mixin):
278 assert that.isResolved()
279 return that
280
282 """Return True iff this component is a simple or complex type
283 definition."""
284 return isinstance(self, (SimpleTypeDefinition, ComplexTypeDefinition))
285
287 """Return True iff this component is a simple or complex type
288 definition."""
289 return isinstance(self, (_SimpleUrTypeDefinition, _UrTypeDefinition))
290
292 """Return the name of this component, as best it can be determined.
293
294 For example, ModelGroup instances will be named by their
295 ModelGroupDefinition, if available. Returns None if no name can be
296 inferred."""
297 if isinstance(self, _NamedComponent_mixin):
298 return self.name()
299 if isinstance(self, ModelGroup):
300 agd = self.modelGroupDefinition()
301 if agd is not None:
302 return agd.name()
303 return None
304
306 """Return the name by which this component is known in the generated
307 binding.
308
309 @note: To support builtin datatypes, type definitions with an
310 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class
311 initialize their binding name from the class name when the support
312 association is created. As long as no built-in datatype conflicts
313 with a language keyword, this should be fine."""
314 return self.__nameInBinding
315
317 """Return C{True} iff this is a component which has a user-visible
318 Python construct which serves as its binding.
319
320 Type definitions have classes as their bindings. Global element
321 declarations have instances of L{pyxb.binding.basis.element} as their
322 bindings."""
323 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
324
326 """Set the name by which this component shall be known in the XSD binding."""
327 self.__nameInBinding = name_in_binding
328 return self
329
331 """Override fields in this instance with those from the other.
332
333 Post-extended; description in leaf implementation in
334 ComplexTypeDefinition and SimpleTypeDefinition."""
335 assert self != other
336 self_fn = lambda *_args, **_kw: self
337 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', self_fn)(other)
338 # The only thing we update is the binding name, and that only if it's new.
339 if self.__nameInBinding is None:
340 self.__nameInBinding = other.__nameInBinding
341 return self
342
344 """This class is a mix-in which guarantees that only one instance
345 of the class will be created. It is used to ensure that the
346 ur-type instances are pointer-equivalent even when unpickling.
347 See ComplexTypeDefinition.UrTypeDefinition()."""
349 singleton_property = '_%s__singleton' % (cls.__name__,)
350 if not (singleton_property in cls.__dict__):
351 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw))
352 return cls.__dict__[singleton_property]
353
355 """Mix-in that supports an optional single annotation that describes the component.
356
357 Most schema components have annotations. The ones that don't are
358 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition}
359 and L{Schema} support multiple annotations, so do not mix-in this
360 class."""
361
362 # Optional Annotation instance
363 __annotation = None
364
366 super(_Annotated_mixin, self).__init__(*args, **kw)
367 self.__annotation = kw.get('annotation')
368
370 cn = domutils.LocateUniqueChild(node, 'annotation')
371 if cn is not None:
372 kw = { }
373 if isinstance(self, _SchemaComponent_mixin):
374 kw['owner'] = self
375 self.__annotation = Annotation.CreateFromDOM(cn, **kw)
376
378 """Override fields in this instance with those from the other.
379
380 Post-extended; description in leaf implementation in
381 ComplexTypeDefinition and SimpleTypeDefinition."""
382 assert self != other
383 self_fn = lambda *_args, **_kw: self
384 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', self_fn)(other)
385 # @todo: make this a copy?
386 self.__annotation = other.__annotation
387 return self
388
390 return self.__annotation
391
393 """A helper that encapsulates a reference to an anonymous type in a different namespace.
394
395 Normally references to components in other namespaces can be made using
396 the component's name. This is not the case when a namespace derives from
397 a base type in another namespace and needs to reference the attribute or
398 element declarations held in that type. If these declarations are local
399 to the base complex type, they cannot be identified by name. This class
400 provides a pickleable representation for them that behaves rather like an
401 L{pyxb.namespace.ExpandedName} instance in that it can be used to
402 dereference various component types."""
403
404 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
405
406 __namespace = None
407 __anonymousName = None
409 """Create a new anonymous reference.
410
411 @param namespace: The namespace in which the component is declared.
412 @type namespace: L{pyxb.namespace.Namespace}
413 @param anonymous_name: A generated name guaranteed to be unique within
414 the namespace. See L{_NamedComponent_mixin._anonymousName}.
415 @type anonymous_name: C{basestring}.
416 """
417 self.__namespace = namespace
418 self.__anonymousName = anonymous_name
419 assert self.__anonymousName is not None
420
421 @classmethod
423 """Return the component referred to by the provided reference,
424 regardless of whether it is a normal or anonymous reference."""
425 if not isinstance(object_reference, _PickledAnonymousReference):
426 assert isinstance(object_reference, tuple)
427 object_reference = pyxb.namespace.ExpandedName(object_reference)
428 return object_reference
429
431 return self.__namespace
432
434 return self.__anonymousName
435
439
442
443 typeDefinition = __lookupObject
444 attributeGroupDefinition = __lookupObject
445 modelGroupDefinition = __lookupObject
446 attributeDeclaration = __lookupObject
447 elementDeclaration = __lookupObject
448 identityConstraintDefinition = __lookupObject
449 notationDeclaration = __lookupObject
450
452 """Represent the anonymous reference in a form recognizable by a developer."""
453 return 'ANONYMOUS:%s' % (pyxb.namespace.ExpandedName(self.__namespace, self.__anonymousName),)
454
456 """Mix-in to hold the name and targetNamespace of a component.
457
458 The name may be None, indicating an anonymous component. The
459 targetNamespace is never None, though it could be an empty namespace. The
460 name and targetNamespace values are immutable after creation.
461
462 This class overrides the pickling behavior: when pickling a Namespace,
463 objects that do not belong to that namespace are pickled as references,
464 not as values. This ensures the uniqueness of objects when multiple
465 namespace definitions are pre-loaded.
466
467 This class must follow L{_SchemaComponent_mixin} in the MRO.
468 """
469
470 __PrivateTransient = set()
471
473 """Name of the component within its scope or namespace.
474
475 This is an NCName. The value isNone if the component is
476 anonymous. The attribute is immutable after the component is
477 created creation."""
478 return self.__name
479 __name = None
480
482 """Return true iff this instance is locally scoped (has no name)."""
483 return self.__name is None
484
486 # If this already has a name, keep using it.
487 if self.__anonymousName is not None:
488 return
489 assert self.__needAnonymousSupport()
490 assert namespace is not None
491 if self.bindingNamespace() is not None:
492 assert self.bindingNamespace() == namespace
493 if self.targetNamespace() is not None:
494 assert self.targetNamespace() == namespace
495 if anon_name is None:
496 anon_name = self.nameInBinding()
497 if anon_name is None:
498 anon_name = self.name()
499 if anon_name is None:
500 anon_name = 'ANON_IN_GROUP'
501 if unique_id is not None:
502 anon_name = '%s_%s' % (anon_name, unique_id)
503 anon_name = pyxb.utils.utility.MakeUnique(anon_name, set(namespace.categoryMap(self.__AnonymousCategory).keys()))
504 self.__anonymousName = anon_name
505 namespace.addCategoryObject(self.__AnonymousCategory, anon_name, self)
507 assert self.__anonymousName is not None, '%x %s %s in %s missing anonymous name' % (id(self), type(self), self.name(), self.targetNamespace())
508 return self.__anonymousName
509 __anonymousName = None
510
512 """The targetNamespace of a component.
513
514 This is None, or a reference to a Namespace in which the
515 component is declared (either as a global or local to one of
516 the namespace's complex type definitions). This is immutable
517 after creation.
518 """
519 return self.__targetNamespace
520 __targetNamespace = None
521
523 """The namespace in which this component's binding is placed."""
524 return self.__bindingNamespace
527 __bindingNamespace = None
528
530 """A map from template keys to component-specific values.
531
532 This is used in code generation to maintain unique names for accessor
533 methods, identifiers, keys, and other characteristics associated with
534 the code generated in support of the binding for this component."""
535 return self.__templateMap
536 __templateMap = None
537
538 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory()
539
541 # If this component doesn't have a name, or if it's in some scope in
542 # which it cannot be located in a category map, we'll need a unique
543 # name for it.
544 return self.isAnonymous() or (self._scopeIsIndeterminate() and not isinstance(self, (AttributeGroupDefinition, ModelGroupDefinition)))
545
547 """Return the schema component from which this component was defined.
548
549 Needed so we can distinguish components that came from different
550 locations, since that imposes an external order dependency on them and
551 on cross-namespace inclusions.
552
553 @note: This characteristic is removed when the component is stored in
554 a namespace archive."""
555 return self.__schema
556 __schema = None
557 __PrivateTransient.add('schema')
558
560 if self.__needAnonymousSupport():
561 self._setAnonymousName(module_record.namespace(), unique_id=module_record.generationUID())
562 self_fn = lambda *_args, **_kw: self
563 return getattr(super(_NamedComponent_mixin, self), '_prepareForArchive_csc', self_fn)(module_record)
564
566 """Return C{True} if this component should be pickled by value in the
567 given namespace.
568
569 When pickling, a declaration component is considered to belong to the
570 namespace if it has a local scope which belongs to the namespace. In
571 that case, the declaration is a clone of something that does not
572 belong to the namespace; but the clone does.
573
574 @see: L{_bindsInNamespace}
575
576 @return: C{False} if the component should be pickled by reference.
577 """
578 if isinstance(self._scope(), ComplexTypeDefinition):
579 return self._scope()._picklesInArchive(archive)
580 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace())
581 assert not (self._objectOrigin() is None)
582 new_flag = (self._objectOrigin().generationUID() == archive.generationUID())
583 return new_flag
584
586 """Return C{True} if the binding for this component should be
587 generated in the given namespace.
588
589 This is the case when the component is in the given namespace. It's
590 also the case when the component has no associated namespace (but not
591 an absent namespace). Be aware that cross-namespace inheritance means
592 you will get references to elements in another namespace when
593 generating code for a subclass; that's fine, and those references
594 should not be generated locally.
595 """
596 return self.targetNamespace() in (ns, None)
597
599 """Return the L{pyxb.namespace.ExpandedName} of this object."""
600 if self.name() is None:
601 return None
602 return pyxb.namespace.ExpandedName(self.targetNamespace(), self.name())
603
605 """Pickling support.
606
607 Normally, we just create a new instance of this class.
608 However, if we're unpickling a reference in a loadable schema,
609 we need to return the existing component instance by looking
610 up the name in the component map of the desired namespace. We
611 can tell the difference because no normal constructors that
612 inherit from this have positional arguments; only invocations
613 by unpickling with a value returned in __getnewargs__ do.
614
615 This does require that the dependent namespace already have
616 been validated (or that it be validated here). That shouldn't
617 be a problem, except for the dependency loop resulting from
618 use of xml:lang in the XMLSchema namespace. For that issue,
619 see pyxb.namespace._XMLSchema.
620 """
621
622 if 0 == len(args):
623 rv = super(_NamedComponent_mixin, cls).__new__(cls)
624 return rv
625 ( object_reference, scope, icls ) = args
626
627 object_reference = _PickledAnonymousReference.FromPickled(object_reference)
628
629 # Explicitly validate here: the lookup operations won't do so,
630 # but will abort if the namespace hasn't been validated yet.
631 object_reference.validateComponentModel()
632 if isinstance(scope, (tuple, _PickledAnonymousReference)):
633 # Scope is the expanded name of the complex type in which the
634 # named value can be located.
635 scope_ref = _PickledAnonymousReference.FromPickled(scope)
636 if object_reference.namespace() != scope_ref.namespace():
637 scope_ref.validateComponentModel()
638 assert 'typeDefinition' in scope_ref.namespace().categories()
639 scope_ctd = scope_ref.typeDefinition()
640 if scope_ctd is None:
641 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,))
642 if issubclass(icls, AttributeDeclaration):
643 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference)
644 elif issubclass(icls, ElementDeclaration):
645 rv = scope_ctd.lookupScopedElementDeclaration(object_reference)
646 else:
647 raise pyxb.IncompleteImplementationError('Scope %s reference lookup of %s not implemented for type %s' % (scope_ref, object_reference, icls))
648 if rv is None:
649 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref))
650 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope):
651 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)):
652 rv = object_reference.typeDefinition()
653 elif issubclass(icls, AttributeGroupDefinition):
654 rv = object_reference.attributeGroupDefinition()
655 elif issubclass(icls, ModelGroupDefinition):
656 rv = object_reference.modelGroupDefinition()
657 elif issubclass(icls, AttributeDeclaration):
658 rv = object_reference.attributeDeclaration()
659 elif issubclass(icls, ElementDeclaration):
660 rv = object_reference.elementDeclaration()
661 elif issubclass(icls, IdentityConstraintDefinition):
662 rv = object_reference.identityConstraintDefinition()
663 else:
664 raise pyxb.IncompleteImplementationError('Reference lookup of %s not implemented for type %s' % (object_reference, icls))
665 if rv is None:
666 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls))
667 else:
668 raise pyxb.IncompleteImplementationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, scope.targetNamespace(), type(scope), icls))
669 return rv
670
672 assert 0 == len(args)
673 name = kw.get('name')
674 # Must be None or a valid NCName
675 assert (name is None) or (0 > name.find(':')), 'name %s' % (name,)
676 self.__name = name
677
678 # Target namespace is taken from the context, unless somebody
679 # overrides it (as is done for local declarations if the form is
680 # unqualified).
681 self.__targetNamespace = kw.get('target_namespace', self._namespaceContext().targetNamespace())
682 self.__bindingNamespace = kw.get('binding_namespace')
683
684 self.__templateMap = {}
685
686 self.__schema = kw.get('schema')
687 assert self._schema() is not None
688
689 # Do parent invocations after we've set the name: they might need it.
690 super(_NamedComponent_mixin, self).__init__(*args, **kw)
691
693 """Return true iff this and the other component share the same name and target namespace.
694
695 Anonymous components are inherently name inequivalent, except to
696 themselves. This relies on equivalence as defined for
697 pyxb.namespace.ExpandedName, for which None is not equivalent to any
698 non-anonymous name."""
699 # Note that unpickled objects
700 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
701
703 """Return True iff this and the other component have matching types.
704
705 It appears that name equivalence is used; two complex type definitions
706 with identical structures are not considered equivalent (at least, per
707 XMLSpy).
708 """
709 return (type(self) == type(other)) and self.isNameEquivalent(other)
710
712 """Return True iff this type can serve as a restriction of the other
713 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}.
714
715 It appears that name equivalence is normally used; two complex type
716 definitions with identical structures are not considered equivalent
717 (at least, per XMLSpy). However, some OpenGIS standards demonstrate
718 that derivation by restriction from the other type is also acceptable.
719 That opens a whole can of worms; see
720 L{ElementDeclaration.isAdaptable}.
721 """
722 this = self
723 # can this succeed if component types are not equivalent?
724 while this is not None:
725 if this.isTypeEquivalent(other):
726 return True
727 if not (this.isResolved() and other.isResolved()):
728 raise pyxb.IncompleteImplementationError('Oh fudge. Somebody violated the assumptions in ElementDeclaration.isAdaptable.')
729 if isinstance(self, ComplexTypeDefinition):
730 if self.DM_restriction != this.derivationMethod():
731 return False
732 elif isinstance(self, SimpleTypeDefinition):
733 if self._DA_restriction != this._derivationAlternative():
734 return False
735 else:
736 raise pyxb.IncompleteImplementationError('Need derivation consistency check for type %s' % (type(this),))
737 this = this.baseTypeDefinition()
738 if this.isUrTypeDefinition():
739 # Well, this certainly can't be a valid restriction of
740 # anything else.
741 break
742 return False
743
745 if self.__needAnonymousSupport():
746 assert self._anonymousName() is not None
747 return _PickledAnonymousReference(self.targetNamespace(), self._anonymousName())
748 return self.expandedName().uriTuple()
749
751 if self.targetNamespace() is None:
752 return False
753 # Get the namespace we're pickling. If the namespace is None,
754 # we're not pickling; we're probably cloning, and in that case
755 # we don't want to use the reference state encoding.
756 pickling_archive = pyxb.namespace.archive.NamespaceArchive.PicklingArchive()
757 if pickling_archive is None:
758 return False
759 # If this thing is scoped in a complex type that belongs to the
760 # namespace being pickled, then it gets pickled as an object even if
761 # its target namespace isn't this one.
762 assert self._objectOrigin() is not None
763 if self._picklesInArchive(pickling_archive):
764 return False
765 # Note that anonymous objects must use their fallback
766 return True
767
769 if self.__pickleAsReference():
770 # NB: This instance may be a scoped declaration, but in
771 # this case (unlike getnewargs) we don't care about trying
772 # to look up a previous instance, so we don't need to
773 # encode the scope in the reference tuple.
774 return self._picklingReference()
775 if self.targetNamespace() is None:
776 # The only internal named objects that should exist are
777 # ones that have a non-global scope (including those with
778 # absent scope).
779 # @todo: this is wrong for schema that are not bound to a
780 # namespace, unless we use an unbound Namespace instance
781 #assert isinstance(self, _ScopedDeclaration_mixin)
782 #assert self.SCOPE_global != self.scope()
783 # NOTE: The name of the scope may be None. This is not a
784 # problem unless somebody tries to extend or restrict the
785 # scope type, which at the moment I'm thinking is
786 # impossible for anonymous types. If it isn't, we're
787 # gonna need some other sort of ID, like a UUID associated
788 # with the anonymous class at the time it's written to the
789 # preprocessed schema file.
790 pass
791 return super(_NamedComponent_mixin, self).__getstate__()
792
794 """Pickling support.
795
796 If this instance is being pickled as a reference, provide the
797 arguments that are necessary so that the unpickler can locate
798 the appropriate component rather than create a duplicate
799 instance."""
800
801 if self.__pickleAsReference():
802 scope = self._scope()
803 if isinstance(self, _ScopedDeclaration_mixin):
804 # If scope is global, we can look it up in the namespace.
805 # If scope is indeterminate, this must be within a group in
806 # another namespace. Why are we serializing it?
807 # If scope is local, provide the namespace and name of
808 # the type that holds it
809 if self.SCOPE_global == self.scope():
810 pass
811 elif isinstance(self.scope(), ComplexTypeDefinition):
812 scope = self.scope()._picklingReference()
813 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self
814 elif self._scopeIsIndeterminate():
815 # This is actually OK: we made sure both the scope and
816 # this instance can be looked up by a unique identifier.
817 pass
818 else:
819 raise pyxb.IncompleteImplementationError('pickling unrecognized scope %s type %s' % (self.scope(), type(self.scope())))
820 else:
821 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,)
822 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin())
823
824 rv = ( self._picklingReference(), scope, self.__class__ )
825 return rv
826 return ()
827
829 if isinstance(state, tuple):
830 # We don't actually have to set any state here; we just
831 # make sure that we resolved to an already-configured
832 # instance.
833 assert self.targetNamespace() is not None
834 assert self.targetNamespace().uri() == state[0]
835 assert self.name() == state[1]
836 return
837 if isinstance(state, _PickledAnonymousReference):
838 assert self.targetNamespace() is not None
839 assert self.targetNamespace() == state.namespace()
840 assert self.__needAnonymousSupport()
841 assert self._anonymousName() == state.anonymousName()
842 return
843 self.__dict__.update(state)
844
846 self.__schema = None
847 self_fn = lambda *_args, **_kw: self
848 rv = getattr(super(_NamedComponent_mixin, self), '_resetClone_csc', self_fn)(**kw)
849 self.__templateMap = { }
850 origin = kw.get('origin')
851 self.__anonymousName = None
852 self._setObjectOrigin(origin, override=True)
853 return rv
854
856 """Mix-in indicating that the component contains a simple-type
857 value that may be constrained."""
858
859 VC_na = 0 #<<< No value constraint applies
860 VC_default = 1 #<<< Provided value constraint is default value
861 VC_fixed = 2 #<<< Provided value constraint is fixed value
862
863 # None, or a tuple containing a string followed by one of the VC_*
864 # values above.
865 __valueConstraint = None
867 """A constraint on the value of the attribute or element.
868
869 Either None, or a pair consisting of a string in the lexical
870 space of the typeDefinition and one of VC_default and
871 VC_fixed."""
872 return self.__valueConstraint
873
875 """If this instance constraints a default value, return that
876 value; otherwise return None."""
877 if not isinstance(self.__valueConstraint, tuple):
878 return None
879 if self.VC_default != self.__valueConstraint[1]:
880 return None
881 return self.__valueConstraint[0]
882
884 """If this instance constraints a fixed value, return that
885 value; otherwise return None."""
886 if not isinstance(self.__valueConstraint, tuple):
887 return None
888 if self.VC_fixed != self.__valueConstraint[1]:
889 return None
890 return self.__valueConstraint[0]
891
893 aval = domutils.NodeAttribute(node, 'default')
894 if aval is not None:
895 self.__valueConstraint = (aval, self.VC_default)
896 return self
897 aval = domutils.NodeAttribute(node, 'fixed')
898 if aval is not None:
899 self.__valueConstraint = (aval, self.VC_fixed)
900 return self
901 self.__valueConstraint = None
902 return self
903
905 """Mix-in class for named components that have a scope.
906
907 Scope is important when doing cross-namespace inheritance,
908 e.g. extending or restricting a complex type definition that is
909 from a different namespace. In this case, we will need to retain
910 a reference to the external component when the schema is
911 serialized.
912
913 This is done in the pickling process by including the scope when
914 pickling a component as a reference. The scope is the
915 SCOPE_global if global; otherwise, it is a tuple containing the
916 external namespace URI and the NCName of the complex type
917 definition in that namespace. We assume that the complex type
918 definition has global scope; otherwise, it should not have been
919 possible to extend or restrict it. (Should this be untrue, there
920 are comments in the code about a possible solution.)
921
922 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}.
923 """
924
925 SCOPE_global = 'global' #<<< Marker to indicate global scope
926 XSCOPE_indeterminate = 'indeterminate' #<<< Marker to indicate scope has not been assigned
927
928 @classmethod
931
932 @classmethod
935
936 @classmethod
939
941 """Return True if this scope currently assigned to this instance is compatible with the given scope.
942
943 If either scope is indeterminate, presume they will ultimately be
944 compatible. Scopes that are equal are compatible, as is a local scope
945 if this already has a global scope."""
946 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()):
947 return True
948 if self.scope() == scope:
949 return True
950 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
951
952 # The scope for the element. Valid values are SCOPE_global or a
953 # complex type definition. None is an invalid value, but may
954 # appear if scope is determined by an ancestor component.
956 """The scope for the declaration.
957
958 Valid values are SCOPE_global, or a complex type definition.
959 A value of None means a non-global declaration that is not
960 owned by a complex type definition. These can only appear in
961 attribute group definitions or model group definitions.
962
963 @todo: For declarations in named model groups (viz., local
964 elements that aren't references), the scope needs to be set by
965 the owning complex type.
966 """
967 return self._scope()
968
969 # The base declaration is the original _ScopedDeclaration_mixin which
970 # introduced the element into its scope. This is used to retain a
971 # particular defining declaration when each extension type gets its own
972 # clone adapted for its scope.
973 __baseDeclaration = None
975 return self.__baseDeclaration or self
977 self.__baseDeclaration = referenced_declaration.baseDeclaration()
978 return self.__baseDeclaration
979
981 """This class represents an abstraction of the set of documents conformant
982 to a particle or particle term.
983
984 The abstraction of a given document is a map from element declarations
985 that can appear at the top level of the document to a boolean that is true
986 iff there could be multiple instances of that element declaration at the
987 top level of a valid document. The abstraction of the set is a list of
988 document abstractions.
989
990 This information is used in binding generation to determine whether a
991 field associated with a tag might need to hold multiple instances.
992 """
993
994 @classmethod
996 """Given two maps, return an updated map indicating the unified
997 plurality."""
998 umap = { }
999 for k in set(map1.keys()).union(map2.keys()):
1000 if k in map1:
1001 umap[k] = (k in map2) or map1[k]
1002 else:
1003 umap[k] = map2[k]
1004 return umap
1005
1007 """Combine all the document abstractions into a single one that covers
1008 all possible documents.
1009
1010 The combined plurality is simply the elemental maximum over all
1011 document abstractions.
1012 """
1013
1014 combined_plurality = { }
1015 for pdm in self:
1016 for (ed, v) in pdm.items():
1017 if isinstance(ed, ElementDeclaration):
1018 assert ed.baseDeclaration() == ed
1019 combined_plurality[ed] = combined_plurality.get(ed, False) or v
1020 elif isinstance(ed, Wildcard):
1021 pass
1022 else:
1023 raise pyxb.LogicError('Unexpected plurality index %s' % (ed,))
1024 return combined_plurality
1025
1027 # Start by collecting the data for each of the particles.
1028 pdll = [ _PluralityData(_p) for _p in model_group.particles() ]
1029 #dumpmap = lambda _pdm: ', '.join( [ '%s: %s' % (_ed.expandedName(), _pl) for (_ed, _pl) in _pdm.items() ])
1030 #dumpmapset = lambda _pd: '(' + ') | ('.join([ dumpmap(_pdm) for _pdm in _pd ]) + ')'
1031 if (ModelGroup.C_CHOICE == model_group.compositor()):
1032 # Plurality for choice is simply any of the pluralities of the particles
1033 [ self.extend(_pd) for _pd in pdll ]
1034 elif ((ModelGroup.C_SEQUENCE == model_group.compositor()) or (ModelGroup.C_ALL == model_group.compositor())):
1035 # Sequence means all of them, in all their glory. All is treated
1036 # the same way. Essentially this is a pointwise OR of the
1037 # pluralities of the particles.
1038 if 0 < len(pdll):
1039 new_pd = pdll.pop()
1040 for pd in pdll:
1041 assert 0 < len(pd)
1042 assert 0 < len(new_pd)
1043 stage_pd = [ ]
1044 for pdm1 in new_pd:
1045 for pdm2 in pd:
1046 stage_pd.append(self._MapUnion(pdm1, pdm2))
1047 new_pd = stage_pd
1048 self.extend(new_pd)
1049 else:
1050 raise pyxb.LogicError('Unrecognized compositor value %s' % (model_group.compositor(),))
1051
1053 assert particle.isResolved()
1054 pd = particle.term().pluralityData()
1055
1056 # If the particle can't appear at all, there are no results.
1057 if 0 == particle.maxOccurs():
1058 return
1059
1060 # If the particle can only occur once, it has no effect on the
1061 # pluralities; use the term to identify them
1062 if 1 == particle.maxOccurs():
1063 self.__setFromComponent(particle.term())
1064 return
1065
1066 # If there are multiple alternatives, assume they are all
1067 # taken. Do this by creating a map that treats every possible
1068 # element as appearing multiple times.
1069 true_map = {}
1070 pd = _PluralityData(particle.term())
1071 while 0 < len(pd):
1072 pdm = pd.pop()
1073 [ true_map.setdefault(_k, True) for _k in pdm.keys() ]
1074 self.append(true_map)
1075
1077 del self[:]
1078 if isinstance(component, ElementDeclaration):
1079 assert component.isResolved()
1080 assert isinstance(component.baseDeclaration(), ElementDeclaration)
1081 self.append( { component.baseDeclaration(): False } )
1082 #self.append( { component: False } )
1083 elif isinstance(component, ModelGroup):
1084 self.__fromModelGroup(component)
1085 elif isinstance(component, Particle):
1086 self.__fromParticle(component)
1087 elif isinstance(component, Wildcard):
1088 pass
1089 elif component is not None:
1090 raise pyxb.IncompleteImplementationError("No support for plurality of component type %s" % (type(component),))
1091 # Elements get lost if there's a result set that doesn't have any
1092 # documents in it.
1093 if 0 == len(self):
1094 self.append({})
1095
1099
1101 """Support for components that accept attribute wildcards.
1102
1103 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The
1104 calculations of the appropriate wildcard are sufficiently complex that
1105 they need to be abstracted out to a mix-in class."""
1106
1107 # Optional wildcard that constrains attributes
1108 __attributeWildcard = None
1109
1111 """Return the L{Wildcard} component associated with attributes of this
1112 instance, or C{None} if attribute wildcards are not present in the
1113 instance."""
1114 return self.__attributeWildcard
1115
1117 """Set the attribute wildcard property for this instance."""
1118 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard)
1119 self.__attributeWildcard = attribute_wildcard
1120 return self
1121
1123 """Return the nodes that are relevant for attribute processing.
1124
1125 @param node_list: A sequence of nodes found in a definition content
1126 information item.
1127
1128 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)}
1129 where C{attributes} is the subsequence of C{node_list} that are
1130 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and
1131 C{attributeWildcard} is a single DOM node with XMLSchema name
1132 C{anyAttribute} (or C{None}, if no such node is present in the list).
1133
1134 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is
1135 present but does not have the required C{ref} attribute.
1136 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are
1137 identified.
1138 """
1139
1140 attributes = []
1141 attribute_groups = []
1142 any_attribute = None
1143 # Handle clauses 1 and 2 (common between simple and complex types)
1144 for node in node_list:
1145 if Node.ELEMENT_NODE != node.nodeType:
1146 continue
1147 if xsd.nodeIsNamed(node, 'attribute'):
1148 # Note: This attribute use instance may have use=prohibited
1149 attributes.append(node)
1150 elif xsd.nodeIsNamed(node, 'attributeGroup'):
1151 # This must be an attributeGroupRef
1152 agd_attr = domutils.NodeAttribute(node, 'ref')
1153 if agd_attr is None:
1154 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements')
1155 attribute_groups.append(agd_attr)
1156 elif xsd.nodeIsNamed(node, 'anyAttribute'):
1157 if any_attribute is not None:
1158 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed')
1159 any_attribute = node
1160
1161 return (attributes, attribute_groups, any_attribute)
1162
1163 @classmethod
1165 """Implement the algorithm as described the
1166 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}.
1167
1168 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be
1169 associated with any created L{Wildcard} instance
1170 @param attribute_groups: A list of L{AttributeGroupDefinition} instances
1171 @param local_wildcard: A L{Wildcard} instance computed from a relevant
1172 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard
1173 is relevant
1174 """
1175
1176 # Non-absent wildcard properties of attribute groups
1177 agd_wildcards = []
1178 for agd in attribute_groups:
1179 assert isinstance(agd, AttributeGroupDefinition)
1180 if agd.attributeWildcard() is not None:
1181 agd_wildcards.append(agd.attributeWildcard())
1182 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ]
1183
1184 # Clause 2.1
1185 if 0 == len(agd_wildcards):
1186 return local_wildcard
1187
1188 if local_wildcard is not None:
1189 # Clause 2.2.1
1190 return Wildcard(process_contents=local_wildcard.processContents(),
1191 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]),
1192 annotation=local_wildcard.annotation(),
1193 namespace_context=namespace_context)
1194 # Clause 2.2.2
1195 return Wildcard(process_contents=agd_wildcards[0].processContents(),
1196 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints),
1197 namespace_context=namespace_context)
1198
1199 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1200 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component.
1201 """
1202
1203 # The STD to which attribute values must conform
1204 __typeDefinition = None
1206 """The simple type definition to which an attribute value must
1207 conform."""
1208 return self.__typeDefinition
1209
1210 # The string value of the XSD type attribute
1211 __typeAttribute = None
1212
1216
1218 if self.typeDefinition():
1219 return 'AD[%s:%s]' % (self.name(), self.typeDefinition().expandedName())
1220 return 'AD[%s:?]' % (self.expandedName(),)
1221
1222 @classmethod
1224 """Create an attribute declaration component for a specified namespace."""
1225 kw = { 'name' : name,
1226 'schema' : schema,
1227 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
1228 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1229 assert schema is not None
1230 bi = cls(**kw)
1231 if std is not None:
1232 bi.__typeDefinition = std
1233 bi.__typeAttribute = None
1234 return bi
1235
1236 # CFD:AD CFD:AttributeDeclaration
1237 @classmethod
1239 """Create an attribute declaration from the given DOM node.
1240
1241 wxs is a Schema instance within which the attribute is being
1242 declared.
1243
1244 node is a DOM element. The name must be one of ( 'all',
1245 'choice', 'sequence' ), and the node must be in the XMLSchema
1246 namespace.
1247
1248 scope is the _ScopeDeclaration_mxin context into which the
1249 attribute declaration is placed. It can be SCOPE_global, a
1250 complex type definition, or XSCOPE_indeterminate if this is an
1251 anonymous declaration within an attribute group. It is a
1252 required parameter for this function.
1253 """
1254
1255 scope = kw['scope']
1256 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1257
1258 # Node should be an XMLSchema attribute node
1259 assert xsd.nodeIsNamed(node, 'attribute')
1260
1261 name = domutils.NodeAttribute(node, 'name')
1262
1263 # Implement per section 3.2.2
1264 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1265 assert cls.SCOPE_global == scope
1266 elif domutils.NodeAttribute(node, 'ref') is None:
1267 # This is an anonymous declaration within an attribute use
1268 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1269 else:
1270 raise pyxb.SchemaValidationError('Internal attribute declaration by reference')
1271
1272 rv = cls(name=name, node=node, **kw)
1273 rv._annotationFromDOM(node)
1274 rv._valueConstraintFromDOM(node)
1275
1276 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1277
1278 kw.pop('node', None)
1279 kw['owner'] = rv
1280
1281 st_node = domutils.LocateUniqueChild(node, 'simpleType')
1282 if st_node is not None:
1283 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw)
1284 elif rv.__typeAttribute is None:
1285 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition()
1286
1287 if rv.__typeDefinition is None:
1288 rv._queueForResolution('creation')
1289 return rv
1290
1292 return self.__typeDefinition is not None
1293
1294 # res:AD res:AttributeDeclaration
1296 if self.isResolved():
1297 return self
1298
1299 # Although the type definition may not be resolved, *this* component
1300 # is resolved, since we don't look into the type definition for anything.
1301 assert self.__typeAttribute is not None, 'AD %s is unresolved but has no typeAttribute field' % (self.expandedName(),)
1302 type_en = self._namespaceContext().interpretQName(self.__typeAttribute)
1303 self.__typeDefinition = type_en.typeDefinition()
1304 if self.__typeDefinition is None:
1305 raise pyxb.SchemaValidationError('Type reference %s cannot be found' % (type_en,))
1306 if not isinstance(self.__typeDefinition, SimpleTypeDefinition):
1307 raise pyxb.SchemaValidationError('Need %s to be a simple type' % (type_en,))
1308
1309 return self
1310
1312 """Override fields in this instance with those from the other.
1313
1314 This method is invoked only by Schema._addNamedComponent, and
1315 then only when a built-in type collides with a schema-defined
1316 type. Material like facets is not (currently) held in the
1317 built-in copy, so the DOM information is copied over to the
1318 built-in STD, which is subsequently re-resolved.
1319
1320 Returns self.
1321 """
1322 assert self != other
1323 assert self.name() is not None
1324 assert self.isNameEquivalent(other)
1325 super(AttributeDeclaration, self)._updateFromOther_csc(other)
1326
1327 # The other STD should be an unresolved schema-defined type.
1328 # Mark this instance as unresolved so it is re-examined
1329 if not other.isResolved():
1330 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID():
1331 #assert self.isResolved(), 'Built-in %s is not resolved' % (self.expandedName(),)
1332 _log.warning('Not destroying builtin %s: %s', self.expandedName(), self.__typeDefinition)
1333 else:
1334 self.__typeDefinition = None
1335 return self
1336
1337 # bR:AD
1339 """Attribute declarations require their type."""
1340 return frozenset([ self.__typeDefinition ])
1341
1342 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1343 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component."""
1344
1345 # How this attribute can be used. The component property
1346 # "required" is true iff the value is USE_required.
1347 __use = None
1348
1349 USE_required = 0x01 #<<< The attribute is required
1350 USE_optional = 0x02 #<<< The attribute may or may not appear
1351 USE_prohibited = 0x04 #<<< The attribute must not appear
1352
1355
1358
1359 # The string value of the XSD ref attribute
1360 __refAttribute = None
1361
1362 __restrictionOf = None
1364 return self.__restrictionOf
1366 assert isinstance(au, AttributeUse)
1367 # Might re-assign if had to suspend resolution
1368 assert (self.__restrictionOf is None) or (self.__restrictionOf == au)
1369 self.__restrictionOf = au
1370
1371 # A reference to an AttributeDeclaration
1373 """The attribute declaration for this use.
1374
1375 When the use scope is assigned, the declaration is cloned (if
1376 necessary) so that each declaration corresponds to only one use. We
1377 rely on this in code generation, because the template map for the use
1378 is stored in its declaration."""
1379 return self.__attributeDeclaration
1380 __attributeDeclaration = None
1381
1382 # Define so superclasses can take keywords
1385
1387 """Return the subset of au_set for which the use names match this use."""
1388
1389 if not self.isResolved():
1390 return None
1391 this_ad = self.attributeDeclaration()
1392 rv = set()
1393 for au in au_set:
1394 if not au.isResolved():
1395 return None
1396 that_ad = au.attributeDeclaration()
1397 if this_ad.isNameEquivalent(that_ad):
1398 rv.add(au)
1399 return rv
1400
1401 @classmethod
1403 kw = { 'schema' : schema,
1404 'namespace_context' : schema.targetNamespace().initialNamespaceContext() }
1405 bi = cls(**kw)
1406 assert isinstance(attribute_declaration, AttributeDeclaration)
1407 bi.__attributeDeclaration = attribute_declaration
1408 bi.__use = use
1409 return bi
1410
1411 # CFD:AU CFD:AttributeUse
1412 @classmethod
1414 """Create an Attribute Use from the given DOM node.
1415
1416 wxs is a Schema instance within which the attribute use is
1417 being defined.
1418
1419 node is a DOM element. The name must be 'attribute', and the
1420 node must be in the XMLSchema namespace.
1421
1422 scope is the _ScopeDeclaration_mixin context into which any
1423 required anonymous attribute declaration is put. This must be
1424 a complex type definition, or None if this use is in an
1425 attribute group.
1426 """
1427
1428 scope = kw['scope']
1429 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1430 assert xsd.nodeIsNamed(node, 'attribute')
1431 schema = kw['schema']
1432 rv = cls(node=node, **kw)
1433
1434 rv.__use = cls.USE_optional
1435 use = domutils.NodeAttribute(node, 'use')
1436 if use is not None:
1437 if 'required' == use:
1438 rv.__use = cls.USE_required
1439 elif 'optional' == use:
1440 rv.__use = cls.USE_optional
1441 elif 'prohibited' == use:
1442 rv.__use = cls.USE_prohibited
1443 else:
1444 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,))
1445
1446 rv._valueConstraintFromDOM(node)
1447
1448 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
1449 if rv.__refAttribute is None:
1450 # Create an anonymous declaration
1451 kw.pop('node', None)
1452 kw['owner'] = rv
1453 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration)
1454 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw)
1455
1456 if not rv.isResolved():
1457 rv._queueForResolution('creation')
1458
1459 return rv
1460
1462 return self.__attributeDeclaration is not None
1463
1465 if self.isResolved():
1466 return self
1467 ad_en = self._namespaceContext().interpretQName(self.__refAttribute)
1468 self.__attributeDeclaration = ad_en.attributeDeclaration()
1469 if self.__attributeDeclaration is None:
1470 raise pyxb.SchemaValidationError('Attribute declaration %s cannot be found' % (ad_en,))
1471
1472 assert isinstance(self.__attributeDeclaration, AttributeDeclaration)
1473
1474 return self
1475
1476 # bR:AU
1478 """Attribute uses require their declarations, but only if lax."""
1479 if not include_lax:
1480 return frozenset()
1481 return frozenset([ self.attributeDeclaration() ])
1482
1483 # aFS:AU
1485 """Adapt this instance for the given complex type.
1486
1487 If the attribute declaration for this use is not associated with a
1488 complex type definition, then associate a clone of it with this CTD,
1489 and clone a new attribute use that uses the associated declaration.
1490 This attribute use is then inherited by extensions and restrictions,
1491 while retaining its original scope."""
1492 rv = self
1493 assert self.isResolved()
1494 ad = self.__attributeDeclaration
1495 assert ad.scope() is not None
1496 assert isinstance(ctd, ComplexTypeDefinition)
1497 if not isinstance(ad.scope(), ComplexTypeDefinition):
1498 rv = self._clone(ctd, ctd._objectOrigin())
1499 rv.__attributeDeclaration = ad._clone(rv, ctd._objectOrigin())
1500 rv.__attributeDeclaration._setScope(ctd)
1501 ctd._recordLocalDeclaration(rv.__attributeDeclaration)
1502 return rv
1503
1505 return 'AU[%s]' % (self.attributeDeclaration(),)
1506
1507
1508 -class ElementDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1509 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component."""
1510
1511 # Simple or complex type definition
1512 __typeDefinition = None
1514 """The simple or complex type to which the element value conforms."""
1515 return self.__typeDefinition
1519
1520 __substitutionGroupAttribute = None
1521
1522 __typeAttribute = None
1523
1524 __nillable = False
1526 return self.__nillable
1527
1528 __identityConstraintDefinitions = None
1530 """A list of IdentityConstraintDefinition instances."""
1531 return self.__identityConstraintDefinitions
1532
1533 __substitutionGroupAffiliation = None
1535 """None, or a reference to an ElementDeclaration."""
1536 return self.__substitutionGroupAffiliation
1537
1538 SGE_none = 0 #<<< No substitution group exclusion specified
1539 SGE_extension = 0x01 #<<< Substitution by an extension of the base type
1540 SGE_restriction = 0x02 #<<< Substitution by a restriction of the base type
1541 SGE_substitution = 0x04 #<<< Substitution by replacement (?)
1542
1543 _SGE_Map = { 'extension' : SGE_extension
1544 , 'restriction' : SGE_restriction }
1545 _DS_Map = _SGE_Map.copy()
1546 _DS_Map.update( { 'substitution' : SGE_substitution } )
1547
1548 # Subset of SGE marks formed by bitmask. SGE_substitution is disallowed.
1549 __substitutionGroupExclusions = SGE_none
1550
1551 # Subset of SGE marks formed by bitmask
1552 __disallowedSubstitutions = SGE_none
1553
1554 __abstract = False
1556 return self.__abstract
1557
1559 """Return the plurality information for this component.
1560
1561 An ElementDeclaration produces one instance of a single element."""
1562 return _PluralityData(self)
1563
1567
1568 # bR:ED
1570 """Element declarations depend on the type definition of their
1571 content."""
1572 return frozenset([self.__typeDefinition])
1573
1576
1577 # CFD:ED CFD:ElementDeclaration
1578 @classmethod
1580 """Create an element declaration from the given DOM node.
1581
1582 wxs is a Schema instance within which the element is being
1583 declared.
1584
1585 scope is the _ScopeDeclaration_mixin context into which the
1586 element declaration is recorded. It can be SCOPE_global, a
1587 complex type definition, or None in the case of elements
1588 declared in a named model group.
1589
1590 node is a DOM element. The name must be 'element', and the
1591 node must be in the XMLSchema namespace."""
1592
1593 scope = kw['scope']
1594 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1595
1596 # Node should be an XMLSchema element node
1597 assert xsd.nodeIsNamed(node, 'element')
1598
1599 # Might be top-level, might be local
1600 name = domutils.NodeAttribute(node, 'name')
1601 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1602 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1603 elif domutils.NodeAttribute(node, 'ref') is None:
1604 # Scope may be None or a CTD.
1605 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1606 else:
1607 raise pyxb.SchemaValidationError('Created reference as element declaration')
1608
1609 rv = cls(name=name, node=node, **kw)
1610 rv._annotationFromDOM(node)
1611 rv._valueConstraintFromDOM(node)
1612
1613 rv.__substitutionGroupAttribute = domutils.NodeAttribute(node, 'substitutionGroup')
1614
1615 kw.pop('node', None)
1616 kw['owner'] = rv
1617
1618 identity_constraints = []
1619 for cn in node.childNodes:
1620 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1621 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1622 rv.__identityConstraintDefinitions = identity_constraints
1623
1624 rv.__typeDefinition = None
1625 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1626 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1627 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1628 if rv.__typeAttribute is not None:
1629 if (simpleType_node is not None) and (complexType_node is not None):
1630 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1631 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1632 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw)
1633 if (rv.__typeDefinition is None) and (complexType_node is not None):
1634 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw)
1635 if rv.__typeDefinition is None:
1636 if rv.__typeAttribute is None:
1637 # Scan for particle types which were supposed to be enclosed in a complexType
1638 for cn in node.childNodes:
1639 if Particle.IsParticleNode(cn):
1640 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1641 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition()
1642 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1643 if not rv.__isResolved:
1644 rv._queueForResolution('creation')
1645
1646 attr_val = domutils.NodeAttribute(node, 'nillable')
1647 if attr_val is not None:
1648 rv.__nillable = datatypes.boolean(attr_val)
1649
1650 attr_val = domutils.NodeAttribute(node, 'abstract')
1651 if attr_val is not None:
1652 rv.__abstract = datatypes.boolean(attr_val)
1653
1654 schema = kw['schema']
1655 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1656 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1657
1658 return rv
1659
1661 """Determine whether this element declaration is adaptable.
1662
1663 OK, this gets ugly. First, if this declaration isn't resolved, it's
1664 clearly not adaptable.
1665
1666 Now: For it to be adaptable, we must know enough about its type to
1667 verify that it is derivation-consistent with any other uses of the
1668 same name in the same complex type. If the element's type is
1669 resolved, that's good enough.
1670
1671 If the element's type isn't resolved, we're golden as long as
1672 type-equivalent types were used. But it's also allowed for the
1673 derived ctd to use the element name constraining it to a derivation of
1674 the element base type. (Go see namespace
1675 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1676 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1677 have to have the element's type resolved.
1678
1679 Except that if a CTD's content incorporates an element with the same
1680 type as the CTD (i.e., nested), this will never happen, because the
1681 CTD can't get resolved until after it has been resolved.
1682 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1683 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1684 an example).
1685
1686 So, we give the world a break and assume that if the type we're trying
1687 to resolve is the same as the type of an element in that type, then
1688 the element type will be resolved by the point it's needed. In point
1689 of fact, it won't, but we'll only notice that if a CTD contains an
1690 element whose type is a restriction of the CTD. In that case,
1691 isDerivationConsistent will blow chunks and somebody'll have to come
1692 back and finish up this mess.
1693 """
1694
1695 if not self.isResolved():
1696 return False
1697 if self.typeDefinition().isResolved():
1698 return True
1699 # Aw, dammit. See if we're gonna need the type resolved before we can
1700 # adapt this thing.
1701 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1702 if existing_decl is None:
1703 # Nobody else has this name, so we don't have to check for
1704 # consistency.
1705 return True
1706 # OK, we've got a name clash. Are the two types trivially equivalent?
1707 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1708 # Yes! Go for it.
1709 return True
1710 # No. Can't proceed until the type definition is resolved. Hope it
1711 # can be....
1712 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1713 return False
1714
1715 # aFS:ED
1717 rv = self
1718 assert isinstance(ctd, ComplexTypeDefinition), '%s is not a CTD' % (ctd,)
1719 if not isinstance(self.scope(), ComplexTypeDefinition):
1720 assert owner is not None
1721 rv = self._clone(owner, ctd._objectOrigin())
1722 rv._setScope(ctd)
1723 ctd._recordLocalDeclaration(rv)
1724 return rv
1725
1726 __isResolved = False
1728 return self.__isResolved
1729
1730 # res:ED res:ElementDeclaration
1732 if self.isResolved():
1733 return self
1734
1735 #if self._scopeIsIndeterminate():
1736 # _log.debug('WARNING: Resolving ED %s with indeterminate scope (is this a problem?)', self.expandedName())
1737 if self.__substitutionGroupAttribute is not None:
1738 sg_en = self._namespaceContext().interpretQName(self.__substitutionGroupAttribute)
1739 sga = sg_en.elementDeclaration()
1740 if sga is None:
1741 raise pyxb.SchemaValidationError('Element declaration refers to unrecognized substitution group %s' % (sg_en,))
1742 self.__substitutionGroupAffiliation = sga
1743
1744 if self.__typeDefinition is None:
1745 assert self.__typeAttribute is not None
1746 type_en = self._namespaceContext().interpretQName(self.__typeAttribute)
1747 self.__typeDefinition = type_en.typeDefinition()
1748 if self.__typeDefinition is None:
1749 raise pyxb.SchemaValidationError('Type declaration %s cannot be found' % (type_en,))
1750
1751 self.__isResolved = True
1752 return self
1753
1755 if self.typeDefinition() is not None:
1756 return 'ED[%s:%s]' % (self.name(), self.typeDefinition().name())
1757 return 'ED[%s:?]' % (self.name(),)
1758
1759
1760 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1761 __PrivateTransient = set()
1762
1763 # The type resolved from the base attribute.
1764 __baseTypeDefinition = None
1768
1769 DM_empty = 0 #<<< No derivation method specified
1770 DM_extension = 0x01 #<<< Derivation by extension
1771 DM_restriction = 0x02 #<<< Derivation by restriction
1772
1773 _DM_Map = { 'extension' : DM_extension
1774 , 'restriction' : DM_restriction }
1775
1776 # How the type was derived (a DM_* value)
1777 # (This field is used to identify unresolved definitions.)
1778 __derivationMethod = None
1782
1783 # Derived from the final and finalDefault attributes
1784 __final = DM_empty
1785
1786 # Derived from the abstract attribute
1787 __abstract = False
1789 return self.__abstract
1790
1791 # A frozenset() of AttributeUse instances.
1792 __attributeUses = None
1796
1797 # A map from NCNames to AttributeDeclaration instances that are
1798 # local to this type.
1799 __scopedAttributeDeclarations = None
1801 """Find an attribute declaration with the given name that is local to this type.
1802
1803 Returns None if there is no such local attribute declaration."""
1804 if self.__scopedAttributeDeclarations is None:
1805 return None
1806 return self.__scopedAttributeDeclarations.get(expanded_name)
1807
1808 # A map from NCNames to ElementDeclaration instances that are
1809 # local to this type.
1810 __scopedElementDeclarations = None
1812 """Find an element declaration with the given name that is local to this type.
1813
1814 Returns None if there is no such local element declaration."""
1815 if self.__scopedElementDeclarations is None:
1816 return None
1817 return self.__scopedElementDeclarations.get(expanded_name)
1818
1819 __localScopedDeclarations = None
1821 """Return a list of element and attribute declarations that were
1822 introduced in this definition (i.e., their scope is this CTD).
1823
1824 @note: This specifically returns a list, with element declarations
1825 first, because name binding should privilege the elements over the
1826 attributes. Within elements and attributes, the components are sorted
1827 by expanded name, to ensure consistency across a series of binding
1828 generations.
1829
1830 @keyword reset: If C{False} (default), a cached previous value (if it
1831 exists) will be returned.
1832 """
1833 if reset or (self.__localScopedDeclarations is None):
1834 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1835 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1836 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1837 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1838 self.__localScopedDeclarations = rve
1839 self.__localScopedDeclarations.extend(rva)
1840 return self.__localScopedDeclarations
1841
1843 """Record the given declaration as being locally scoped in
1844 this type."""
1845 assert isinstance(decl, _ScopedDeclaration_mixin)
1846 if isinstance(decl, ElementDeclaration):
1847 scope_map = self.__scopedElementDeclarations
1848 elif isinstance(decl, AttributeDeclaration):
1849 scope_map = self.__scopedAttributeDeclarations
1850 else:
1851 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1852 decl_en = decl.expandedName()
1853 existing_decl = scope_map.setdefault(decl_en, decl)
1854 if decl != existing_decl:
1855 if isinstance(decl, ElementDeclaration):
1856 # Test cos-element-consistent
1857 existing_type = existing_decl.typeDefinition()
1858 pending_type = decl.typeDefinition()
1859 if not pending_type.isDerivationConsistent(existing_type):
1860 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1861 elif isinstance(decl, AttributeDeclaration):
1862 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1863 else:
1864 assert False, 'Unrecognized type %s' % (type(decl),)
1865 decl._baseDeclaration(existing_decl)
1866 return self
1867
1869 """Return C{True} iff this is the root of a complex type definition hierarchy.
1870 """
1871 base = self.__baseTypeDefinition
1872 return isinstance(base, SimpleTypeDefinition) or base.isUrTypeDefinition()
1873
1874 CT_EMPTY = 'EMPTY' #<<< No content
1875 CT_SIMPLE = 'SIMPLE' #<<< Simple (character) content
1876 CT_MIXED = 'MIXED' #<<< Children may be elements or other (e.g., character) content
1877 CT_ELEMENT_ONLY = 'ELEMENT_ONLY' #<<< Expect only element content.
1878
1880 """Return the value of the content type identifier, i.e. one of the
1881 CT_ constants. Return value is None if no content type has been
1882 defined."""
1883 if isinstance(self.__contentType, tuple):
1884 return self.__contentType[0]
1885 return self.__contentType
1886
1891
1892 # Identify the sort of content in this type.
1893 __contentType = None
1895 """Identify the sort of content in this type.
1896
1897 Valid values are:
1898 - C{CT_EMPTY}
1899 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1900 - ( C{CT_MIXED}, a L{Particle} instance )
1901 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1902 """
1903 return self.__contentType
1904
1906 if self.CT_EMPTY == self.contentType():
1907 return 'EMPTY'
1908 ( tag, particle ) = self.contentType()
1909 if self.CT_SIMPLE == tag:
1910 return 'Simple [%s]' % (particle,)
1911 if self.CT_MIXED == tag:
1912 return 'Mixed [%s]' % (particle,)
1913 if self.CT_ELEMENT_ONLY == tag:
1914 return 'Element [%s]' % (particle,)
1915 raise pyxb.LogicError('Unhandled content type')
1916
1917 # Derived from the block and blockDefault attributes
1918 __prohibitedSubstitutions = DM_empty
1919
1920 # @todo: Extracted from children of various types
1921 __annotations = None
1922
1924 super(ComplexTypeDefinition, self).__init__(*args, **kw)
1925 self.__derivationMethod = kw.get('derivation_method')
1926 self.__scopedElementDeclarations = { }
1927 self.__scopedAttributeDeclarations = { }
1928
1930 """Return True iff this type includes a wildcard element in
1931 its content model."""
1932 if self.CT_EMPTY == self.contentType():
1933 return False
1934 ( tag, particle ) = self.contentType()
1935 if self.CT_SIMPLE == tag:
1936 return False
1937 return particle.hasWildcardElement()
1938
1940 """Override fields in this instance with those from the other.
1941
1942 This method is invoked only by Schema._addNamedComponent, and
1943 then only when a built-in type collides with a schema-defined
1944 type. Material like facets is not (currently) held in the
1945 built-in copy, so the DOM information is copied over to the
1946 built-in STD, which is subsequently re-resolved.
1947
1948 Returns self.
1949 """
1950 assert self != other
1951 assert self.isNameEquivalent(other)
1952 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1953
1954 if not other.isResolved():
1955 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1956 self.__derivationMethod = None
1957
1958 return self
1959
1960 __UrTypeDefinition = None
1961 @classmethod
1963 """Create the ComplexTypeDefinition instance that approximates
1964 the ur-type.
1965
1966 See section 3.4.7.
1967 """
1968
1969 # The first time, and only the first time, this is called, a
1970 # namespace should be provided which is the XMLSchema
1971 # namespace for this run of the system. Please, do not try to
1972 # allow this by clearing the type definition.
1973 #if in_builtin_definition and (cls.__UrTypeDefinition is not None):
1974 # raise pyxb.LogicError('Multiple definitions of UrType')
1975 if cls.__UrTypeDefinition is None:
1976 # NOTE: We use a singleton subclass of this class
1977 assert schema is not None
1978
1979 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1980
1981 kw = { 'name' : 'anyType',
1982 'schema' : schema,
1983 'namespace_context' : ns_ctx,
1984 'binding_namespace' : schema.targetNamespace(),
1985 'derivation_method' : cls.DM_restriction,
1986 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1987 bi = _UrTypeDefinition(**kw)
1988
1989 # The ur-type is its own baseTypeDefinition
1990 bi.__baseTypeDefinition = bi
1991
1992 # No constraints on attributes
1993 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1994
1995 # There isn't anything to look up, but context is still global.
1996 # No declarations will be created, so use indeterminate scope to
1997 # be consistent with validity checks in Particle constructor.
1998 # Content is mixed, with elements completely unconstrained. @todo:
1999 # not associated with a schema (it should be)
2000 kw = { 'namespace_context' : ns_ctx
2001 , 'schema' : schema
2002 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
2003 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
2004 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
2005 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
2006 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
2007
2008 # No attribute uses
2009 bi.__attributeUses = set()
2010
2011 # No constraints on extension or substitution
2012 bi.__final = cls.DM_empty
2013 bi.__prohibitedSubstitutions = cls.DM_empty
2014
2015 bi.__abstract = False
2016
2017 # Refer to it by name
2018 bi.setNameInBinding(bi.name())
2019
2020 # The ur-type is always resolved
2021 bi.__derivationMethod = cls.DM_restriction
2022
2023 cls.__UrTypeDefinition = bi
2024 return cls.__UrTypeDefinition
2025
2027 """Indicate whether this simple type is a built-in type."""
2028 return (self.UrTypeDefinition() == self)
2029
2030 # bR:CTD
2032 """Complex type definitions depend on their base type definition, the
2033 type definitions of any local attribute declarations, and if strict
2034 the type definitions of any local element declarations."""
2035 rv = set()
2036 assert self.__baseTypeDefinition is not None
2037 rv.add(self.__baseTypeDefinition)
2038 for decl in self.localScopedDeclarations():
2039 if include_lax or isinstance(decl, AttributeDeclaration):
2040 rv.add(decl.typeDefinition())
2041 if include_lax:
2042 ct = self._contentTypeComponent()
2043 if ct is not None:
2044 rv.add(ct)
2045 return frozenset(rv)
2046
2047 # CFD:CTD CFD:ComplexTypeDefinition
2048 @classmethod
2050 # Node should be an XMLSchema complexType node
2051 assert xsd.nodeIsNamed(node, 'complexType')
2052
2053 name = domutils.NodeAttribute(node, 'name')
2054
2055 rv = cls(name=name, node=node, derivation_method=None, **kw)
2056
2057 if name is None:
2058 assert not isinstance(rv.owner(), Schema)
2059
2060 # Most of the time, the scope will be global. It can be something
2061 # else only if this is an anonymous CTD (created within an element
2062 # declaration which itself may be global, in a containing CTD, or in a
2063 # model group).
2064 if not (rv._scopeIsGlobal() or rv.isAnonymous()):
2065 raise pyxb.LogicError('Attempt to create non-global complex type definition')
2066
2067 kw.pop('node', None)
2068 kw['owner'] = rv
2069 kw['scope'] = rv
2070
2071 return rv.__setContentFromDOM(node, **kw)
2072
2073 __baseAttribute = None
2074
2075
2076 __ckw = None
2077 __anyAttribute = None
2078 __attributeGroupAttributes = None
2079 __usesC1 = None
2080 __usesC1C2 = None
2081 __attributeGroups = None
2082 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2083
2084 # Handle attributeUses, attributeWildcard, contentType
2086
2087 if self.__usesC1C2 is None:
2088 # Handle clauses 1 and 2 (common between simple and complex types)
2089 uses_c1 = self.__usesC1 # attribute children
2090 uses_c2 = set() # attribute group children
2091 self.__attributeGroups = []
2092 for ag_attr in self.__attributeGroupAttributes:
2093 ag_en = self._namespaceContext().interpretQName(ag_attr)
2094 agd = ag_en.attributeGroupDefinition()
2095 if agd is None:
2096 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2097 if not agd.isResolved():
2098 self._queueForResolution('unresolved attribute group', depends_on=agd)
2099 return self
2100 self.__attributeGroups.append(agd)
2101 uses_c2.update(agd.attributeUses())
2102
2103 uses_c1c2 = uses_c1.union(uses_c2)
2104 for au in uses_c1c2:
2105 if not au.isResolved():
2106 self._queueForResolution('attribute use not resolved')
2107 return self
2108 ad = au.attributeDeclaration()
2109 if not ad.isResolved():
2110 ad_en = ad.expandedName()
2111 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2112 return self
2113
2114 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2115
2116 # Handle clause 3. Note the slight difference in description between
2117 # simple and complex content is just that the complex content doesn't
2118 # bother to check that the base type definition is a complex type
2119 # definition. So the same code should work for both, and we don't
2120 # bother to check content_style.
2121 uses_c3 = set() # base attributes
2122 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2123 # NB: The base type definition should be resolved, which means
2124 # that all its attribute uses have been adapted for scope already
2125 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2126 assert self.__baseTypeDefinition.isResolved()
2127 for au in uses_c3:
2128 if not au.isResolved():
2129 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2130 return self
2131 ad = au.attributeDeclaration()
2132 if not ad.isResolved():
2133 ad_en = ad.expandedName()
2134 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2135 return self
2136 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2137
2138 if self.DM_restriction == method:
2139 # Exclude attributes per clause 3. Note that this process
2140 # handles both 3.1 and 3.2, since we have not yet filtered
2141 # uses_c1 for prohibited attributes.
2142 for au in self.__usesC1C2:
2143 matching_uses = au.matchingQNameMembers(uses_c3)
2144 assert matching_uses is not None
2145 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2146 for au2 in matching_uses:
2147 assert au2.isResolved()
2148 uses_c3.remove(au2)
2149 au._setRestrictionOf(au2)
2150 else:
2151 # In theory, the same attribute name can't appear in the base
2152 # and sub types because that would violate the local
2153 # declaration constraint.
2154 assert self.DM_extension == method
2155
2156 use_map = { }
2157 for au in self.__usesC1C2.union(uses_c3):
2158 assert au.isResolved()
2159 ad_en = au.attributeDeclaration().expandedName()
2160 if ad_en in use_map:
2161 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2162 use_map[ad_en] = au
2163
2164 # Past the last point where we might not resolve this instance. Store
2165 # the attribute uses, also recording local attribute declarations.
2166 self.__attributeUses = frozenset(use_map.values())
2167 if not self._scopeIsIndeterminate():
2168 for au in self.__attributeUses:
2169 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2170
2171 # @todo: Handle attributeWildcard
2172 # Clause 1
2173 local_wildcard = None
2174 if self.__anyAttribute is not None:
2175 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2176
2177 # Clause 2
2178 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2179
2180 # Clause 3
2181 if self.DM_restriction == method:
2182 # Clause 3.1
2183 self._setAttributeWildcard(complete_wildcard)
2184 else:
2185 assert (self.DM_extension == method)
2186 assert self.baseTypeDefinition().isResolved()
2187 # 3.2.1
2188 base_wildcard = None
2189 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2190 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2191 # 3.2.2
2192 if base_wildcard is not None:
2193 if complete_wildcard is None:
2194 # 3.2.2.1.1
2195 self._setAttributeWildcard(base_wildcard)
2196 else:
2197 # 3.2.2.1.2
2198 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2199 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2200 base_wildcard.namespaceConstraint()]),
2201 annotation=complete_wildcard.annotation(),
2202 namespace_context=self._namespaceContext()))
2203 else:
2204 # 3.2.2.2
2205 self._setAttributeWildcard(complete_wildcard)
2206
2207 # @todo: Make sure we didn't miss any child nodes
2208
2209 # Remove local attributes we will never use again
2210 del self.__usesC1
2211 del self.__usesC1C2
2212 del self.__attributeGroups
2213 self.__ckw = None
2214
2215 # Only now that we've succeeded do we store the method, which
2216 # marks this component resolved.
2217
2218 self.__derivationMethod = method
2219 return self
2220
2222 # Do content type
2223 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2224 # Clauses 1, 2, and 3 might apply
2225 parent_content_type = self.__baseTypeDefinition.__contentType
2226 if ((type(parent_content_type) == tuple) \
2227 and (self.CT_SIMPLE == parent_content_type[0]) \
2228 and (self.DM_restriction == method)):
2229 # Clause 1
2230 assert self.__ctscRestrictionNode is not None
2231 std = self.__ctscClause2STD
2232 if std is None:
2233 std = parent_content_type[1]
2234 assert isinstance(std, SimpleTypeDefinition)
2235 if not std.isResolved():
2236 return None
2237 restriction_node = self.__ctscRestrictionNode
2238 self.__ctscClause2STD = None
2239 self.__ctscRestrictionNode = None
2240 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2241 if ((type(parent_content_type) == tuple) \
2242 and (self.CT_MIXED == parent_content_type[0]) \
2243 and parent_content_type[1].isEmptiable()):
2244 # Clause 2
2245 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2246 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2247 # Clause 3
2248 return parent_content_type
2249 # Clause 4
2250 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2251
2252 __ctscClause2STD = None
2253 __ctscRestrictionNode = None
2254 __effectiveMixed = None
2255 __effectiveContent = None
2256 __pendingDerivationMethod = None
2257 __isComplexContent = None
2258 __ctscRestrictionMode = None
2259 __contentStyle = None
2260
2261 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2262 # Do content type. Cache the keywords that need to be used
2263 # for newly created schema components.
2264 ckw = kw.copy()
2265 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2266
2267 # Definition 1: effective mixed
2268 mixed_attr = None
2269 if content_node is not None:
2270 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2271 if mixed_attr is None:
2272 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2273 if mixed_attr is not None:
2274 effective_mixed = datatypes.boolean(mixed_attr)
2275 else:
2276 effective_mixed = False
2277
2278 # Definition 2: effective content
2279 test_2_1_1 = True
2280 test_2_1_2 = False
2281 test_2_1_3 = False
2282 typedef_node = None
2283 for cn in definition_node_list:
2284 if Node.ELEMENT_NODE != cn.nodeType:
2285 continue
2286 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2287 # Should have found the content node earlier.
2288 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2289 if Particle.IsTypedefNode(cn):
2290 typedef_node = cn
2291 test_2_1_1 = False
2292 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2293 and (not domutils.HasNonAnnotationChild(cn)):
2294 test_2_1_2 = True
2295 if xsd.nodeIsNamed(cn, 'choice') \
2296 and (not domutils.HasNonAnnotationChild(cn)):
2297 mo_attr = domutils.NodeAttribute(cn, 'minOccurs')
2298 if ((mo_attr is not None) \
2299 and (0 == datatypes.integer(mo_attr))):
2300 test_2_1_3 = True
2301 satisfied_predicates = 0
2302 if test_2_1_1:
2303 satisfied_predicates += 1
2304 if test_2_1_2:
2305 satisfied_predicates += 1
2306 if test_2_1_3:
2307 satisfied_predicates += 1
2308 if 1 == satisfied_predicates:
2309 if effective_mixed:
2310 # Clause 2.1.4
2311 assert (typedef_node is None) or test_2_1_2
2312 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2313 effective_content = Particle(m, **ckw)
2314 else:
2315 # Clause 2.1.5
2316 effective_content = self.CT_EMPTY
2317 else:
2318 # Clause 2.2
2319 assert typedef_node is not None
2320 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2321
2322 # For issues related to soapenc:Array and the fact that PyXB
2323 # determines the content of types derived from it is empty, see
2324 # http://tech.groups.yahoo.com/group/soapbuilders/message/5879 and
2325 # lament the fact that the WSDL spec is not compatible with XSD. It
2326 # is *not* an error in PyXB.
2327
2328 self.__effectiveMixed = effective_mixed
2329 self.__effectiveContent = effective_content
2330 self.__ckw = ckw
2331
2333 ckw = self.__ckw
2334
2335 # Shared from clause 3.1.2
2336 if self.__effectiveMixed:
2337 ct = self.CT_MIXED
2338 else:
2339 ct = self.CT_ELEMENT_ONLY
2340 # Clause 3
2341 if self.DM_restriction == method:
2342 # Clause 3.1
2343 if self.CT_EMPTY == self.__effectiveContent:
2344 # Clause 3.1.1
2345 content_type = self.CT_EMPTY # ASSIGN CT_EMPTY
2346 else:
2347 # Clause 3.1.2(.2)
2348 content_type = ( ct, self.__effectiveContent ) # ASSIGN RESTRICTION
2349 assert 0 == len(self.__scopedElementDeclarations)
2350 # Reference the parent element declarations; normally this
2351 # would happen naturally as a consequence of appending this
2352 # type's content model to the parent's, but with restriction
2353 # there is no such re-use unless we do this.
2354 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2355 else:
2356 # Clause 3.2
2357 assert self.DM_extension == method
2358 assert self.__baseTypeDefinition.isResolved()
2359 parent_content_type = self.__baseTypeDefinition.contentType()
2360 if self.CT_EMPTY == self.__effectiveContent:
2361 content_type = parent_content_type # ASSIGN EXTENSION PARENT ONLY
2362 elif self.CT_EMPTY == parent_content_type:
2363 # Clause 3.2.2
2364 content_type = ( ct, self.__effectiveContent ) # ASSIGN EXTENSION LOCAL ONLY
2365 else:
2366 assert type(parent_content_type) == tuple
2367 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2368 content_type = ( ct, Particle(m, **ckw) ) # ASSIGN EXTENSION PARENT AND LOCAL
2369
2370 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2371 return content_type
2372
2374 """Indicate whether this complex type is fully defined.
2375
2376 All built-in type definitions are resolved upon creation.
2377 Schema-defined type definitionss are held unresolved until the
2378 schema has been completely read, so that references to later
2379 schema-defined types can be resolved. Resolution is performed
2380 after the entire schema has been scanned and type-definition
2381 instances created for all topLevel{Simple,Complex}Types.
2382
2383 If a built-in type definition is also defined in a schema
2384 (which it should be), the built-in definition is kept, with
2385 the schema-related information copied over from the matching
2386 schema-defined type definition. The former then replaces the
2387 latter in the list of type definitions to be resolved. See
2388 Schema._addNamedComponent.
2389 """
2390 # Only unresolved nodes have an unset derivationMethod
2391 return (self.__derivationMethod is not None)
2392
2393 # Back door to allow the ur-type to re-resolve itself. Only needed when
2394 # we're generating bindings for XMLSchema itself.
2398
2400 schema = kw.get('schema')
2401 assert schema is not None
2402 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2403 self.__final = schema.finalForNode(node, self._DM_Map)
2404
2405 attr_val = domutils.NodeAttribute(node, 'abstract')
2406 if attr_val is not None:
2407 self.__abstract = datatypes.boolean(attr_val)
2408
2409 # Assume we're in the short-hand case: the entire content is
2410 # implicitly wrapped in a complex restriction of the ur-type.
2411 definition_node_list = node.childNodes
2412 is_complex_content = True
2413 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2414 method = self.DM_restriction
2415
2416 # Determine whether above assumption is correct by looking for
2417 # element content and seeing if it's one of the wrapper
2418 # elements.
2419 first_elt = domutils.LocateFirstChildElement(node)
2420 content_node = None
2421 clause2_std = None
2422 ctsc_restriction_node = None
2423 if first_elt:
2424 have_content = False
2425 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2426 have_content = True
2427 is_complex_content = False
2428 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2429 have_content = True
2430 else:
2431 # Not one of the wrappers; use implicit wrapper around
2432 # the children
2433 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2434 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2435 if have_content:
2436 # Repeat the search to verify that only the one child is present.
2437 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2438 assert content_node == first_elt
2439
2440 # Identify the contained restriction or extension
2441 # element, and extract the base type.
2442 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2443 if xsd.nodeIsNamed(ions, 'restriction'):
2444 method = self.DM_restriction
2445 if not is_complex_content:
2446 # Clause 2 of complex type with simple content
2447 ctsc_restriction_node = ions
2448 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2449 if ions_st is not None:
2450 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2451 elif xsd.nodeIsNamed(ions, 'extension'):
2452 method = self.DM_extension
2453 else:
2454 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2455 self.__baseAttribute = domutils.NodeAttribute(ions, 'base')
2456 if self.__baseAttribute is None:
2457 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2458 self.__baseTypeDefinition = None
2459 # The content is defined by the restriction/extension element
2460 definition_node_list = ions.childNodes
2461 # deriviationMethod is assigned after resolution completes
2462 self.__pendingDerivationMethod = method
2463 self.__isComplexContent = is_complex_content
2464 self.__ctscRestrictionNode = ctsc_restriction_node
2465 self.__ctscClause2STD = clause2_std
2466
2467 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2468 self.__usesC1 = set()
2469 for cn in attributes:
2470 au = AttributeUse.CreateFromDOM(cn, **kw)
2471 self.__usesC1.add(au)
2472 self.__attributeGroupAttributes = attribute_group_attrs
2473 self.__anyAttribute = any_attribute
2474
2475 if self.__isComplexContent:
2476 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2477
2478 # Creation does not attempt to do resolution. Queue up the newly created
2479 # whatsis so we can resolve it after everything's been read in.
2480 self._annotationFromDOM(node)
2481
2482 if not self.isResolved():
2483 self._queueForResolution('creation')
2484
2485 return self
2486
2487 # Resolution of a CTD can be delayed for the following reasons:
2488 #
2489 # * It extends or restricts a base type that has not been resolved
2490 # [_resolve]
2491 #
2492 # * It refers to an attribute or attribute group that has not been
2493 # resolved [__completeProcessing]
2494 #
2495 # * It includes an attribute that matches in NCName and namespace
2496 # an unresolved attribute from the base type
2497 # [__completeProcessing]
2498 #
2499 # * The content model includes a particle which cannot be resolved
2500 # (so has not contributed any local element declarations).
2501 # res:CTD
2503 if self.isResolved():
2504 return self
2505
2506 # @todo: implement prohibitedSubstitutions, final, annotations
2507
2508 # See whether we've resolved through to the base type
2509 if self.__baseTypeDefinition is None:
2510 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
2511 base_type = base_en.typeDefinition()
2512 if base_type is None:
2513 raise pyxb.SchemaValidationError('Cannot locate %s: need import?' % (base_en,))
2514 if not base_type.isResolved():
2515 # Have to delay resolution until the type this
2516 # depends on is available.
2517 self._queueForResolution('unresolved base type %s' % (base_en,), depends_on=base_type)
2518 return self
2519 self.__baseTypeDefinition = base_type
2520
2521 # Only build the content once. This will not complete if the content
2522 # is a restriction of an unresolved simple type; otherwise, it only
2523 # depends on the base type which we know is good.
2524 if self.__contentType is None:
2525 if self.__isComplexContent:
2526 content_type = self.__complexContent(self.__pendingDerivationMethod)
2527 self.__contentStyle = 'complex'
2528 else:
2529 # The definition node list is not relevant to simple content
2530 content_type = self.__simpleContent(self.__pendingDerivationMethod)
2531 if content_type is None:
2532 self._queueForResolution('restriction of unresolved simple type')
2533 return self
2534 self.__contentStyle = 'simple'
2535 assert content_type is not None
2536 self.__contentType = content_type
2537
2538 # Last chance for failure is if we haven't been able to
2539 # extract all the element declarations that might appear in
2540 # this complex type. That technically wouldn't stop this from
2541 # being resolved, but it does prevent us from using it as a
2542 # context.
2543 if isinstance(self.__contentType, tuple) and isinstance(self.__contentType[1], Particle):
2544 prt = self.__contentType[1]
2545 if not prt.isAdaptable(self):
2546 self._queueForResolution('content particle %s is not deep-resolved' % (prt,))
2547 return self
2548 self.__contentType = (self.__contentType[0], prt._adaptForScope(self, self))
2549
2550 return self.__completeProcessing(self.__pendingDerivationMethod, self.__contentStyle)
2551
2555
2557 if self.isAnonymous():
2558 return 'CTD{Anonymous}[%x]' % (id(self),)
2559 return 'CTD[%s]' % (self.expandedName(),)
2560
2562 """Subclass ensures there is only one ur-type."""
2566
2568 # The ur type is always resolved, except when it gets unresolved
2569 # through being updated from an instance read from the schema.
2570 return self._setDerivationMethod(self.DM_restriction)
2571
2572
2573 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2574 """An XMLSchema U{Attribute Group Definition<http://www.w3.org/TR/xmlschema-1/#cAttribute_Group_Definitions>} component."""
2575 __PrivateTransient = set()
2576
2577 # A frozenset of AttributeUse instances
2578 __attributeUses = None
2579
2582 #assert 'scope' in kw
2583 #assert self._scopeIsIndeterminate()
2584
2586 return 'AGD[%s]' % (self.expandedName(),)
2587
2588 @classmethod
2590 """Create an attribute declaration component for a specified namespace."""
2591 kw = { 'name' : name,
2592 'schema' : schema,
2593 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
2594 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
2595 bi = cls(**kw)
2596 bi.__attributeUses = frozenset(attribute_uses)
2597 bi.__isResolved = True
2598 return bi
2599
2600 __anyAttribute = None
2601 __attributeGroupAttributes = None
2602 __refAttribute = None
2603 __PrivateTransient.update(['anyAttribute', 'attributeGroupAttributes'])
2604
2605
2606 # CFD:AGD CFD:AttributeGroupDefinition
2607 @classmethod
2609 """Create an attribute group definition from the given DOM node.
2610
2611 """
2612
2613 assert xsd.nodeIsNamed(node, 'attributeGroup')
2614 name = domutils.NodeAttribute(node, 'name')
2615
2616 # Attribute group definitions can only appear at the top level of the
2617 # schema, and any definitions in them are scope indeterminate until
2618 # they're referenced in a complex type.
2619 kw.update({ 'scope' : _ScopedDeclaration_mixin.XSCOPE_indeterminate })
2620 rv = cls(name=name, node=node, **kw)
2621
2622 rv._annotationFromDOM(node)
2623
2624 # Attribute group definitions must not be references
2625 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
2626 if rv.__refAttribute is not None:
2627 raise pyxb.SchemaValidationError('Attribute reference at top level')
2628
2629 kw.pop('node', None)
2630 kw['owner'] = rv
2631
2632 (attributes, attribute_group_attrs, any_attribute) = rv._attributeRelevantChildren(node.childNodes)
2633 rv.__attributeUses = set()
2634 for cn in attributes:
2635 rv.__attributeUses.add(AttributeUse.CreateFromDOM(cn, **kw))
2636 rv.__attributeGroupAttributes = attribute_group_attrs
2637 rv.__anyAttribute = any_attribute
2638
2639 # Unconditionally queue for resolution, to avoid repeating the
2640 # wildcard code.
2641 rv._queueForResolution('creation')
2642
2643 return rv
2644
2645 # Indicates whether we have resolved any references
2646 __isResolved = False
2648 return self.__isResolved
2649
2651 if self.__isResolved:
2652 return self
2653
2654 uses = self.__attributeUses
2655 attribute_groups = []
2656 for ag_attr in self.__attributeGroupAttributes:
2657 ag_en = self._namespaceContext().interpretQName(ag_attr)
2658 agd = ag_en.attributeGroupDefinition()
2659 if agd is None:
2660 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2661 attribute_groups.append(agd)
2662 uses = uses.union(agd.attributeUses())
2663
2664 self.__attributeUses = frozenset(uses)
2665
2666 # "Complete wildcard" per CTD
2667 local_wildcard = None
2668 if self.__anyAttribute is not None:
2669 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2670 self._setAttributeWildcard(_AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), attribute_groups, local_wildcard))
2671
2672 self.__isResolved = True
2673 return self
2674
2675 # bR:AGD
2677 """Attribute group declarations require their uses, but only if lax."""
2678 if not include_lax:
2679 return frozenset()
2680 return frozenset(self.attributeUses())
2681
2683 return self.__attributeUses
2684
2686 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2687 # Reference to a _ModelGroup
2688 __modelGroup = None
2689
2693
2694 # CFD:MGD CFD:ModelGroupDefinition
2695 @classmethod
2697 """Create a Model Group Definition from a DOM element node.
2698
2699 wxs is a Schema instance within which the model group is being
2700 defined.
2701
2702 node is a DOM element. The name must be 'group', and the node
2703 must be in the XMLSchema namespace. The node must have a
2704 'name' attribute, and must not have a 'ref' attribute.
2705 """
2706 assert xsd.nodeIsNamed(node, 'group')
2707
2708 assert domutils.NodeAttribute(node, 'ref') is None
2709
2710 name = domutils.NodeAttribute(node, 'name')
2711 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2712 rv = cls(name=name, node=node, **kw)
2713 rv._annotationFromDOM(node)
2714
2715 kw.pop('node', None)
2716 kw['owner'] = rv
2717
2718 for cn in node.childNodes:
2719 if Node.ELEMENT_NODE != cn.nodeType:
2720 continue
2721 if ModelGroup.IsGroupMemberNode(cn):
2722 assert not rv.__modelGroup
2723 # Model group definitions always occur at the top level of the
2724 # schema, so the elements declared in them are not bound to a
2725 # scope until they are referenced in a complex type.
2726 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2727 assert rv.__modelGroup is not None
2728 return rv
2729
2730 # bR:MGD
2732 """Model group definitions depend on the contained model group."""
2733 if not include_lax:
2734 return frozenset()
2735 return frozenset([self.__modelGroup])
2736
2739
2742 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2743 C_INVALID = 0
2744 C_ALL = 0x01
2745 C_CHOICE = 0x02
2746 C_SEQUENCE = 0x03
2747
2748 # One of the C_* values above. Set at construction time from the
2749 # keyword parameter "compositor".
2750 __compositor = C_INVALID
2752 return self.__compositor
2753
2754 @classmethod
2756 """Map a compositor value to a string."""
2757 if cls.C_ALL == compositor:
2758 return 'all'
2759 if cls.C_CHOICE == compositor:
2760 return 'choice'
2761 if cls.C_SEQUENCE == compositor:
2762 return 'sequence'
2763 return 'invalid'
2764
2766 """Return a string representing the compositor value."""
2767 return self.CompositorToString(self.__compositor)
2768
2769 # A list of Particle instances. Set at construction time from
2770 # the keyword parameter "particles".
2771 __particles = None
2773 return self.__particles
2774
2776 """A model group has an unresolvable particle if any of its
2777 particles is unresolvable. Duh."""
2778 for p in self.particles():
2779 if not p.isAdaptable(ctd):
2780 return False
2781 return True
2782
2784 """Return the minimum and maximum of the number of elements that can
2785 appear in a sequence matched by this particle.
2786
2787 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2788 """
2789 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2790 sum_minoccurs = 0
2791 sum_maxoccurs = 0
2792 for prt in self.__particles:
2793 (prt_min, prt_max) = prt.effectiveTotalRange()
2794 sum_minoccurs += prt_min
2795 if sum_maxoccurs is not None:
2796 if prt_max is None:
2797 sum_maxoccurs = None
2798 else:
2799 sum_maxoccurs += prt_max
2800 prod_maxoccurs = particle.maxOccurs()
2801 if prod_maxoccurs is not None:
2802 if sum_maxoccurs is None:
2803 prod_maxoccurs = None
2804 else:
2805 prod_maxoccurs *= sum_maxoccurs
2806 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2807 assert self.__compositor == self.C_CHOICE
2808 if 0 == len(self.__particles):
2809 min_minoccurs = 0
2810 max_maxoccurs = 0
2811 else:
2812 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2813 for prt in self.__particles[1:]:
2814 (prt_min, prt_max) = prt.effectiveTotalRange()
2815 if prt_min < min_minoccurs:
2816 min_minoccurs = prt_min
2817 if prt_max is None:
2818 max_maxoccurs = None
2819 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2820 max_maxoccurs = prt_max
2821 min_minoccurs *= particle.minOccurs()
2822 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2823 max_maxoccurs *= particle.maxOccurs()
2824 return (min_minoccurs, max_maxoccurs)
2825
2826 # The ModelGroupDefinition that names this ModelGroup, or None if
2827 # the ModelGroup is anonymous. This is set at construction time
2828 # from the keyword parameter "model_group_definition".
2829 __modelGroupDefinition = None
2831 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2832 return self.__modelGroupDefinition
2833
2835 """Create a new model group.
2836
2837 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2838
2839 particles must be a list of zero or more Particle instances.
2840
2841 scope is the _ScopeDeclaration_mixin context into which new
2842 declarations are recorded. It can be SCOPE_global, a complex
2843 type definition, or None if this is (or is within) a named
2844 model group.
2845
2846 model_group_definition is an instance of ModelGroupDefinition
2847 if this is a named model group. It defaults to None
2848 indicating a local group.
2849 """
2850
2851 super(ModelGroup, self).__init__(*args, **kw)
2852 assert 'scope' in kw
2853 self.__compositor = compositor
2854 self.__particles = particles
2855 self.__modelGroupDefinition = kw.get('model_group_definition')
2856
2861
2863 """Return True if the model includes a wildcard amongst its particles."""
2864 for p in self.particles():
2865 if p.hasWildcardElement():
2866 return True
2867 return False
2868
2869 # bR:MG
2874
2875 # CFD:MG CFD:ModelGroup
2876 @classmethod
2878 """Create a model group from the given DOM node.
2879
2880 wxs is a Schema instance within which the model group is being
2881 defined.
2882
2883 node is a DOM element. The name must be one of ( 'all',
2884 'choice', 'sequence' ), and the node must be in the XMLSchema
2885 namespace.
2886
2887 scope is the _ScopeDeclaration_mxin context that is assigned
2888 to declarations that appear within the model group. It can be
2889 None, indicating no scope defined, or a complex type
2890 definition.
2891 """
2892
2893 scope = kw['scope']
2894 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2895
2896 if xsd.nodeIsNamed(node, 'all'):
2897 compositor = cls.C_ALL
2898 elif xsd.nodeIsNamed(node, 'choice'):
2899 compositor = cls.C_CHOICE
2900 elif xsd.nodeIsNamed(node, 'sequence'):
2901 compositor = cls.C_SEQUENCE
2902 else:
2903 raise pyxb.IncompleteImplementationError('ModelGroup: Got unexpected %s' % (node.nodeName,))
2904 particles = []
2905 # Remove the owner from particle constructor arguments: we need to set it later
2906 kw.pop('owner', None)
2907 for cn in node.childNodes:
2908 if Node.ELEMENT_NODE != cn.nodeType:
2909 continue
2910 if Particle.IsParticleNode(cn):
2911 # NB: Ancestor of particle is set in the ModelGroup constructor
2912 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2913 elif not xsd.nodeIsNamed(cn, 'annotation'):
2914 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2915 rv = cls(compositor, particles, node=node, **kw)
2916 for p in particles:
2917 p._setOwner(rv)
2918 rv._annotationFromDOM(node)
2919 return rv
2920
2921 @classmethod
2923 return xsd.nodeIsNamed(node, 'all', 'choice', 'sequence')
2924
2926 """Return a list of all ElementDeclarations that are at the
2927 top level of this model group, in the order in which they can
2928 occur."""
2929 element_decls = []
2930 model_groups = [ self ]
2931 while model_groups:
2932 mg = model_groups.pop(0)
2933 for p in mg.particles():
2934 if isinstance(p.term(), ModelGroup):
2935 model_groups.append(p.term())
2936 elif isinstance(p.term(), ElementDeclaration):
2937 element_decls.extend(p.elementDeclarations())
2938 else:
2939 assert p.term() is not None
2940 return element_decls
2941
2942 # aFS:MG
2944 rv = self
2945 assert isinstance(ctd, ComplexTypeDefinition)
2946 maybe_rv = self._clone(owner, ctd._objectOrigin())
2947 scoped_particles = [ _p._adaptForScope(maybe_rv, ctd) for _p in self.particles() ]
2948 do_clone = (self._scope() != ctd) or (self.particles() != scoped_particles)
2949 if do_clone:
2950 rv = maybe_rv
2951 rv.__particles = scoped_particles
2952 return rv
2953
2955 comp = None
2956 if self.C_ALL == self.compositor():
2957 comp = 'ALL'
2958 elif self.C_CHOICE == self.compositor():
2959 comp = 'CHOICE'
2960 elif self.C_SEQUENCE == self.compositor():
2961 comp = 'SEQUENCE'
2962 return '%s:(%s)' % (comp, ",".join( [ str(_p) for _p in self.particles() ] ) )
2963
2965 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2966
2967 # The minimum number of times the term may appear.
2968 __minOccurs = 1
2970 """The minimum number of times the term may appear.
2971
2972 Defaults to 1."""
2973 return self.__minOccurs
2974
2975 # Upper limit on number of times the term may appear.
2976 __maxOccurs = 1
2978 """Upper limit on number of times the term may appear.
2979
2980 If None, the term may appear any number of times; otherwise,
2981 this is an integral value indicating the maximum number of times
2982 the term may appear. The default value is 1; the value, unless
2983 None, must always be at least minOccurs().
2984 """
2985 return self.__maxOccurs
2986
2987 # A reference to a ModelGroup, WildCard, or ElementDeclaration
2988 __term = None
2992 __pendingTerm = None
2993
2994 __refAttribute = None
2995 __resolvableType = None
2996
2998 assert self.__term is not None
2999 if isinstance(self.__term, ModelGroup):
3000 return self.__term.elementDeclarations()
3001 if isinstance(self.__term, ElementDeclaration):
3002 return [ self.__term ]
3003 if isinstance(self.__term, Wildcard):
3004 return [ ]
3005 raise pyxb.LogicError('Unexpected term type %s' % (self.__term,))
3006
3008 """Return the plurality data for this component.
3009
3010 The plurality data for a particle is the plurality data for
3011 its term, with the counts scaled by the effect of
3012 maxOccurs."""
3013 return _PluralityData(self)
3014
3016 """Extend the concept of effective total range to all particles.
3017
3018 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
3019 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
3020 """
3021 if isinstance(self.__term, ModelGroup):
3022 return self.__term.effectiveTotalRange(self)
3023 return (self.minOccurs(), self.maxOccurs())
3024
3026 """Return C{True} iff this particle can legitimately match an empty
3027 sequence (no content).
3028
3029 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
3030 """
3031 return 0 == self.effectiveTotalRange()[0]
3032
3034 """Return True iff this particle has a wildcard in its term.
3035
3036 Note that the wildcard may be in a nested model group."""
3037 return self.term().hasWildcardElement()
3038
3040 """Create a particle from the given DOM node.
3041
3042 term is a XML Schema Component: one of ModelGroup,
3043 ElementDeclaration, and Wildcard.
3044
3045 The following keyword arguments are processed:
3046
3047 min_occurs is a non-negative integer value with default 1,
3048 denoting the minimum number of terms required by the content
3049 model.
3050
3051 max_occurs is a positive integer value with default 1, or None
3052 indicating unbounded, denoting the maximum number of terms
3053 allowed by the content model.
3054
3055 scope is the _ScopeDeclaration_mxin context that is assigned
3056 to declarations that appear within the particle. It can be
3057 None, indicating no scope defined, or a complex type
3058 definition.
3059 """
3060
3061 super(Particle, self).__init__(*args, **kw)
3062
3063 min_occurs = kw.get('min_occurs', 1)
3064 max_occurs = kw.get('max_occurs', 1)
3065
3066 assert 'scope' in kw
3067 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
3068
3069 if term is not None:
3070 self.__term = term
3071
3072 assert isinstance(min_occurs, (types.IntType, types.LongType))
3073 self.__minOccurs = min_occurs
3074 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
3075 self.__maxOccurs = max_occurs
3076 if self.__maxOccurs is not None:
3077 if self.__minOccurs > self.__maxOccurs:
3078 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3079
3080 # res:Particle
3082 if self.isResolved():
3083 return self
3084
3085 # @RESOLUTION@
3086 if ModelGroup == self.__resolvableType:
3087 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3088 group_decl = ref_en.modelGroupDefinition()
3089 if group_decl is None:
3090 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
3091
3092 self.__pendingTerm = group_decl.modelGroup()
3093 assert self.__pendingTerm is not None
3094 elif ElementDeclaration == self.__resolvableType:
3095 # 3.9.2 says use 3.3.2, which is Element. The element inside a
3096 # particle is a localElement, so we either get the one it refers
3097 # to (which is top-level), or create a local one here.
3098 if self.__refAttribute is not None:
3099 assert self.__pendingTerm is None
3100 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3101 self.__pendingTerm = ref_en.elementDeclaration()
3102 if self.__pendingTerm is None:
3103 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3104 assert self.__pendingTerm is not None
3105
3106 # Whether this is a local declaration or one pulled in from the
3107 # global type definition symbol space, its name is now reserved in
3108 # this type.
3109 assert self.__pendingTerm is not None
3110 else:
3111 assert False
3112
3113 self.__term = self.__pendingTerm
3114 assert self.__term is not None
3115 return self
3116
3118 return self.__term is not None
3119
3120 # CFD:Particle
3121 @classmethod
3123 """Create a particle from the given DOM node.
3124
3125 wxs is a Schema instance within which the model group is being
3126 defined.
3127
3128 node is a DOM element. The name must be one of ( 'group',
3129 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3130 must be in the XMLSchema namespace.
3131
3132 scope is the _ScopeDeclaration_mxin context that is assigned
3133 to declarations that appear within the model group. It can be
3134 None, indicating no scope defined, or a complex type
3135 definition.
3136 """
3137 scope = kw['scope']
3138 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3139
3140 kw.update({ 'min_occurs' : 1
3141 , 'max_occurs' : 1
3142 , 'node' : node })
3143
3144 if not Particle.IsParticleNode(node):
3145 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3146 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3147 if attr_val is not None:
3148 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3149 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3150 if attr_val is not None:
3151 if 'unbounded' == attr_val:
3152 kw['max_occurs'] = None
3153 else:
3154 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3155
3156 rv = cls(None, **kw)
3157
3158 kw.pop('node', None)
3159 kw['owner'] = rv
3160
3161 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
3162 rv.__pendingTerm = None
3163 rv.__resolvableType = None
3164 if xsd.nodeIsNamed(node, 'group'):
3165 # 3.9.2 says use 3.8.2, which is ModelGroup. The group
3166 # inside a particle is a groupRef. If there is no group
3167 # with that name, this throws an exception as expected.
3168 if rv.__refAttribute is None:
3169 raise pyxb.SchemaValidationError('group particle without reference')
3170 rv.__resolvableType = ModelGroup
3171 elif xsd.nodeIsNamed(node, 'element'):
3172 if rv.__refAttribute is None:
3173 schema = kw.get('schema')
3174 assert schema is not None
3175 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3176 incoming_tns = kw.get('target_namespace')
3177 if incoming_tns is not None:
3178 assert incoming_tns == target_namespace
3179 else:
3180 kw['target_namespace'] = target_namespace
3181 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3182 else:
3183 # NOTE: 3.3.3 clause 2.2 specifies that if ref is used, all
3184 # the other configuration attributes like nillable and default
3185 # must be absent. We don't even bother looking for them.
3186 rv.__resolvableType = ElementDeclaration
3187 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3188 elif xsd.nodeIsNamed(node, 'any'):
3189 # 3.9.2 says use 3.10.2, which is Wildcard.
3190 rv.__term = Wildcard.CreateFromDOM(node=node)
3191 elif ModelGroup.IsGroupMemberNode(node):
3192 # Choice, sequence, and all inside a particle are explicit
3193 # groups (or a restriction of explicit group, in the case
3194 # of all)
3195 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3196 else:
3197 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3198
3199 if not rv.isResolved():
3200 rv._queueForResolution('creation')
3201 return rv
3202
3203 # bR:PRT
3208
3209 # aFS:PRT
3211 rv = self
3212 assert isinstance(ctd, ComplexTypeDefinition)
3213 maybe_rv = self._clone(owner, ctd._objectOrigin())
3214 term = rv.__term._adaptForScope(maybe_rv, ctd)
3215 do_clone = (self._scope() != ctd) or (rv.__term != term)
3216 if do_clone:
3217 rv = maybe_rv
3218 rv.__term = term
3219 return rv
3220
3222 """A particle has an unresolvable particle if it cannot be
3223 resolved, or if it has resolved to a term which is a model
3224 group that has an unresolvable particle.
3225 """
3226 if not self.isResolved():
3227 return False
3228 return self.term().isAdaptable(ctd)
3229
3230 @classmethod
3232 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3233
3234 @classmethod
3236 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3237
3241
3245 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3246
3247 NC_any = '##any' #<<< The namespace constraint "##any"
3248 NC_not = '##other' #<<< A flag indicating constraint "##other"
3249 NC_targetNamespace = '##targetNamespace'
3250 NC_local = '##local'
3251
3252 __namespaceConstraint = None
3254 """A constraint on the namespace for the wildcard.
3255
3256 Valid values are:
3257 - L{Wildcard.NC_any}
3258 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3259 - set(of_namespaces)
3260
3261 Note that namespace are represented by
3262 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3263 actually define a namespace. Absence of a namespace is represented by
3264 C{None}, both in the "not" pair and in the set.
3265 """
3266 return self.__namespaceConstraint
3267
3268 @classmethod
3270 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3271 assert 0 < len(constraints)
3272 o1 = constraints.pop(0)
3273 while 0 < len(constraints):
3274 o2 = constraints.pop(0)
3275 # 1
3276 if (o1 == o2):
3277 continue
3278 # 2
3279 if (cls.NC_any == o1) or (cls.NC_any == o2):
3280 o1 = cls.NC_any
3281 continue
3282 # 3
3283 if isinstance(o1, set) and isinstance(o2, set):
3284 o1 = o1.union(o2)
3285 continue
3286 # 4
3287 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3288 o1 = ( cls.NC_not, None )
3289 continue
3290 # At this point, one must be a negated namespace and the
3291 # other a set. Identify them.
3292 c_tuple = None
3293 c_set = None
3294 if isinstance(o1, tuple):
3295 assert isinstance(o2, set)
3296 c_tuple = o1
3297 c_set = o2
3298 else:
3299 assert isinstance(o1, set)
3300 assert isinstance(o2, tuple)
3301 c_tuple = o2
3302 c_set = o1
3303 negated_ns = c_tuple[1]
3304 if negated_ns is not None:
3305 # 5.1
3306 if (negated_ns in c_set) and (None in c_set):
3307 o1 = cls.NC_any
3308 continue
3309 # 5.2
3310 if negated_ns in c_set:
3311 o1 = ( cls.NC_not, None )
3312 continue
3313 # 5.3
3314 if None in c_set:
3315 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3316 o1 = c_tuple
3317 continue
3318 # 6
3319 if None in c_set:
3320 o1 = cls.NC_any
3321 else:
3322 o1 = ( cls.NC_not, None )
3323 return o1
3324
3325 @classmethod
3327 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3328 assert 0 < len(constraints)
3329 o1 = constraints.pop(0)
3330 while 0 < len(constraints):
3331 o2 = constraints.pop(0)
3332 # 1
3333 if (o1 == o2):
3334 continue
3335 # 2
3336 if (cls.NC_any == o1) or (cls.NC_any == o2):
3337 if cls.NC_any == o1:
3338 o1 = o2
3339 continue
3340 # 4
3341 if isinstance(o1, set) and isinstance(o2, set):
3342 o1 = o1.intersection(o2)
3343 continue
3344 if isinstance(o1, tuple) and isinstance(o2, tuple):
3345 ns1 = o1[1]
3346 ns2 = o2[1]
3347 # 5
3348 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3349 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3350 # 6
3351 assert (ns1 is None) or (ns2 is None)
3352 if ns1 is None:
3353 assert ns2 is not None
3354 o1 = ( cls.NC_not, ns2 )
3355 else:
3356 assert ns1 is not None
3357 o1 = ( cls.NC_not, ns1 )
3358 continue
3359 # 3
3360 # At this point, one must be a negated namespace and the
3361 # other a set. Identify them.
3362 c_tuple = None
3363 c_set = None
3364 if isinstance(o1, tuple):
3365 assert isinstance(o2, set)
3366 c_tuple = o1
3367 c_set = o2
3368 else:
3369 assert isinstance(o1, set)
3370 assert isinstance(o2, tuple)
3371 c_tuple = o2
3372 c_set = o1
3373 negated_ns = c_tuple[1]
3374 if negated_ns in c_set:
3375 c_set.remove(negated_ns)
3376 if None in c_set:
3377 c_set.remove(None)
3378 o1 = c_set
3379 return o1
3380
3381 PC_skip = 'skip' #<<< No constraint is applied
3382 PC_lax = 'lax' #<<< Validate against available uniquely determined declaration
3383 PC_strict = 'strict' #<<< Validate against declaration or xsi:type which must be available
3384
3385 # One of PC_*
3386 __processContents = None
3388 return self.__processContents
3389
3394
3398
3400 assert 0 == len(args)
3401 super(Wildcard, self).__init__(*args, **kw)
3402 self.__namespaceConstraint = kw['namespace_constraint']
3403 self.__processContents = kw['process_contents']
3404
3407
3408 # aFS:WC
3412
3413 # CFD:Wildcard
3414 @classmethod
3416 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3417 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3418 nc = domutils.NodeAttribute(node, 'namespace')
3419 if nc is None:
3420 namespace_constraint = cls.NC_any
3421 else:
3422 if cls.NC_any == nc:
3423 namespace_constraint = cls.NC_any
3424 elif cls.NC_not == nc:
3425 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3426 else:
3427 ncs = set()
3428 for ns_uri in nc.split():
3429 if cls.NC_local == ns_uri:
3430 ncs.add(None)
3431 elif cls.NC_targetNamespace == ns_uri:
3432 ncs.add(namespace_context.targetNamespace())
3433 else:
3434 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3435 namespace_constraint = frozenset(ncs)
3436
3437 pc = domutils.NodeAttribute(node, 'processContents')
3438 if pc is None:
3439 process_contents = cls.PC_strict
3440 else:
3441 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3442 process_contents = pc
3443 else:
3444 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3445
3446 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3447 rv._annotationFromDOM(node)
3448 return rv
3449
3450 # 3.11.1
3451 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3452 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3453
3454 ICC_KEY = 0x01
3455 ICC_KEYREF = 0x02
3456 ICC_UNIQUE = 0x04
3457
3458 __identityConstraintCategory = None
3460 return self.__identityConstraintCategory
3461
3462 __selector = None
3464 return self.__selector
3465
3466 __fields = None
3468 return self.__fields
3469
3470 __referencedKey = None
3471 __referAttribute = None
3472 __icc = None
3473
3474 __annotations = None
3476 return self.__annotations
3477
3478 # CFD:ICD CFD:IdentityConstraintDefinition
3479 @classmethod
3481 name = domutils.NodeAttribute(node, 'name')
3482 scope = kw['scope']
3483 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3484 rv = cls(name=name, node=node, **kw)
3485
3486 kw.pop('node', None)
3487 kw['owner'] = rv
3488
3489 #self._annotationFromDOM(node);
3490 rv.__isResolved = True
3491 icc = None
3492 if xsd.nodeIsNamed(node, 'key'):
3493 icc = rv.ICC_KEY
3494 elif xsd.nodeIsNamed(node, 'keyref'):
3495 icc = rv.ICC_KEYREF
3496 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3497 if rv.__referAttribute is None:
3498 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3499 rv.__isResolved = False
3500 elif xsd.nodeIsNamed(node, 'unique'):
3501 icc = rv.ICC_UNIQUE
3502 else:
3503 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3504 rv.__icc = icc
3505
3506 cn = domutils.LocateUniqueChild(node, 'selector')
3507 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3508 if rv.__selector is None:
3509 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3510
3511 rv.__fields = []
3512 for cn in domutils.LocateMatchingChildren(node, 'field'):
3513 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3514 if xp_attr is None:
3515 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3516 rv.__fields.append(xp_attr)
3517
3518 rv._annotationFromDOM(node)
3519 rv.__annotations = []
3520 if rv.annotation() is not None:
3521 rv.__annotations.append(rv)
3522
3523 for cn in node.childNodes:
3524 if (Node.ELEMENT_NODE != cn.nodeType):
3525 continue
3526 an = None
3527 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3528 an = domutils.LocateUniqueChild(cn, 'annotation')
3529 elif xsd.nodeIsNamed(cn, 'annotation'):
3530 an = cn
3531 if an is not None:
3532 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3533
3534 rv.__identityConstraintCategory = icc
3535 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3536 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3537
3538 if not rv.isResolved():
3539 rv._queueForResolution('creation')
3540 return rv
3541
3542 __isResolved = False
3544 return self.__isResolved
3545
3546 # res:ICD res:IdentityConstraintDefinition
3548 if self.isResolved():
3549 return self
3550
3551 icc = self.__icc
3552 if self.ICC_KEYREF == icc:
3553 refer_en = self._namespaceContext().interpretQName(self.__referAttribute)
3554 refer = refer_en.identityConstraintDefinition()
3555 if refer is None:
3556 self._queueForResolution('Identity constraint definition %s cannot be found' % (refer_en,), depends_on=refer)
3557 return self
3558 self.__referencedKey = refer
3559 self.__isResolved = True
3560 return self
3561
3562 # bR:ICD
3564 """Constraint definitions that are by reference require the referenced constraint."""
3565 rv = set()
3566 if include_lax and (self.__referencedKey is not None):
3567 rv.add(self.__referencedKey)
3568 return frozenset(rv)
3569
3570
3571
3572 # 3.12.1
3573 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3574 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3575 __systemIdentifier = None
3577 return self.__systemIdentifier
3578
3579 __publicIdentifier = None
3581 return self.__publicIdentifier
3582
3583 # CFD:ND CFD:NotationDeclaration
3584 @classmethod
3586 name = domutils.NodeAttribute(node, 'name')
3587 rv = cls(name=name, node=node, **kw)
3588
3589 rv.__systemIdentifier = domutils.NodeAttribute(node, 'system')
3590 rv.__publicIdentifier = domutils.NodeAttribute(node, 'public')
3591
3592 rv._annotationFromDOM(node)
3593 return rv
3594
3597 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3598
3599 __applicationInformation = None
3601 return self.__applicationInformation
3602
3603 __userInformation = None
3605 return self.__userInformation
3606
3607 # Define so superclasses can take keywords
3609 application_information = kw.pop('application_information', None)
3610 user_information = kw.pop('user_information', None)
3611 super(Annotation, self).__init__(**kw)
3612 if (user_information is not None) and (not isinstance(user_information, list)):
3613 user_information = [ unicode(user_information) ]
3614 if (application_information is not None) and (not isinstance(application_information, list)):
3615 application_information = [ unicode(application_information) ]
3616 self.__userInformation = user_information
3617 self.__applicationInformation = application_information
3618
3619 # @todo: what the hell is this? From 3.13.2, I think it's a place
3620 # to stuff attributes from the annotation element, which makes
3621 # sense, as well as from the annotation's parent element, which
3622 # doesn't. Apparently it's for attributes that don't belong to
3623 # the XMLSchema namespace; so maybe we're not supposed to add
3624 # those to the other components. Note that these are attribute
3625 # information items, not attribute uses.
3626 __attributes = None
3627
3628 # CFD:Annotation
3629 @classmethod
3631 rv = cls(node=node, **kw)
3632
3633 # @todo:: Scan for attributes in the node itself that do not
3634 # belong to the XMLSchema namespace.
3635
3636 # Node should be an XMLSchema annotation node
3637 assert xsd.nodeIsNamed(node, 'annotation')
3638 app_info = []
3639 user_info = []
3640 for cn in node.childNodes:
3641 if xsd.nodeIsNamed(cn, 'appinfo'):
3642 app_info.append(cn)
3643 elif xsd.nodeIsNamed(cn, 'documentation'):
3644 user_info.append(cn)
3645 else:
3646 pass
3647 if 0 < len(app_info):
3648 rv.__applicationInformation = app_info
3649 if 0 < len(user_info):
3650 rv.__userInformation = user_info
3651
3652 return rv
3653
3654 __RemoveMultiQuote_re = re.compile('""+')
3656 """Return the text in a form suitable for embedding in a
3657 triple-double-quoted docstring.
3658
3659 Any sequence of two or more double quotes is replaced by a sequence of
3660 single quotes that is the same length. Following this, spaces are
3661 added at the start and the end as necessary to ensure a double quote
3662 does not appear in those positions."""
3663 rv = self.text()
3664 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3665 if rv.startswith('"'):
3666 rv = ' ' + rv
3667 if rv.endswith('"'):
3668 rv = rv + ' '
3669 return rv
3670
3672 if self.__userInformation is None:
3673 return ''
3674 text = []
3675 # Values in userInformation are DOM "documentation" elements.
3676 # We want their combined content.
3677 for dn in self.__userInformation:
3678 for cn in dn.childNodes:
3679 if Node.TEXT_NODE == cn.nodeType:
3680 text.append(cn.data)
3681 return ''.join(text)
3682
3684 """Return the catenation of all user information elements in the
3685 annotation as a single unicode string. Returns the empty string if
3686 there are no user information elements."""
3687 return self.text()
3688
3689 # Section 3.14.
3690 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3691 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3692
3693 # Reference to the SimpleTypeDefinition on which this is based.
3694 # The value must be non-None except for the simple ur-type
3695 # definition.
3696 __baseTypeDefinition = None
3698 return self.__baseTypeDefinition
3699
3700 __memberTypes = None
3701 __itemTypeAttribute = None
3702 __baseAttribute = None
3703 __memberTypesAttribute = None
3704 __localFacets = None
3705
3706 # A map from a subclass of facets.Facet to an instance of that class.
3707 # Presence of a facet class as a key in this map is the indicator that the
3708 # type definition and its subtypes are permitted to use the corresponding
3709 # facet. All facets in force for this type are present in the map,
3710 # including those constraints inherited parent types.
3711 __facets = None
3713 assert (self.__facets is None) or (type(self.__facets) == types.DictType)
3714 return self.__facets
3715
3716 # The facets.FundamentalFacet instances that describe this type
3717 __fundamentalFacets = None
3719 """A frozenset of instances of facets.FundamentallFacet."""
3720 return self.__fundamentalFacets
3721
3722 STD_empty = 0 #<<< Marker indicating an empty set of STD forms
3723 STD_extension = 0x01 #<<< Representation for extension in a set of STD forms
3724 STD_list = 0x02 #<<< Representation for list in a set of STD forms
3725 STD_restriction = 0x04 #<<< Representation of restriction in a set of STD forms
3726 STD_union = 0x08 #<<< Representation of union in a set of STD forms
3727
3728 _STD_Map = { 'extension' : STD_extension
3729 , 'list' : STD_list
3730 , 'restriction' : STD_restriction
3731 , 'union' : STD_union }
3732
3733 # Bitmask defining the subset that comprises the final property
3734 __final = STD_empty
3735 @classmethod
3737 """Convert a final value to a string."""
3738 tags = []
3739 if final_value & cls.STD_extension:
3740 tags.append('extension')
3741 if final_value & cls.STD_list:
3742 tags.append('list')
3743 if final_value & cls.STD_restriction:
3744 tags.append('restriction')
3745 if final_value & cls.STD_union:
3746 tags.append('union')
3747 return ' '.join(tags)
3748
3749 VARIETY_absent = 0x01 #<<< Only used for the ur-type
3750 VARIETY_atomic = 0x02 #<<< Use for types based on a primitive type
3751 VARIETY_list = 0x03 #<<< Use for lists of atomic-variety types
3752 VARIETY_union = 0x04 #<<< Use for types that aggregate other types
3753
3754 # Derivation alternative
3755 _DA_empty = 'none specified'
3756 _DA_restriction = 'restriction'
3757 _DA_list = 'list'
3758 _DA_union = 'union'
3759
3761 return self.__derivationAlternative
3762 __derivationAlternative = None
3763
3764 # Identify the sort of value collection this holds. This field is
3765 # used to identify unresolved definitions.
3766 __variety = None
3768 return self.__variety
3769 @classmethod
3771 """Convert a variety value to a string."""
3772 if cls.VARIETY_absent == variety:
3773 return 'absent'
3774 if cls.VARIETY_atomic == variety:
3775 return 'atomic'
3776 if cls.VARIETY_list == variety:
3777 return 'list'
3778 if cls.VARIETY_union == variety:
3779 return 'union'
3780 return '?NoVariety?'
3781
3782 # For atomic variety only, the root (excepting ur-type) type.
3783 __primitiveTypeDefinition = None
3785 if throw_if_absent:
3786 if self.variety() != self.VARIETY_atomic:
3787 raise pyxb.BadPropertyError('[%s] primitiveTypeDefinition only defined for atomic types' % (self.name(), self.variety()))
3788 if self.__primitiveTypeDefinition is None:
3789 raise pyxb.LogicError('Expected primitive type for %s in %s', self, self.targetNamespace())
3790 return self.__primitiveTypeDefinition
3791
3792 # For list variety only, the type of items in the list
3793 __itemTypeDefinition = None
3795 if self.VARIETY_list != self.variety():
3796 raise pyxb.BadPropertyError('itemTypeDefinition only defined for list types')
3797 if self.__itemTypeDefinition is None:
3798 raise pyxb.LogicError('Expected item type')
3799 return self.__itemTypeDefinition
3800
3801 # For union variety only, the sequence of candidate members
3802 __memberTypeDefinitions = None
3804 if self.VARIETY_union != self.variety():
3805 raise pyxb.BadPropertyError('memberTypeDefinitions only defined for union types')
3806 if self.__memberTypeDefinitions is None:
3807 raise pyxb.LogicError('Expected member types')
3808 return self.__memberTypeDefinitions
3809
3810 # bR:STD
3812 """Implement base class method.
3813
3814 This STD depends on its baseTypeDefinition, unless its variety
3815 is absent. Other dependencies are on item, primitive, or
3816 member type definitions."""
3817 type_definitions = set()
3818 if self != self.baseTypeDefinition():
3819 type_definitions.add(self.baseTypeDefinition())
3820 if self.VARIETY_absent == self.variety():
3821 type_definitions = set()
3822 elif self.VARIETY_atomic == self.variety():
3823 if self != self.primitiveTypeDefinition():
3824 type_definitions.add(self.primitiveTypeDefinition())
3825 elif self.VARIETY_list == self.variety():
3826 assert self != self.itemTypeDefinition()
3827 type_definitions.add(self.itemTypeDefinition())
3828 elif self.VARIETY_union == self.variety():
3829 assert self not in self.memberTypeDefinitions()
3830 type_definitions.update(self.memberTypeDefinitions())
3831 else:
3832 raise pyxb.LogicError('Unable to identify dependent types: variety %s' % (self.variety(),))
3833 # NB: This type also depends on the value type definitions for
3834 # any facets that apply to it. This fact only matters when
3835 # generating the datatypes_facets source. That, and the fact
3836 # that there are dependency loops (e.g., integer requires a
3837 # nonNegativeInteger for its length facet) means we don't
3838 # bother adding in those.
3839 return frozenset(type_definitions)
3840
3841 # A non-property field that holds a reference to the DOM node from
3842 # which the type is defined. The value is held only between the
3843 # point where the simple type definition instance is created until
3844 # the point it is resolved.
3845 __domNode = None
3846
3847 # Indicate that this instance was defined as a built-in rather
3848 # than from a DOM instance.
3849 __isBuiltin = False
3850
3851 # Allocate one of these. Users should use one of the Create*
3852 # factory methods instead.
3853
3857
3859 """Extend base class unpickle support to retain link between
3860 this instance and the Python class that it describes.
3861
3862 This is because the pythonSupport value is a class reference,
3863 not an instance reference, so it wasn't deserialized, and its
3864 class member link was never set.
3865 """
3866 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3867 super_fn(state)
3868 if self.__pythonSupport is not None:
3869 self.__pythonSupport._SimpleTypeDefinition(self)
3870
3872 if self.name() is not None:
3873 elts = [ self.name(), ':' ]
3874 else:
3875 elts = [ '<anonymous>:' ]
3876 if self.VARIETY_absent == self.variety():
3877 elts.append('the ur-type')
3878 elif self.VARIETY_atomic == self.variety():
3879 elts.append('restriction of %s' % (self.baseTypeDefinition().name(),))
3880 elif self.VARIETY_list == self.variety():
3881 elts.append('list of %s' % (self.itemTypeDefinition().name(),))
3882 elif self.VARIETY_union == self.variety():
3883 elts.append('union of %s' % (" ".join([str(_mtd.name()) for _mtd in self.memberTypeDefinitions()],)))
3884 else:
3885 # Gets here if the type has not been resolved.
3886 elts.append('?')
3887 #raise pyxb.LogicError('Unexpected variety %s' % (self.variety(),))
3888 if self.__facets:
3889 felts = []
3890 for (k, v) in self.__facets.items():
3891 if v is not None:
3892 felts.append(str(v))
3893 elts.append("\n %s" % (','.join(felts),))
3894 if self.__fundamentalFacets:
3895 elts.append("\n ")
3896 elts.append(','.join( [str(_f) for _f in self.__fundamentalFacets ]))
3897 return 'STD[%s]' % (''.join(elts),)
3898
3900 """Override fields in this instance with those from the other.
3901
3902 This method is invoked only by Schema._addNamedComponent, and
3903 then only when a built-in type collides with a schema-defined
3904 type. Material like facets is not (currently) held in the
3905 built-in copy, so the DOM information is copied over to the
3906 built-in STD, which is subsequently re-resolved.
3907
3908 Returns self.
3909 """
3910 assert self != other
3911 assert self.isNameEquivalent(other)
3912 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3913
3914 # The other STD should be an unresolved schema-defined type.
3915 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3916 assert other.__domNode is not None
3917 self.__domNode = other.__domNode
3918
3919 # Preserve the python support
3920 if other.__pythonSupport is not None:
3921 # @todo: ERROR multiple references
3922 self.__pythonSupport = other.__pythonSupport
3923
3924 # Mark this instance as unresolved so it is re-examined
3925 self.__variety = None
3926 return self
3927
3931
3932 __SimpleUrTypeDefinition = None
3933 @classmethod
3935 """Create the SimpleTypeDefinition instance that approximates the simple ur-type.
3936
3937 See section 3.14.7."""
3938
3939 #if in_builtin_definition and (cls.__SimpleUrTypeDefinition is not None):
3940 # raise pyxb.LogicError('Multiple definitions of SimpleUrType')
3941 if cls.__SimpleUrTypeDefinition is None:
3942 # Note: We use a singleton subclass
3943 assert schema is not None
3944
3945 ns_ctx = schema.targetNamespace().initialNamespaceContext()
3946
3947 kw = { 'name' : 'anySimpleType',
3948 'schema' : schema,
3949 'namespace_context' : ns_ctx,
3950 'binding_namespace' : schema.targetNamespace(),
3951 'variety' : cls.VARIETY_absent,
3952 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
3953 bi = _SimpleUrTypeDefinition(**kw)
3954 bi._setPythonSupport(datatypes.anySimpleType)
3955
3956 # The baseTypeDefinition is the ur-type.
3957 bi.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
3958 # The simple ur-type has an absent variety, not an atomic
3959 # variety, so does not have a primitiveTypeDefinition
3960
3961 # No facets on the ur type
3962 bi.__facets = {}
3963 bi.__fundamentalFacets = frozenset()
3964
3965 bi.__resolveBuiltin()
3966
3967 cls.__SimpleUrTypeDefinition = bi
3968 return cls.__SimpleUrTypeDefinition
3969
3970 @classmethod
3972 """Create STD instances for built-in types.
3973
3974 For example, xml:space is a restriction of NCName; xml:lang is a union.
3975
3976 """
3977 from pyxb.binding import xml_
3978 kw = { 'schema' : schema,
3979 'binding_namespace' : schema.targetNamespace(),
3980 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
3981 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
3982 'variety' : cls.VARIETY_atomic }
3983 if 'space' == name:
3984 bi = cls(**kw)
3985 bi.__derivationAlternative = cls._DA_restriction
3986 bi.__baseTypeDefinition = datatypes.NCName.SimpleTypeDefinition()
3987 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition
3988 bi._setPythonSupport(xml_.STD_ANON_space)
3989 bi.setNameInBinding('STD_ANON_space')
3990 elif 'lang' == name:
3991 bi = cls(**kw)
3992 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
3993 bi.__memberTypes = [ datatypes.language.SimpleTypeDefinition() ]
3994 bi.__derivationAlternative = cls._DA_union
3995 bi.__primitiveTypeDefinition = bi
3996 bi._setPythonSupport(xml_.STD_ANON_lang)
3997 bi.setNameInBinding('STD_ANON_lang')
3998 else:
3999 raise pyxb.IncompleteImplementationError('No implementation for %s' % (name,))
4000 bi.__facets = { }
4001 for v in bi.pythonSupport().__dict__.values():
4002 if isinstance(v, facets.ConstrainingFacet):
4003 bi.__facets[v.__class__] = v
4004 return bi
4005
4006 @classmethod
4008 """Create a primitive simple type in the target namespace.
4009
4010 This is mainly used to pre-load standard built-in primitive
4011 types, such as those defined by XMLSchema Datatypes. You can
4012 use it for your own schemas as well, if you have special types
4013 that require explicit support to for Pythonic conversion.
4014
4015 All parameters are required and must be non-None.
4016 """
4017
4018 kw = { 'name' : name,
4019 'schema' : schema,
4020 'binding_namespace' : schema.targetNamespace(),
4021 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
4022 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
4023 'variety' : cls.VARIETY_atomic }
4024
4025 bi = cls(**kw)
4026 bi._setPythonSupport(python_support)
4027
4028 # Primitive types are based on the ur-type, and have
4029 # themselves as their primitive type definition.
4030 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
4031 bi.__primitiveTypeDefinition = bi
4032
4033 # Primitive types are built-in
4034 bi.__resolveBuiltin()
4035 assert bi.isResolved()
4036 return bi
4037
4038 @classmethod
4040 """Create a derived simple type in the target namespace.
4041
4042 This is used to pre-load standard built-in derived types. You
4043 can use it for your own schemas as well, if you have special
4044 types that require explicit support to for Pythonic
4045 conversion.
4046 """
4047 assert parent_std
4048 assert parent_std.__variety in (cls.VARIETY_absent, cls.VARIETY_atomic)
4049 kw = { 'name' : name,
4050 'schema' : schema,
4051 'binding_namespace' : schema.targetNamespace(),
4052 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
4053 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
4054 'variety' : parent_std.__variety }
4055
4056 bi = cls(**kw)
4057 bi._setPythonSupport(python_support)
4058
4059 # We were told the base type. If this is atomic, we re-use
4060 # its primitive type. Note that these all may be in different
4061 # namespaces.
4062 bi.__baseTypeDefinition = parent_std
4063 if cls.VARIETY_atomic == bi.__variety:
4064 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition
4065
4066 # Derived types are built-in
4067 bi.__resolveBuiltin()
4068 return bi
4069
4070 @classmethod
4072 """Create a list simple type in the target namespace.
4073
4074 This is used to preload standard built-in list types. You can
4075 use it for your own schemas as well, if you have special types
4076 that require explicit support to for Pythonic conversion; but
4077 note that such support is identified by the item_std.
4078 """
4079
4080 kw = { 'name' : name,
4081 'schema' : schema,
4082 'binding_namespace' : schema.targetNamespace(),
4083 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
4084 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
4085 'variety' : cls.VARIETY_list }
4086 bi = cls(**kw)
4087 bi._setPythonSupport(python_support)
4088
4089 # The base type is the ur-type. We were given the item type.
4090 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
4091 assert item_std
4092 bi.__itemTypeDefinition = item_std
4093
4094 # List types are built-in
4095 bi.__resolveBuiltin()
4096 return bi
4097
4098 @classmethod
4100 """(Placeholder) Create a union simple type in the target namespace.
4101
4102 This function has not been implemented."""
4103 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4104
4106 simple_type_child = None
4107 for cn in body.childNodes:
4108 if (Node.ELEMENT_NODE == cn.nodeType):
4109 if not xsd.nodeIsNamed(cn, 'simpleType'):
4110 if other_elts_ok:
4111 continue
4112 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4113 assert not simple_type_child
4114 simple_type_child = cn
4115 if simple_type_child is None:
4116 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4117 return simple_type_child
4118
4119 # The __initializeFrom* methods are responsible for identifying
4120 # the variety and the baseTypeDefinition. The remainder of the
4121 # resolution is performed by the __completeResolution method.
4122 # Note that in some cases resolution might yet be premature, so
4123 # variety is not saved until it is complete. All this stuff is
4124 # from section 3.14.2.
4125
4127 self.__baseTypeDefinition = self.SimpleUrTypeDefinition()
4128 self.__itemTypeAttribute = domutils.NodeAttribute(body, 'itemType')
4129 if self.__itemTypeAttribute is None:
4130 # NOTE: The newly created anonymous item type will
4131 # not be resolved; the caller needs to handle
4132 # that.
4133 self.__itemTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body), **kw)
4134 return self.__completeResolution(body, self.VARIETY_list, self._DA_list)
4135
4137 if self.__baseTypeDefinition is None:
4138 self.__baseAttribute = domutils.NodeAttribute(body, 'base')
4139 if self.__baseAttribute is None:
4140 self.__baseTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body, other_elts_ok=True), **kw)
4141 return self.__completeResolution(body, None, self._DA_restriction)
4142
4143 __localMemberTypes = None
4145 self.__baseTypeDefinition = self.SimpleUrTypeDefinition()
4146 self.__memberTypesAttribute = domutils.NodeAttribute(body, 'memberTypes')
4147 if self.__localMemberTypes is None:
4148 self.__localMemberTypes = []
4149 for cn in body.childNodes:
4150 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'simpleType'):
4151 self.__localMemberTypes.append(self.CreateFromDOM(cn, **kw))
4152 return self.__completeResolution(body, self.VARIETY_union, self._DA_union)
4153
4155 if self.hasPythonSupport():
4156 self.__facets = { }
4157 for v in self.pythonSupport().__dict__.values():
4158 if isinstance(v, facets.ConstrainingFacet):
4159 self.__facets[v.__class__] = v
4160 if v.ownerTypeDefinition() is None:
4161 v.setFromKeywords(_constructor=True, owner_type_definition=self)
4162 self.__isBuiltin = True
4163 return self
4164
4166 """Create facets for varieties that can take facets that are undeclared.
4167
4168 This means unions, which per section 4.1.2.3 of
4169 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4170 pattern restrictions."""
4171 if self.VARIETY_union != variety:
4172 return self
4173 self.__facets.setdefault(facets.CF_pattern)
4174 self.__facets.setdefault(facets.CF_enumeration)
4175 return self
4176
4178 """Identify the facets and properties for this stype.
4179
4180 This method simply identifies the facets that apply to this
4181 specific type, and records property values. Only
4182 explicitly-associated facets and properties are stored; others
4183 from base types will also affect this type. The information
4184 is taken from the applicationInformation children of the
4185 definition's annotation node, if any. If there is no support
4186 for the XMLSchema_hasFacetAndProperty namespace, this is a
4187 no-op.
4188
4189 Upon return, self.__facets is a map from the class for an
4190 associated fact to None, and self.__fundamentalFacets is a
4191 frozenset of instances of FundamentalFacet.
4192
4193 The return value is self.
4194 """
4195 self.__facets = { }
4196 self.__fundamentalFacets = frozenset()
4197 if self.annotation() is None:
4198 return self.__defineDefaultFacets(variety)
4199 app_info = self.annotation().applicationInformation()
4200 if app_info is None:
4201 return self.__defineDefaultFacets(variety)
4202 facet_map = { }
4203 fundamental_facets = set()
4204 seen_facets = set()
4205 for ai in app_info:
4206 for cn in ai.childNodes:
4207 if Node.ELEMENT_NODE != cn.nodeType:
4208 continue
4209 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4210 facet_name = domutils.NodeAttribute(cn, 'name')# , pyxb.namespace.XMLSchema_hfp)
4211 if facet_name is None:
4212 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4213 if facet_name in seen_facets:
4214 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4215 seen_facets.add(facet_name)
4216 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4217 #facet_map[facet_class] = facet_class(base_type_definition=self)
4218 facet_map[facet_class] = None
4219 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4220 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4221 if 0 < len(facet_map):
4222 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4223 self.__facets = facet_map
4224 assert type(self.__facets) == types.DictType
4225 if 0 < len(fundamental_facets):
4226 self.__fundamentalFacets = frozenset(fundamental_facets)
4227 return self
4228
4229 # NB: Must be done after resolution of the base type
4231
4232 # Create local list consisting of facet classes matched in children
4233 # and the map of keywords used to initialize the local instance.
4234
4235 local_facets = {}
4236 for fc in facets.Facet.Facets:
4237 children = domutils.LocateMatchingChildren(body, fc.Name())
4238 if 0 < len(children):
4239 fi = fc(base_type_definition=self.__baseTypeDefinition,
4240 owner_type_definition=self)
4241 if isinstance(fi, facets._LateDatatype_mixin):
4242 fi.bindValueDatatype(self)
4243 for cn in children:
4244 kw = { 'annotation': domutils.LocateUniqueChild(cn, 'annotation') }
4245 for ai in range(0, cn.attributes.length):
4246 attr = cn.attributes.item(ai)
4247 # Convert name from unicode to string
4248 kw[str(attr.localName)] = attr.value
4249 try:
4250 fi.setFromKeywords(**kw)
4251 except pyxb.PyXBException, e:
4252 raise pyxb.SchemaValidationError('Error assigning facet %s in %s: %s' % (fc.Name(), self.expandedName(), e))
4253 local_facets[fc] = fi
4254 self.__localFacets = local_facets
4255
4256 # We want a map from the union of the facet classes from this STD up
4257 # through its baseTypeDefinition (if present). Map elements should be
4258 # to None if the facet has not been constrained, or to the nearest
4259 # ConstrainingFacet instance if it is. ConstrainingFacet instances
4260 # created for local constraints also need a pointer to the
4261 # corresponding facet from the ancestor type definition, because those
4262 # constraints also affect this type.
4263 base_facets = {}
4264
4265 # Built-ins didn't get their facets() setting configured, so use the
4266 # _FacetMap() instead.
4267 if self.__baseTypeDefinition.isBuiltin():
4268 pstd = self.__baseTypeDefinition.pythonSupport()
4269 if pstd != datatypes.anySimpleType:
4270 base_facets.update(pstd._FacetMap())
4271 elif self.__baseTypeDefinition.facets():
4272 assert type(self.__baseTypeDefinition.facets()) == types.DictType
4273 base_facets.update(self.__baseTypeDefinition.facets())
4274 base_facets.update(self.facets())
4275
4276 self.__facets = self.__localFacets
4277 for fc in base_facets.keys():
4278 self.__facets.setdefault(fc, base_facets[fc])
4279 assert type(self.__facets) == types.DictType
4280
4282 """Create a new simple type with this as its base.
4283
4284 The type is owned by the provided owner, and may have facet
4285 restrictions defined by the body.
4286 @param owner: the owner for the newly created type
4287 @type owner: L{ComplexTypeDefinition}
4288 @param body: the DOM node from which facet information will be extracted
4289 @type body: C{xml.dom.Node}
4290 @rtype: L{SimpleTypeDefinition}
4291 """
4292 std = SimpleTypeDefinition(owner=owner, namespace_context=owner._namespaceContext(), variety=None, scope=self._scope(), schema=owner._schema())
4293 std.__baseTypeDefinition = self
4294 return std.__completeResolution(body, None, self._DA_restriction)
4295
4296 # Complete the resolution of some variety of STD. Note that the
4297 # variety is compounded by an alternative, since there is no
4298 # 'restriction' variety.
4300 assert self.__variety is None
4301 if self.__baseTypeDefinition is None:
4302 assert self.__baseAttribute is not None
4303 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4304 base_type = base_en.typeDefinition()
4305 if not isinstance(base_type, SimpleTypeDefinition):
4306 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4307 self.__baseTypeDefinition = base_type
4308 # If the base type exists but has not yet been resolved,
4309 # delay processing this type until the one it depends on
4310 # has been completed.
4311 assert self.__baseTypeDefinition != self
4312 if not self.__baseTypeDefinition.isResolved():
4313 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4314 return self
4315 if variety is None:
4316 # 3.14.1 specifies that the variety is the variety of the base
4317 # type definition which, by the way, can't be the ur type.
4318 variety = self.__baseTypeDefinition.__variety
4319 assert variety is not None
4320
4321 if self.VARIETY_absent == variety:
4322 # The ur-type is always resolved. So are restrictions of it,
4323 # which is how we might get here.
4324 pass
4325 elif self.VARIETY_atomic == variety:
4326 # Atomic types (and their restrictions) use the primitive
4327 # type, which is the highest type that is below the
4328 # ur-type (which is not atomic).
4329 ptd = self
4330 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4331 ptd = ptd.__baseTypeDefinition
4332
4333 self.__primitiveTypeDefinition = ptd
4334 elif self.VARIETY_list == variety:
4335 if self._DA_list == alternative:
4336 if self.__itemTypeAttribute is not None:
4337 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4338 self.__itemTypeDefinition = it_en.typeDefinition()
4339 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4340 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4341 elif self._DA_restriction == alternative:
4342 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4343 else:
4344 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4345 elif self.VARIETY_union == variety:
4346 if self._DA_union == alternative:
4347 # First time we try to resolve, create the member type
4348 # definitions. If something later prevents us from resolving
4349 # this type, we don't want to create them again, because we
4350 # might already have references to them.
4351 if self.__memberTypeDefinitions is None:
4352 mtd = []
4353 # If present, first extract names from memberTypes,
4354 # and add each one to the list
4355 if self.__memberTypesAttribute is not None:
4356 for mn in self.__memberTypesAttribute.split():
4357 # THROW if type has not been defined
4358 mn_en = self._namespaceContext().interpretQName(mn)
4359 std = mn_en.typeDefinition()
4360 if std is None:
4361 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4362 # Note: We do not need these to be resolved (here)
4363 assert isinstance(std, SimpleTypeDefinition)
4364 mtd.append(std)
4365 # Now look for local type definitions
4366 mtd.extend(self.__localMemberTypes)
4367 self.__memberTypeDefinitions = mtd
4368 assert None not in self.__memberTypeDefinitions
4369
4370 # Replace any member types that are themselves unions with the
4371 # members of those unions, in order. Note that doing this
4372 # might indicate we can't resolve this type yet, which is why
4373 # we separated the member list creation and the substitution
4374 # phases
4375 mtd = []
4376 for mt in self.__memberTypeDefinitions:
4377 assert isinstance(mt, SimpleTypeDefinition)
4378 if not mt.isResolved():
4379 self._queueForResolution('member type not resolved', depends_on=mt)
4380 return self
4381 if self.VARIETY_union == mt.variety():
4382 mtd.extend(mt.memberTypeDefinitions())
4383 else:
4384 mtd.append(mt)
4385 elif self._DA_restriction == alternative:
4386 assert self.__baseTypeDefinition
4387 # Base type should have been resolved before we got here
4388 assert self.__baseTypeDefinition.isResolved()
4389 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4390 assert mtd is not None
4391 else:
4392 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4393 # Save a unique copy
4394 self.__memberTypeDefinitions = mtd[:]
4395 else:
4396 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4397
4398 # Determine what facets, if any, apply to this type. This
4399 # should only do something if this is a primitive type.
4400 self.__processHasFacetAndProperty(variety)
4401 self.__updateFacets(body)
4402
4403 self.__derivationAlternative = alternative
4404 self.__variety = variety
4405 self.__domNode = None
4406 return self
4407
4409 """Indicate whether this simple type is fully defined.
4410
4411 Type resolution for simple types means that the corresponding
4412 schema component fields have been set. Specifically, that
4413 means variety, baseTypeDefinition, and the appropriate
4414 additional fields depending on variety. See _resolve() for
4415 more information.
4416 """
4417 # Only unresolved nodes have an unset variety
4418 return (self.__variety is not None)
4419
4420 # STD:res
4422 """Attempt to resolve the type.
4423
4424 Type resolution for simple types means that the corresponding
4425 schema component fields have been set. Specifically, that
4426 means variety, baseTypeDefinition, and the appropriate
4427 additional fields depending on variety.
4428
4429 All built-in STDs are resolved upon creation. Schema-defined
4430 STDs are held unresolved until the schema has been completely
4431 read, so that references to later schema-defined STDs can be
4432 resolved. Resolution is performed after the entire schema has
4433 been scanned and STD instances created for all
4434 topLevelSimpleTypes.
4435
4436 If a built-in STD is also defined in a schema (which it should
4437 be for XMLSchema), the built-in STD is kept, with the
4438 schema-related information copied over from the matching
4439 schema-defined STD. The former then replaces the latter in
4440 the list of STDs to be resolved.
4441
4442 Types defined by restriction have the same variety as the type
4443 they restrict. If a simple type restriction depends on an
4444 unresolved type, this method simply queues it for resolution
4445 in a later pass and returns.
4446 """
4447 if self.__variety is not None:
4448 return self
4449 assert self.__domNode
4450 node = self.__domNode
4451
4452 kw = { 'owner' : self
4453 , 'schema' : self._schema() }
4454
4455 bad_instance = False
4456 # The guts of the node should be exactly one instance of
4457 # exactly one of these three types.
4458 candidate = domutils.LocateUniqueChild(node, 'list')
4459 if candidate:
4460 self.__initializeFromList(candidate, **kw)
4461
4462 candidate = domutils.LocateUniqueChild(node, 'restriction')
4463 if candidate:
4464 if self.__variety is None:
4465 self.__initializeFromRestriction(candidate, **kw)
4466 else:
4467 bad_instance = True
4468
4469 candidate = domutils.LocateUniqueChild(node, 'union')
4470 if candidate:
4471 if self.__variety is None:
4472 self.__initializeFromUnion(candidate, **kw)
4473 else:
4474 bad_instance = True
4475
4476 if self.__baseTypeDefinition is None:
4477 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4478
4479 if self._schema() is not None:
4480 self.__final = self._schema().finalForNode(node, self._STD_Map)
4481
4482 # It is NOT an error to fail to resolve the type.
4483 if bad_instance:
4484 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4485
4486 return self
4487
4488 # CFD:STD CFD:SimpleTypeDefinition
4489 @classmethod
4491 # Node should be an XMLSchema simpleType node
4492 assert xsd.nodeIsNamed(node, 'simpleType')
4493
4494 name = domutils.NodeAttribute(node, 'name')
4495
4496 rv = cls(name=name, node=node, variety=None, **kw)
4497 rv._annotationFromDOM(node)
4498
4499 # Creation does not attempt to do resolution. Queue up the newly created
4500 # whatsis so we can resolve it after everything's been read in.
4501 rv.__domNode = node
4502 rv._queueForResolution('creation')
4503
4504 return rv
4505
4506 # pythonSupport is None, or a subclass of datatypes.simpleTypeDefinition.
4507 # When set, this simple type definition instance must be uniquely
4508 # associated with the python support type.
4509 __pythonSupport = None
4510
4512 # Includes check that python_support is not None
4513 assert issubclass(python_support, basis.simpleTypeDefinition)
4514 # Can't share support instances
4515 self.__pythonSupport = python_support
4516 self.__pythonSupport._SimpleTypeDefinition(self)
4517 if self.nameInBinding() is None:
4518 self.setNameInBinding(self.__pythonSupport.__name__)
4519 return self.__pythonSupport
4520
4522 return self.__pythonSupport is not None
4523
4525 if self.__pythonSupport is None:
4526 raise pyxb.LogicError('%s: No support defined' % (self.name(),))
4527 return self.__pythonSupport
4528
4531
4534
4538
4540 """Data associated with an
4541 U{import<http://www.w3.org/TR/xmlschema-1/#composition-schemaImport>}
4542 statement within a schema."""
4543
4547 __id = None
4548
4550 """The L{pyxb.namespace.Namespace} instance corresponding to the value
4551 of the C{namespace} attribute from the import statement."""
4552 return self.__namespace
4553 __namespace = None
4554
4556 """The value of the C{schemaLocation} attribute from the import
4557 statement, normalized relative to the location of the importing
4558 schema."""
4559 return self.__schemaLocation
4560 __schemaLocation = None
4561
4563 """The prefix from a namespace declaration for L{namespace} that was
4564 active in the context of the import element, or C{None} if there was
4565 no relevant namespace declaration in scope at that point.
4566
4567 This is propagated to be used as the default prefix for the
4568 corresponding namespace if no prefix had been assigned.
4569 """
4570 return self.__prefix
4571 __prefix = None
4572
4574 """The L{Schema} instance corresponding to the imported schema, if
4575 available.
4576
4577 Normally C{import} statements will be fulfilled by loading components
4578 from a L{namespace archive<pyxb.namespace.NamespaceArchive>} in which
4579 the corresponding namespace is marked as public. Where there are
4580 cycles in the namespace dependency graph, or the schema for a
4581 namespace are associated with a restricted profile of another
4582 namespace, there may be no such archive and instead the components are
4583 obtained using this schema."""
4584 return self.__schema
4585 __schema = None
4586
4588 """Gather the information relative to an C{import} statement.
4589
4590 If the imported namespace can be loaded from an archive, the
4591 C{schemaLocation} attribute is ignored. Otherwise, it attempts to
4592 retrieve and parse the corresponding schema (if this has not already
4593 been done).
4594
4595 @param importing_schema: The L{Schema} instance in which the import
4596 was found.
4597 @param node: The C{xml.dom.DOM} node incorporating the schema
4598 information.
4599
4600 @raise Exception: Any exception raised when attempting to retrieve and
4601 parse data from the schema location.
4602 """
4603
4604 super(_ImportElementInformationItem, self).__init__(**kw)
4605 uri = domutils.NodeAttribute(node, 'namespace')
4606 if uri is None:
4607 raise pyxb.IncompleteImplementationError('import statements without namespace not supported')
4608 schema_location = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), importing_schema.location())
4609 self.__schemaLocation = schema_location
4610 ns = self.__namespace = pyxb.namespace.NamespaceForURI(uri, create_if_missing=True)
4611 need_schema = not (ns.isLoadable() or ns.isBuiltinNamespace())
4612 if not need_schema:
4613 # Discard location if we expect to be able to learn about this
4614 # namespace from an archive or a built-in description
4615 self.__schemaLocation = None
4616
4617 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
4618 if self.schemaLocation() is not None:
4619 # @todo: NOTICE
4620 (has_schema, schema_instance) = self.__namespace.lookupSchemaByLocation(schema_location)
4621 if not has_schema:
4622 ckw = { 'absolute_schema_location' : schema_location,
4623 'generation_uid' : importing_schema.generationUID(),
4624 'uri_content_archive_directory' : importing_schema._uriContentArchiveDirectory(),
4625 }
4626 try:
4627 schema_instance = Schema.CreateFromLocation(**ckw)
4628 except Exception, e:
4629 _log.exception('Import %s cannot read schema location %s (%s)', ns, self.__schemaLocation, schema_location)
4630 raise
4631 self.__schema = schema_instance
4632 elif need_schema:
4633 _log.warning('No information available on imported namespace %s', uri)
4634
4635 # If we think we found a schema, make sure it's in the right
4636 # namespace.
4637 if self.__schema is not None:
4638 if ns != self.__schema.targetNamespace():
4639 raise pyxb.SchemaValidationError('Import expected namespace %s but got %s' % (ns, self.__schema.targetNamespace()))
4640
4641 self.__prefix = ns_ctx.prefixForNamespace(self.namespace())
4642
4643 self._annotationFromDOM(node)
4644
4646 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4647
4650
4651 # List of annotations
4652 __annotations = None
4653
4654 # True when we have started seeing elements, attributes, or
4655 # notations.
4656 __pastProlog = False
4657
4659 """URI or path to where the schema can be found.
4660
4661 For schema created by a user, the location should be provided to the
4662 constructor using the C{schema_location} keyword. In the case of
4663 imported or included schema, the including schema's location is used
4664 as the base URI for determining the absolute URI of the included
4665 schema from its (possibly relative) location value. For files,
4666 the scheme and authority portions are generally absent, as is often
4667 the abs_path part."""
4668 return self.__location
4669 __location = None
4670
4672 return self.__locationTag
4673 __locationTag = None
4674
4676 return self.__signature
4677 __signature = None
4678
4680 return self.__generationUID
4681 __generationUID = None
4682
4684 return self.__originRecord
4685 __originRecord = None
4686
4688 """The targetNamespace of a componen.
4689
4690 This is None, or a reference to a Namespace in which the
4691 component is declared (either as a global or local to one of
4692 the namespace's complex type definitions). This is immutable
4693 after creation.
4694 """
4695 return self.__targetNamespace
4696 __targetNamespace = None
4697
4699 """Default namespace of the schema.
4700
4701 Will be None unless the schema has an 'xmlns' attribute. The
4702 value must currently be provided as a keyword parameter to the
4703 constructor. """
4704 return self.__defaultNamespace
4705 __defaultNamespace = None
4706
4708 return self.__referencedNamespaces
4709 __referencedNamespaces = None
4710
4711 __namespaceData = None
4712
4714 return self.__importEIIs
4715 __importEIIs = None
4716
4718 return self.__importedSchema
4719 __importedSchema = None
4721 return self.__includedSchema
4722 __includedSchema = None
4723
4724 _QUALIFIED = "qualified"
4725 _UNQUALIFIED = "unqualified"
4726
4727 # Default values for standard recognized schema attributes
4728 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4729 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4730 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4731 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4732 , pyxb.namespace.ExpandedName(None, 'id') : None
4733 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4734 , pyxb.namespace.ExpandedName(None, 'version') : None
4735 , pyxb.namespace.XML.createExpandedName('lang') : None
4736 }
4737
4739 """Override the schema attribute with the given DOM value."""
4740 self.__attributeMap[pyxb.namespace.ExpandedName(attr.name)] = attr.nodeValue
4741 return self
4742
4744 """Override the schema attributes with values from the given map."""
4745 self.__attributeMap.update(attr_map)
4746 return self
4747
4749 """Return True iff the schema has an attribute with the given (nc)name."""
4750 if isinstance(attr_name, basestring):
4751 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4752 return self.__attributeMap.has_key(attr_name)
4753
4755 """Return the schema attribute value associated with the given (nc)name.
4756
4757 @param attr_name: local name for the attribute in the schema element.
4758 @return: the value of the corresponding attribute, or C{None} if it
4759 has not been defined and has no default.
4760 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4761 """
4762 if isinstance(attr_name, basestring):
4763 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4764 return self.__attributeMap[attr_name]
4765
4766 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4767 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4768 'identityConstraintDefinition' )
4769
4771 return self.__uriContentArchiveDirectory
4772 __uriContentArchiveDirectory = None
4773
4775 # Force resolution of available namespaces if not already done
4776 if not kw.get('_bypass_preload', False):
4777 pyxb.namespace.archive.NamespaceArchive.PreLoadArchives()
4778
4779 assert 'schema' not in kw
4780 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
4781 self.__location = kw.get('schema_location')
4782 if self.__location is not None:
4783 schema_path = self.__location
4784 if 0 <= schema_path.find(':'):
4785 schema_path = urlparse.urlparse(schema_path)[2] # .path
4786 self.__locationTag = os.path.split(schema_path)[1].split('.')[0]
4787
4788 self.__generationUID = kw.get('generation_uid')
4789 if self.__generationUID is None:
4790 _log.warning('No generationUID provided')
4791 self.__generationUID = pyxb.utils.utility.UniqueIdentifier()
4792
4793 self.__signature = kw.get('schema_signature')
4794
4795 super(Schema, self).__init__(*args, **kw)
4796 self.__importEIIs = set()
4797 self.__includedSchema = set()
4798 self.__importedSchema = set()
4799 self.__targetNamespace = self._namespaceContext().targetNamespace()
4800 if not isinstance(self.__targetNamespace, pyxb.namespace.Namespace):
4801 raise pyxb.LogicError('Schema constructor requires valid Namespace instance as target_namespace')
4802
4803 # NB: This will raise pyxb.SchemaUniquenessError if it appears this
4804 # schema has already been incorporated into the target namespace.
4805 self.__originRecord = self.__targetNamespace.addSchema(self)
4806
4807 self.__targetNamespace.configureCategories(self.__SchemaCategories)
4808 if self.__defaultNamespace is not None:
4809 self.__defaultNamespace.configureCategories(self.__SchemaCategories)
4810
4811 self.__attributeMap = self.__attributeMap.copy()
4812 self.__annotations = []
4813 # @todo: This isn't right if namespaces are introduced deeper in the document
4814 self.__referencedNamespaces = self._namespaceContext().inScopeNamespaces().values()
4815
4816 __TopLevelComponentMap = {
4817 'element' : ElementDeclaration,
4818 'attribute' : AttributeDeclaration,
4819 'notation' : NotationDeclaration,
4820 'simpleType' : SimpleTypeDefinition,
4821 'complexType' : ComplexTypeDefinition,
4822 'group' : ModelGroupDefinition,
4823 'attributeGroup' : AttributeGroupDefinition
4824 }
4825
4826 @classmethod
4828 if not ('schema_signature' in kw):
4829 kw['schema_signature'] = pyxb.utils.utility.HashForText(xmls)
4830 return cls.CreateFromDOM(domutils.StringToDOM(xmls, **kw), **kw)
4831
4832 @classmethod
4834 """Create a schema from a schema location.
4835
4836 Reads an XML document from the schema location and creates a schema
4837 using it. All keyword parameters are passed to L{CreateFromDOM}.
4838
4839 @keyword schema_location: A file path or a URI. If this is a relative
4840 URI and C{parent_uri} is present, the actual location will be
4841 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4842 @keyword parent_uri: The context within which schema_location will be
4843 normalized, if necessary.
4844 @keyword absolute_schema_location: A file path or URI. This value is
4845 not normalized, and supersedes C{schema_location}.
4846 """
4847 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4848 kw['location_base'] = kw['schema_location'] = schema_location
4849 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4850 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4851 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4852
4853 @classmethod
4855 return cls.CreateFromDocument(stream.read(), **kw)
4856
4857 @classmethod
4858 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4859 """Take the root element of the document, and scan its attributes under
4860 the assumption it is an XMLSchema schema element. That means
4861 recognize namespace declarations and process them. Also look for
4862 and set the default namespace. All other attributes are passed up
4863 to the parent class for storage."""
4864
4865 # Get the context of any schema that is including (not importing) this
4866 # one.
4867 including_context = kw.get('including_context')
4868
4869 root_node = node
4870 if Node.DOCUMENT_NODE == node.nodeType:
4871 root_node = root_node.documentElement
4872 if Node.ELEMENT_NODE != root_node.nodeType:
4873 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4874
4875 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4876 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4877 parent_context=namespace_context,
4878 including_context=including_context)
4879
4880 tns = ns_ctx.targetNamespace()
4881 if tns is None:
4882 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4883 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4884 schema.__namespaceData = ns_ctx
4885
4886 if schema.targetNamespace() != ns_ctx.targetNamespace():
4887 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4888
4889 # Update the attribute map
4890 for ai in range(root_node.attributes.length):
4891 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4892
4893 # Verify that the root node is an XML schema element
4894 if not xsd.nodeIsNamed(root_node, 'schema'):
4895 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4896
4897 for cn in root_node.childNodes:
4898 if Node.ELEMENT_NODE == cn.nodeType:
4899 rv = schema.__processTopLevelNode(cn)
4900 if rv is None:
4901 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4902 elif Node.TEXT_NODE == cn.nodeType:
4903 # Non-element content really should just be whitespace.
4904 # If something else is seen, print it for inspection.
4905 text = cn.data.strip()
4906 if text:
4907 _log.info('Ignored text: %s', text)
4908 elif Node.COMMENT_NODE == cn.nodeType:
4909 pass
4910 else:
4911 # ATTRIBUTE_NODE
4912 # CDATA_SECTION_NODE
4913 # ENTITY_NODE
4914 # PROCESSING_INSTRUCTION
4915 # DOCUMENT_NODE
4916 # DOCUMENT_TYPE_NODE
4917 # NOTATION_NODE
4918 _log.info('Ignoring non-element: %s', cn)
4919
4920 # Do not perform resolution yet: we may be done with this schema, but
4921 # the namespace may incorporate additional ones, and we can't resolve
4922 # until everything's present.
4923 return schema
4924
4925 _SA_All = '#all'
4926
4928 ebv = domutils.NodeAttribute(dom_node, attr)
4929 if ebv is None:
4930 ebv = self.schemaAttribute('%sDefault' % (attr,))
4931 rv = 0
4932 if ebv == self._SA_All:
4933 for v in candidate_map.values():
4934 rv += v
4935 else:
4936 for candidate in ebv.split():
4937 rv += candidate_map.get(candidate, 0)
4938 return rv
4939
4941 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4942
4943 A value of '#all' means enable every options; otherwise, the attribute
4944 value should be a list of tokens, for which the corresponding value
4945 will be added to the return value.
4946
4947 @param dom_node: the node from which the "block" attribute will be retrieved
4948 @type dom_node: C{xml.dom.Node}
4949 @param candidate_map: map from strings to bitmask values
4950 """
4951 return self.__ebvForNode('block', dom_node, candidate_map)
4952
4954 """Return a bit mask indicating a set of options read from the node's
4955 "final" attribute or the schema's "finalDefault" attribute.
4956
4957 A value of '#all' means enable every options; otherwise, the attribute
4958 value should be a list of tokens, for which the corresponding value
4959 will be added to the return value.
4960
4961 @param dom_node: the node from which the "final" attribute will be retrieved
4962 @type dom_node: C{xml.dom.Node}
4963 @param candidate_map: map from strings to bitmask values
4964 """
4965 return self.__ebvForNode('final', dom_node, candidate_map)
4966
4968 """Determine the target namespace for a local attribute or element declaration.
4969
4970 Look at the node's C{form} attribute, or if none the schema's
4971 C{attributeFormDefault} or C{elementFormDefault} value. If the
4972 resulting value is C{"qualified"} and the parent schema has a
4973 non-absent target namespace, return it to use as the declaration
4974 target namespace. Otherwise, return None to indicate that the
4975 declaration has no namespace.
4976
4977 @param dom_node: The node defining an element or attribute declaration
4978 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4979 @return: L{pyxb.namespace.Namespace} or None
4980 """
4981
4982 form_type = domutils.NodeAttribute(dom_node, 'form')
4983 if form_type is None:
4984 if declaration_type == ElementDeclaration:
4985 form_type = self.schemaAttribute('elementFormDefault')
4986 elif declaration_type == AttributeDeclaration:
4987 form_type = self.schemaAttribute('attributeFormDefault')
4988 else:
4989 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4990 tns = None
4991 if (self._QUALIFIED == form_type):
4992 tns = self.targetNamespace()
4993 if tns.isAbsentNamespace():
4994 tns = None
4995 else:
4996 if (self._UNQUALIFIED != form_type):
4997 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4998 return tns
4999
5001 """Throw a SchemaValidationException referencing the given
5002 node if we have passed the sequence point representing the end
5003 of prolog elements."""
5004
5005 if self.__pastProlog:
5006 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
5007
5009 self.__requireInProlog(node.nodeName)
5010 # See section 4.2.1 of Structures.
5011 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
5012 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
5013 if not has_schema:
5014 kw = { 'absolute_schema_location': abs_uri,
5015 'including_context': self.__namespaceData,
5016 'generation_uid': self.generationUID(),
5017 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
5018 }
5019 try:
5020 schema_instance = self.CreateFromLocation(**kw)
5021 except pyxb.SchemaUniquenessError, e:
5022 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
5023 except Exception, e:
5024 _log.exception('INCLUDE %s caught', abs_uri)
5025 raise
5026 if schema_instance:
5027 if self.targetNamespace() != schema_instance.targetNamespace():
5028 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
5029 self.__includedSchema.add(schema_instance)
5030 return node
5031
5033 """Process an import directive.
5034
5035 This attempts to locate schema (named entity) information for
5036 a namespace that is referenced by this schema.
5037 """
5038
5039 self.__requireInProlog(node.nodeName)
5040 import_eii = _ImportElementInformationItem(self, node)
5041 if import_eii.schema() is not None:
5042 self.__importedSchema.add(import_eii.schema())
5043 self.targetNamespace().importNamespace(import_eii.namespace())
5044 ins = import_eii.namespace()
5045 if ins.prefix() is None:
5046 ins.setPrefix(import_eii.prefix())
5047 self.__importEIIs.add(import_eii)
5048 return node
5049
5051 self.__requireInProlog(node.nodeName)
5052 raise pyxb.IncompleteImplementationError('redefine not implemented')
5053
5057
5059 """Process a DOM node from the top level of the schema.
5060
5061 This should return a non-None value if the node was
5062 successfully recognized."""
5063 if xsd.nodeIsNamed(node, 'include'):
5064 return self.__processInclude(node)
5065 if xsd.nodeIsNamed(node, 'import'):
5066 return self.__processImport(node)
5067 if xsd.nodeIsNamed(node, 'redefine'):
5068 return self.__processRedefine(node)
5069 if xsd.nodeIsNamed(node, 'annotation'):
5070 return self.__processAnnotation(node)
5071
5072 component = self.__TopLevelComponentMap.get(node.localName)
5073 if component is not None:
5074 self.__pastProlog = True
5075 kw = { 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
5076 'schema' : self,
5077 'owner' : self }
5078 return self._addNamedComponent(component.CreateFromDOM(node, **kw))
5079
5080 raise pyxb.SchemaValidationError('Unexpected top-level element %s' % (node.nodeName,))
5081
5085
5087 tns = self.targetNamespace()
5088 assert tns is not None
5089 if not isinstance(nc, _NamedComponent_mixin):
5090 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
5091 if nc.isAnonymous():
5092 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
5093 if isinstance(nc, _ScopedDeclaration_mixin):
5094 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
5095 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5096 return self.__addTypeDefinition(nc)
5097 if isinstance(nc, AttributeDeclaration):
5098 return self.__addAttributeDeclaration(nc)
5099 if isinstance(nc, AttributeGroupDefinition):
5100 return self.__addAttributeGroupDefinition(nc)
5101 if isinstance(nc, ModelGroupDefinition):
5102 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5103 if isinstance(nc, ElementDeclaration):
5104 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5105 if isinstance(nc, NotationDeclaration):
5106 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5107 if isinstance(nc, IdentityConstraintDefinition):
5108 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5109 raise pyxb.IncompleteImplementationError('No support to record named component of type %s' % (nc.__class__,))
5110
5112 local_name = td.name()
5113 assert self.__targetNamespace
5114 tns = self.targetNamespace()
5115 old_td = tns.typeDefinitions().get(local_name)
5116 if (old_td is not None) and (old_td != td):
5117 if isinstance(td, ComplexTypeDefinition) != isinstance(old_td, ComplexTypeDefinition):
5118 raise pyxb.SchemaValidationError('Name %s used for both simple and complex types' % (td.name(),))
5119
5120 if not old_td._allowUpdateFromOther(td):
5121 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin type definition %s' % (tns.createExpandedName(local_name),))
5122
5123 # Copy schema-related information from the new definition
5124 # into the old one, and continue to use the old one.
5125 td = tns._replaceComponent(td, old_td._updateFromOther(td))
5126 else:
5127 tns.addCategoryObject('typeDefinition', td.name(), td)
5128 assert td is not None
5129 return td
5130
5132 local_name = ad.name()
5133 assert self.__targetNamespace
5134 tns = self.targetNamespace()
5135 old_ad = tns.attributeDeclarations().get(local_name)
5136 if (old_ad is not None) and (old_ad != ad):
5137 if not old_ad._allowUpdateFromOther(ad):
5138 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute declaration %s' % (tns.createExpandedName(local_name),))
5139
5140 # Copy schema-related information from the new definition
5141 # into the old one, and continue to use the old one.
5142 ad = tns._replaceComponent(ad, old_ad._updateFromOther(ad))
5143 else:
5144 tns.addCategoryObject('attributeDeclaration', ad.name(), ad)
5145 assert ad is not None
5146 return ad
5147
5149 local_name = agd.name()
5150 assert self.__targetNamespace
5151 tns = self.targetNamespace()
5152 old_agd = tns.attributeGroupDefinitions().get(local_name)
5153 if (old_agd is not None) and (old_agd != agd):
5154 if not old_agd._allowUpdateFromOther(agd):
5155 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute group definition %s' % (tns.createExpandedName(local_name),))
5156
5157 # Copy schema-related information from the new definition
5158 # into the old one, and continue to use the old one.
5159 tns._replaceComponent(agd, old_agd._updateFromOther(agd))
5160 else:
5161 tns.addCategoryObject('attributeGroupDefinition', agd.name(), agd)
5162 assert agd is not None
5163 return agd
5164
5166 return 'SCH[%s]' % (self.location(),)
5167
5170 """Add to the schema the definitions of the built-in types of XMLSchema.
5171 This should only be invoked by L{pyxb.namespace} when the built-in
5172 namespaces are initialized. """
5173 # Add the ur type
5174 #schema = namespace.schema()
5175 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5176 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5177 assert td.isResolved()
5178 # Add the simple ur type
5179 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5180 assert td.isResolved()
5181 # Add definitions for all primitive and derived simple types
5182 pts_std_map = {}
5183 for dtc in datatypes._PrimitiveDatatypes:
5184 name = dtc.__name__.rstrip('_')
5185 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5186 assert td.isResolved()
5187 assert dtc.SimpleTypeDefinition() == td
5188 pts_std_map.setdefault(dtc, td)
5189 for dtc in datatypes._DerivedDatatypes:
5190 name = dtc.__name__.rstrip('_')
5191 parent_std = pts_std_map[dtc.XsdSuperType()]
5192 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5193 assert td.isResolved()
5194 assert dtc.SimpleTypeDefinition() == td
5195 pts_std_map.setdefault(dtc, td)
5196 for dtc in datatypes._ListDatatypes:
5197 list_name = dtc.__name__.rstrip('_')
5198 element_name = dtc._ItemType.__name__.rstrip('_')
5199 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5200 assert element_std is not None
5201 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5202 assert td.isResolved()
5203 global _PastAddBuiltInTypes
5204 _PastAddBuiltInTypes = True
5205
5206 return schema
5207
5208 import sys
5209 import pyxb.namespace.builtin
5210 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5211
5212 ## Local Variables:
5213 ## fill-column:78
5214 ## End:
5215
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Thu Nov 1 15:13:25 2012 | http://epydoc.sourceforge.net |