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