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