| 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.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
1456
1457 __substitutionGroupAttribute = None
1458
1459 __typeAttribute = None
1460
1461 __nillable = False
1463 return self.__nillable
1464
1465 __identityConstraintDefinitions = None
1467 """A list of IdentityConstraintDefinition instances."""
1468 return self.__identityConstraintDefinitions
1469
1470 __substitutionGroupAffiliation = None
1472 """None, or a reference to an ElementDeclaration."""
1473 return self.__substitutionGroupAffiliation
1474
1475 SGE_none = 0 #<<< No substitution group exclusion specified
1476 SGE_extension = 0x01 #<<< Substitution by an extension of the base type
1477 SGE_restriction = 0x02 #<<< Substitution by a restriction of the base type
1478 SGE_substitution = 0x04 #<<< Substitution by replacement (?)
1479
1480 _SGE_Map = { 'extension' : SGE_extension
1481 , 'restriction' : SGE_restriction }
1482 _DS_Map = _SGE_Map.copy()
1483 _DS_Map.update( { 'substitution' : SGE_substitution } )
1484
1485 # Subset of SGE marks formed by bitmask. SGE_substitution is disallowed.
1486 __substitutionGroupExclusions = SGE_none
1487
1488 # Subset of SGE marks formed by bitmask
1489 __disallowedSubstitutions = SGE_none
1490
1491 __abstract = False
1493 return self.__abstract
1494
1498
1499 # bR:ED
1501 """Element declarations depend on the type definition of their
1502 content."""
1503 return frozenset([self.__typeDefinition])
1504
1507
1508 # CFD:ED CFD:ElementDeclaration
1509 @classmethod
1511 """Create an element declaration from the given DOM node.
1512
1513 wxs is a Schema instance within which the element is being
1514 declared.
1515
1516 scope is the _ScopeDeclaration_mixin context into which the
1517 element declaration is recorded. It can be SCOPE_global, a
1518 complex type definition, or None in the case of elements
1519 declared in a named model group.
1520
1521 node is a DOM element. The name must be 'element', and the
1522 node must be in the XMLSchema namespace."""
1523
1524 scope = kw['scope']
1525 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
1526
1527 # Node should be an XMLSchema element node
1528 assert xsd.nodeIsNamed(node, 'element')
1529
1530 # Might be top-level, might be local
1531 name = domutils.NodeAttribute(node, 'name')
1532 if xsd.nodeIsNamed(node.parentNode, 'schema'):
1533 assert _ScopedDeclaration_mixin.SCOPE_global == scope
1534 elif domutils.NodeAttribute(node, 'ref') is None:
1535 # Scope may be None or a CTD.
1536 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
1537 else:
1538 raise pyxb.SchemaValidationError('Created reference as element declaration')
1539
1540 rv = cls(name=name, node=node, **kw)
1541 rv._annotationFromDOM(node)
1542 rv._valueConstraintFromDOM(node)
1543
1544 rv.__substitutionGroupAttribute = domutils.NodeAttribute(node, 'substitutionGroup')
1545
1546 kw.pop('node', None)
1547 kw['owner'] = rv
1548
1549 identity_constraints = []
1550 for cn in node.childNodes:
1551 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'):
1552 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw))
1553 rv.__identityConstraintDefinitions = identity_constraints
1554
1555 rv.__typeDefinition = None
1556 rv.__typeAttribute = domutils.NodeAttribute(node, 'type')
1557 simpleType_node = domutils.LocateUniqueChild(node, 'simpleType')
1558 complexType_node = domutils.LocateUniqueChild(node, 'complexType')
1559 if rv.__typeAttribute is not None:
1560 if (simpleType_node is not None) and (complexType_node is not None):
1561 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child')
1562 if (rv.__typeDefinition is None) and (simpleType_node is not None):
1563 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw)
1564 if (rv.__typeDefinition is None) and (complexType_node is not None):
1565 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw)
1566 if rv.__typeDefinition is None:
1567 if rv.__typeAttribute is None:
1568 # Scan for particle types which were supposed to be enclosed in a complexType
1569 for cn in node.childNodes:
1570 if Particle.IsParticleNode(cn):
1571 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,))
1572 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition()
1573 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None)
1574 if not rv.__isResolved:
1575 rv._queueForResolution('creation')
1576
1577 attr_val = domutils.NodeAttribute(node, 'nillable')
1578 if attr_val is not None:
1579 rv.__nillable = datatypes.boolean(attr_val)
1580
1581 attr_val = domutils.NodeAttribute(node, 'abstract')
1582 if attr_val is not None:
1583 rv.__abstract = datatypes.boolean(attr_val)
1584
1585 schema = kw['schema']
1586 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map)
1587 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map)
1588
1589 return rv
1590
1592 """Determine whether this element declaration is adaptable.
1593
1594 OK, this gets ugly. First, if this declaration isn't resolved, it's
1595 clearly not adaptable.
1596
1597 Now: For it to be adaptable, we must know enough about its type to
1598 verify that it is derivation-consistent with any other uses of the
1599 same name in the same complex type. If the element's type is
1600 resolved, that's good enough.
1601
1602 If the element's type isn't resolved, we're golden as long as
1603 type-equivalent types were used. But it's also allowed for the
1604 derived ctd to use the element name constraining it to a derivation of
1605 the element base type. (Go see namespace
1606 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D,
1607 BoundingBox, and WGS84BoundingBox for an example). So, we really do
1608 have to have the element's type resolved.
1609
1610 Except that if a CTD's content incorporates an element with the same
1611 type as the CTD (i.e., nested), this will never happen, because the
1612 CTD can't get resolved until after it has been resolved.
1613 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and
1614 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for
1615 an example).
1616
1617 So, we give the world a break and assume that if the type we're trying
1618 to resolve is the same as the type of an element in that type, then
1619 the element type will be resolved by the point it's needed. In point
1620 of fact, it won't, but we'll only notice that if a CTD contains an
1621 element whose type is a restriction of the CTD. In that case,
1622 isDerivationConsistent will blow chunks and somebody'll have to come
1623 back and finish up this mess.
1624 """
1625
1626 if not self.isResolved():
1627 return False
1628 if self.typeDefinition().isResolved():
1629 return True
1630 # Aw, dammit. See if we're gonna need the type resolved before we can
1631 # adapt this thing.
1632 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName())
1633 if existing_decl is None:
1634 # Nobody else has this name, so we don't have to check for
1635 # consistency.
1636 return True
1637 # OK, we've got a name clash. Are the two types trivially equivalent?
1638 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()):
1639 # Yes! Go for it.
1640 return True
1641 # No. Can't proceed until the type definition is resolved. Hope it
1642 # can be....
1643 _log.warning('Require %s to be resolved; might be a loop.', self.typeDefinition())
1644 return False
1645
1646 # aFS:ED
1648 rv = self
1649 assert isinstance(ctd, ComplexTypeDefinition), '%s is not a CTD' % (ctd,)
1650 if not isinstance(self.scope(), ComplexTypeDefinition):
1651 assert owner is not None
1652 rv = self._clone(owner, ctd._objectOrigin())
1653 rv._setScope(ctd)
1654 ctd._recordLocalDeclaration(rv)
1655 return rv
1656
1657 __isResolved = False
1659 return self.__isResolved
1660
1661 # res:ED res:ElementDeclaration
1663 if self.isResolved():
1664 return self
1665
1666 #if self._scopeIsIndeterminate():
1667 # _log.debug('WARNING: Resolving ED %s with indeterminate scope (is this a problem?)', self.expandedName())
1668 if self.__substitutionGroupAttribute is not None:
1669 sg_en = self._namespaceContext().interpretQName(self.__substitutionGroupAttribute)
1670 sga = sg_en.elementDeclaration()
1671 if sga is None:
1672 raise pyxb.SchemaValidationError('Element declaration refers to unrecognized substitution group %s' % (sg_en,))
1673 self.__substitutionGroupAffiliation = sga
1674
1675 if self.__typeDefinition is None:
1676 assert self.__typeAttribute is not None
1677 type_en = self._namespaceContext().interpretQName(self.__typeAttribute)
1678 self.__typeDefinition = type_en.typeDefinition()
1679 if self.__typeDefinition is None:
1680 raise pyxb.SchemaValidationError('Type declaration %s cannot be found' % (type_en,))
1681
1682 self.__isResolved = True
1683 return self
1684
1687
1689 if self.typeDefinition() is not None:
1690 return 'ED[%s:%s]' % (self.name(), self.typeDefinition().name())
1691 return 'ED[%s:?]' % (self.name(),)
1692
1693
1694 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1695 __PrivateTransient = set()
1696
1697 # The type resolved from the base attribute.
1698 __baseTypeDefinition = None
1702
1703 DM_empty = 0 #<<< No derivation method specified
1704 DM_extension = 0x01 #<<< Derivation by extension
1705 DM_restriction = 0x02 #<<< Derivation by restriction
1706
1707 _DM_Map = { 'extension' : DM_extension
1708 , 'restriction' : DM_restriction }
1709
1710 # How the type was derived (a DM_* value)
1711 # (This field is used to identify unresolved definitions.)
1712 __derivationMethod = None
1716
1717 # Derived from the final and finalDefault attributes
1718 __final = DM_empty
1719
1720 # Derived from the abstract attribute
1721 __abstract = False
1723 return self.__abstract
1724
1725 # A frozenset() of AttributeUse instances.
1726 __attributeUses = None
1730
1731 # A map from NCNames to AttributeDeclaration instances that are
1732 # local to this type.
1733 __scopedAttributeDeclarations = None
1735 """Find an attribute declaration with the given name that is local to this type.
1736
1737 Returns None if there is no such local attribute declaration."""
1738 if self.__scopedAttributeDeclarations is None:
1739 return None
1740 return self.__scopedAttributeDeclarations.get(expanded_name)
1741
1742 # A map from NCNames to ElementDeclaration instances that are
1743 # local to this type.
1744 __scopedElementDeclarations = None
1746 """Find an element declaration with the given name that is local to this type.
1747
1748 Returns None if there is no such local element declaration."""
1749 if self.__scopedElementDeclarations is None:
1750 return None
1751 return self.__scopedElementDeclarations.get(expanded_name)
1752
1753 __localScopedDeclarations = None
1755 """Return a list of element and attribute declarations that were
1756 introduced in this definition (i.e., their scope is this CTD).
1757
1758 @note: This specifically returns a list, with element declarations
1759 first, because name binding should privilege the elements over the
1760 attributes. Within elements and attributes, the components are sorted
1761 by expanded name, to ensure consistency across a series of binding
1762 generations.
1763
1764 @keyword reset: If C{False} (default), a cached previous value (if it
1765 exists) will be returned.
1766 """
1767 if reset or (self.__localScopedDeclarations is None):
1768 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ]
1769 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1770 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ]
1771 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName()))
1772 self.__localScopedDeclarations = rve
1773 self.__localScopedDeclarations.extend(rva)
1774 return self.__localScopedDeclarations
1775
1777 """Record the given declaration as being locally scoped in
1778 this type."""
1779 assert isinstance(decl, _ScopedDeclaration_mixin)
1780 if isinstance(decl, ElementDeclaration):
1781 scope_map = self.__scopedElementDeclarations
1782 elif isinstance(decl, AttributeDeclaration):
1783 scope_map = self.__scopedAttributeDeclarations
1784 else:
1785 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),))
1786 decl_en = decl.expandedName()
1787 existing_decl = scope_map.setdefault(decl_en, decl)
1788 if decl != existing_decl:
1789 if isinstance(decl, ElementDeclaration):
1790 # Test cos-element-consistent
1791 existing_type = existing_decl.typeDefinition()
1792 pending_type = decl.typeDefinition()
1793 if not pending_type.isDerivationConsistent(existing_type):
1794 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type))
1795 elif isinstance(decl, AttributeDeclaration):
1796 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),))
1797 else:
1798 assert False, 'Unrecognized type %s' % (type(decl),)
1799 decl._baseDeclaration(existing_decl)
1800 return self
1801
1803 """Return C{True} iff this is the root of a complex type definition hierarchy.
1804 """
1805 base = self.__baseTypeDefinition
1806 return isinstance(base, SimpleTypeDefinition) or base.isUrTypeDefinition()
1807
1808 CT_EMPTY = 'EMPTY' #<<< No content
1809 CT_SIMPLE = 'SIMPLE' #<<< Simple (character) content
1810 CT_MIXED = 'MIXED' #<<< Children may be elements or other (e.g., character) content
1811 CT_ELEMENT_ONLY = 'ELEMENT_ONLY' #<<< Expect only element content.
1812
1814 """Return the value of the content type identifier, i.e. one of the
1815 CT_ constants. Return value is None if no content type has been
1816 defined."""
1817 if isinstance(self.__contentType, tuple):
1818 return self.__contentType[0]
1819 return self.__contentType
1820
1825
1826 # Identify the sort of content in this type.
1827 __contentType = None
1829 """Identify the sort of content in this type.
1830
1831 Valid values are:
1832 - C{CT_EMPTY}
1833 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance )
1834 - ( C{CT_MIXED}, a L{Particle} instance )
1835 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance )
1836 """
1837 return self.__contentType
1838
1840 if self.CT_EMPTY == self.contentType():
1841 return 'EMPTY'
1842 ( tag, particle ) = self.contentType()
1843 if self.CT_SIMPLE == tag:
1844 return 'Simple [%s]' % (particle,)
1845 if self.CT_MIXED == tag:
1846 return 'Mixed [%s]' % (particle,)
1847 if self.CT_ELEMENT_ONLY == tag:
1848 return 'Element [%s]' % (particle,)
1849 raise pyxb.LogicError('Unhandled content type')
1850
1851 # Derived from the block and blockDefault attributes
1852 __prohibitedSubstitutions = DM_empty
1853
1854 # @todo: Extracted from children of various types
1855 __annotations = None
1856
1858 super(ComplexTypeDefinition, self).__init__(*args, **kw)
1859 self.__derivationMethod = kw.get('derivation_method')
1860 self.__scopedElementDeclarations = { }
1861 self.__scopedAttributeDeclarations = { }
1862
1864 """Return True iff this type includes a wildcard element in
1865 its content model."""
1866 if self.CT_EMPTY == self.contentType():
1867 return False
1868 ( tag, particle ) = self.contentType()
1869 if self.CT_SIMPLE == tag:
1870 return False
1871 return particle.hasWildcardElement()
1872
1874 """Override fields in this instance with those from the other.
1875
1876 This method is invoked only by Schema._addNamedComponent, and
1877 then only when a built-in type collides with a schema-defined
1878 type. Material like facets is not (currently) held in the
1879 built-in copy, so the DOM information is copied over to the
1880 built-in STD, which is subsequently re-resolved.
1881
1882 Returns self.
1883 """
1884 assert self != other
1885 assert self.isNameEquivalent(other)
1886 super(ComplexTypeDefinition, self)._updateFromOther_csc(other)
1887
1888 if not other.isResolved():
1889 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID():
1890 self.__derivationMethod = None
1891
1892 return self
1893
1894 __UrTypeDefinition = None
1895 @classmethod
1897 """Create the ComplexTypeDefinition instance that approximates
1898 the ur-type.
1899
1900 See section 3.4.7.
1901 """
1902
1903 # The first time, and only the first time, this is called, a
1904 # namespace should be provided which is the XMLSchema
1905 # namespace for this run of the system. Please, do not try to
1906 # allow this by clearing the type definition.
1907 #if in_builtin_definition and (cls.__UrTypeDefinition is not None):
1908 # raise pyxb.LogicError('Multiple definitions of UrType')
1909 if cls.__UrTypeDefinition is None:
1910 # NOTE: We use a singleton subclass of this class
1911 assert schema is not None
1912
1913 ns_ctx = schema.targetNamespace().initialNamespaceContext()
1914
1915 kw = { 'name' : 'anyType',
1916 'schema' : schema,
1917 'namespace_context' : ns_ctx,
1918 'binding_namespace' : schema.targetNamespace(),
1919 'derivation_method' : cls.DM_restriction,
1920 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
1921 bi = _UrTypeDefinition(**kw)
1922
1923 # The ur-type is its own baseTypeDefinition
1924 bi.__baseTypeDefinition = bi
1925
1926 # No constraints on attributes
1927 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw))
1928
1929 # There isn't anything to look up, but context is still global.
1930 # No declarations will be created, so use indeterminate scope to
1931 # be consistent with validity checks in Particle constructor.
1932 # Content is mixed, with elements completely unconstrained. @todo:
1933 # not associated with a schema (it should be)
1934 kw = { 'namespace_context' : ns_ctx
1935 , 'schema' : schema
1936 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate }
1937 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)
1938 p = Particle(w, min_occurs=0, max_occurs=None, **kw)
1939 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw)
1940 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) )
1941
1942 # No attribute uses
1943 bi.__attributeUses = set()
1944
1945 # No constraints on extension or substitution
1946 bi.__final = cls.DM_empty
1947 bi.__prohibitedSubstitutions = cls.DM_empty
1948
1949 bi.__abstract = False
1950
1951 # Refer to it by name
1952 bi.setNameInBinding(bi.name())
1953
1954 # The ur-type is always resolved
1955 bi.__derivationMethod = cls.DM_restriction
1956
1957 cls.__UrTypeDefinition = bi
1958 return cls.__UrTypeDefinition
1959
1961 """Indicate whether this simple type is a built-in type."""
1962 return (self.UrTypeDefinition() == self)
1963
1964 # bR:CTD
1966 """Complex type definitions depend on their base type definition, the
1967 type definitions of any local attribute declarations, and if strict
1968 the type definitions of any local element declarations."""
1969 rv = set()
1970 assert self.__baseTypeDefinition is not None
1971 rv.add(self.__baseTypeDefinition)
1972 for decl in self.localScopedDeclarations():
1973 if include_lax or isinstance(decl, AttributeDeclaration):
1974 rv.add(decl.typeDefinition())
1975 if include_lax:
1976 ct = self._contentTypeComponent()
1977 if ct is not None:
1978 rv.add(ct)
1979 return frozenset(rv)
1980
1981 # CFD:CTD CFD:ComplexTypeDefinition
1982 @classmethod
1984 # Node should be an XMLSchema complexType node
1985 assert xsd.nodeIsNamed(node, 'complexType')
1986
1987 name = domutils.NodeAttribute(node, 'name')
1988
1989 rv = cls(name=name, node=node, derivation_method=None, **kw)
1990
1991 if name is None:
1992 assert not isinstance(rv.owner(), Schema)
1993
1994 # Most of the time, the scope will be global. It can be something
1995 # else only if this is an anonymous CTD (created within an element
1996 # declaration which itself may be global, in a containing CTD, or in a
1997 # model group).
1998 if not (rv._scopeIsGlobal() or rv.isAnonymous()):
1999 raise pyxb.LogicError('Attempt to create non-global complex type definition')
2000
2001 kw.pop('node', None)
2002 kw['owner'] = rv
2003 kw['scope'] = rv
2004
2005 return rv.__setContentFromDOM(node, **kw)
2006
2007 __baseAttribute = None
2008
2009
2010 __ckw = None
2011 __anyAttribute = None
2012 __attributeGroupAttributes = None
2013 __usesC1 = None
2014 __usesC1C2 = None
2015 __attributeGroups = None
2016 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ])
2017
2018 # Handle attributeUses, attributeWildcard, contentType
2020
2021 if self.__usesC1C2 is None:
2022 # Handle clauses 1 and 2 (common between simple and complex types)
2023 uses_c1 = self.__usesC1 # attribute children
2024 uses_c2 = set() # attribute group children
2025 self.__attributeGroups = []
2026 for ag_attr in self.__attributeGroupAttributes:
2027 ag_en = self._namespaceContext().interpretQName(ag_attr)
2028 agd = ag_en.attributeGroupDefinition()
2029 if agd is None:
2030 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2031 if not agd.isResolved():
2032 self._queueForResolution('unresolved attribute group', depends_on=agd)
2033 return self
2034 self.__attributeGroups.append(agd)
2035 uses_c2.update(agd.attributeUses())
2036
2037 uses_c1c2 = uses_c1.union(uses_c2)
2038 for au in uses_c1c2:
2039 if not au.isResolved():
2040 self._queueForResolution('attribute use not resolved')
2041 return self
2042 ad = au.attributeDeclaration()
2043 if not ad.isResolved():
2044 ad_en = ad.expandedName()
2045 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2046 return self
2047
2048 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ])
2049
2050 # Handle clause 3. Note the slight difference in description between
2051 # simple and complex content is just that the complex content doesn't
2052 # bother to check that the base type definition is a complex type
2053 # definition. So the same code should work for both, and we don't
2054 # bother to check content_style.
2055 uses_c3 = set() # base attributes
2056 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2057 # NB: The base type definition should be resolved, which means
2058 # that all its attribute uses have been adapted for scope already
2059 uses_c3 = set(self.__baseTypeDefinition.__attributeUses)
2060 assert self.__baseTypeDefinition.isResolved()
2061 for au in uses_c3:
2062 if not au.isResolved():
2063 self._queueForResolution('unresolved attribute use from base type', depends_on=au)
2064 return self
2065 ad = au.attributeDeclaration()
2066 if not ad.isResolved():
2067 ad_en = ad.expandedName()
2068 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,), depends_on=ad)
2069 return self
2070 assert not au.attributeDeclaration()._scopeIsIndeterminate()
2071
2072 if self.DM_restriction == method:
2073 # Exclude attributes per clause 3. Note that this process
2074 # handles both 3.1 and 3.2, since we have not yet filtered
2075 # uses_c1 for prohibited attributes.
2076 for au in self.__usesC1C2:
2077 matching_uses = au.matchingQNameMembers(uses_c3)
2078 assert matching_uses is not None
2079 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s'
2080 for au2 in matching_uses:
2081 assert au2.isResolved()
2082 uses_c3.remove(au2)
2083 au._setRestrictionOf(au2)
2084 else:
2085 # In theory, the same attribute name can't appear in the base
2086 # and sub types because that would violate the local
2087 # declaration constraint.
2088 assert self.DM_extension == method
2089
2090 use_map = { }
2091 for au in self.__usesC1C2.union(uses_c3):
2092 assert au.isResolved()
2093 ad_en = au.attributeDeclaration().expandedName()
2094 if ad_en in use_map:
2095 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName()))
2096 use_map[ad_en] = au
2097
2098 # Past the last point where we might not resolve this instance. Store
2099 # the attribute uses, also recording local attribute declarations.
2100 self.__attributeUses = frozenset(use_map.values())
2101 if not self._scopeIsIndeterminate():
2102 for au in self.__attributeUses:
2103 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,)
2104
2105 # @todo: Handle attributeWildcard
2106 # Clause 1
2107 local_wildcard = None
2108 if self.__anyAttribute is not None:
2109 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2110
2111 # Clause 2
2112 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard)
2113
2114 # Clause 3
2115 if self.DM_restriction == method:
2116 # Clause 3.1
2117 self._setAttributeWildcard(complete_wildcard)
2118 else:
2119 assert (self.DM_extension == method)
2120 assert self.baseTypeDefinition().isResolved()
2121 # 3.2.1
2122 base_wildcard = None
2123 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition):
2124 base_wildcard = self.baseTypeDefinition().attributeWildcard()
2125 # 3.2.2
2126 if base_wildcard is not None:
2127 if complete_wildcard is None:
2128 # 3.2.2.1.1
2129 self._setAttributeWildcard(base_wildcard)
2130 else:
2131 # 3.2.2.1.2
2132 self._setAttributeWildcard(Wildcard (process_contents=complete_wildcard.processContents(),
2133 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(),
2134 base_wildcard.namespaceConstraint()]),
2135 annotation=complete_wildcard.annotation(),
2136 namespace_context=self._namespaceContext()))
2137 else:
2138 # 3.2.2.2
2139 self._setAttributeWildcard(complete_wildcard)
2140
2141 # @todo: Make sure we didn't miss any child nodes
2142
2143 # Remove local attributes we will never use again
2144 del self.__usesC1
2145 del self.__usesC1C2
2146 del self.__attributeGroups
2147 self.__ckw = None
2148
2149 # Only now that we've succeeded do we store the method, which
2150 # marks this component resolved.
2151
2152 self.__derivationMethod = method
2153 return self
2154
2156 # Do content type
2157 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition):
2158 # Clauses 1, 2, and 3 might apply
2159 parent_content_type = self.__baseTypeDefinition.__contentType
2160 if ((type(parent_content_type) == tuple) \
2161 and (self.CT_SIMPLE == parent_content_type[0]) \
2162 and (self.DM_restriction == method)):
2163 # Clause 1
2164 assert self.__ctscRestrictionNode is not None
2165 std = self.__ctscClause2STD
2166 if std is None:
2167 std = parent_content_type[1]
2168 assert isinstance(std, SimpleTypeDefinition)
2169 if not std.isResolved():
2170 return None
2171 restriction_node = self.__ctscRestrictionNode
2172 self.__ctscClause2STD = None
2173 self.__ctscRestrictionNode = None
2174 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) )
2175 if ((type(parent_content_type) == tuple) \
2176 and (self.CT_MIXED == parent_content_type[0]) \
2177 and parent_content_type[1].isEmptiable()):
2178 # Clause 2
2179 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition)
2180 return ( self.CT_SIMPLE, self.__ctscClause2STD )
2181 # Clause 3
2182 return parent_content_type
2183 # Clause 4
2184 return ( self.CT_SIMPLE, self.__baseTypeDefinition )
2185
2186 __ctscClause2STD = None
2187 __ctscRestrictionNode = None
2188 __effectiveMixed = None
2189 __effectiveContent = None
2190 __pendingDerivationMethod = None
2191 __isComplexContent = None
2192 __ctscRestrictionMode = None
2193 __contentStyle = None
2194
2195 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2196 # Do content type. Cache the keywords that need to be used
2197 # for newly created schema components.
2198 ckw = kw.copy()
2199 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node)
2200
2201 # Definition 1: effective mixed
2202 mixed_attr = None
2203 if content_node is not None:
2204 mixed_attr = domutils.NodeAttribute(content_node, 'mixed')
2205 if mixed_attr is None:
2206 mixed_attr = domutils.NodeAttribute(type_node, 'mixed')
2207 if mixed_attr is not None:
2208 effective_mixed = datatypes.boolean(mixed_attr)
2209 else:
2210 effective_mixed = False
2211
2212 # Definition 2: effective content
2213 test_2_1_1 = True
2214 test_2_1_2 = False
2215 test_2_1_3 = False
2216 typedef_node = None
2217 for cn in definition_node_list:
2218 if Node.ELEMENT_NODE != cn.nodeType:
2219 continue
2220 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'):
2221 # Should have found the content node earlier.
2222 raise pyxb.LogicError('Missed explicit wrapper in complexType content')
2223 if Particle.IsTypedefNode(cn):
2224 typedef_node = cn
2225 test_2_1_1 = False
2226 if xsd.nodeIsNamed(cn, 'all', 'sequence') \
2227 and (not domutils.HasNonAnnotationChild(cn)):
2228 test_2_1_2 = True
2229 if xsd.nodeIsNamed(cn, 'choice') \
2230 and (not domutils.HasNonAnnotationChild(cn)):
2231 mo_attr = domutils.NodeAttribute(cn, 'minOccurs')
2232 if ((mo_attr is not None) \
2233 and (0 == datatypes.integer(mo_attr))):
2234 test_2_1_3 = True
2235 satisfied_predicates = 0
2236 if test_2_1_1:
2237 satisfied_predicates += 1
2238 if test_2_1_2:
2239 satisfied_predicates += 1
2240 if test_2_1_3:
2241 satisfied_predicates += 1
2242 if 1 == satisfied_predicates:
2243 if effective_mixed:
2244 # Clause 2.1.4
2245 assert (typedef_node is None) or test_2_1_2
2246 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw)
2247 effective_content = Particle(m, **ckw)
2248 else:
2249 # Clause 2.1.5
2250 effective_content = self.CT_EMPTY
2251 else:
2252 # Clause 2.2
2253 assert typedef_node is not None
2254 effective_content = Particle.CreateFromDOM(typedef_node, **kw)
2255
2256 # For issues related to soapenc:Array and the fact that PyXB
2257 # determines the content of types derived from it is empty, see
2258 # http://tech.groups.yahoo.com/group/soapbuilders/message/5879 and
2259 # lament the fact that the WSDL spec is not compatible with XSD. It
2260 # is *not* an error in PyXB.
2261
2262 self.__effectiveMixed = effective_mixed
2263 self.__effectiveContent = effective_content
2264 self.__ckw = ckw
2265
2267 ckw = self.__ckw
2268
2269 # Shared from clause 3.1.2
2270 if self.__effectiveMixed:
2271 ct = self.CT_MIXED
2272 else:
2273 ct = self.CT_ELEMENT_ONLY
2274 # Clause 3
2275 if self.DM_restriction == method:
2276 # Clause 3.1
2277 if self.CT_EMPTY == self.__effectiveContent:
2278 # Clause 3.1.1
2279 content_type = self.CT_EMPTY # ASSIGN CT_EMPTY
2280 else:
2281 # Clause 3.1.2(.2)
2282 content_type = ( ct, self.__effectiveContent ) # ASSIGN RESTRICTION
2283 assert 0 == len(self.__scopedElementDeclarations)
2284 # Reference the parent element declarations; normally this
2285 # would happen naturally as a consequence of appending this
2286 # type's content model to the parent's, but with restriction
2287 # there is no such re-use unless we do this.
2288 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations)
2289 else:
2290 # Clause 3.2
2291 assert self.DM_extension == method
2292 assert self.__baseTypeDefinition.isResolved()
2293 parent_content_type = self.__baseTypeDefinition.contentType()
2294 if self.CT_EMPTY == self.__effectiveContent:
2295 content_type = parent_content_type # ASSIGN EXTENSION PARENT ONLY
2296 elif self.CT_EMPTY == parent_content_type:
2297 # Clause 3.2.2
2298 content_type = ( ct, self.__effectiveContent ) # ASSIGN EXTENSION LOCAL ONLY
2299 else:
2300 assert type(parent_content_type) == tuple
2301 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw)
2302 content_type = ( ct, Particle(m, **ckw) ) # ASSIGN EXTENSION PARENT AND LOCAL
2303
2304 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None))
2305 return content_type
2306
2308 """Indicate whether this complex type is fully defined.
2309
2310 All built-in type definitions are resolved upon creation.
2311 Schema-defined type definitionss are held unresolved until the
2312 schema has been completely read, so that references to later
2313 schema-defined types can be resolved. Resolution is performed
2314 after the entire schema has been scanned and type-definition
2315 instances created for all topLevel{Simple,Complex}Types.
2316
2317 If a built-in type definition is also defined in a schema
2318 (which it should be), the built-in definition is kept, with
2319 the schema-related information copied over from the matching
2320 schema-defined type definition. The former then replaces the
2321 latter in the list of type definitions to be resolved. See
2322 Schema._addNamedComponent.
2323 """
2324 # Only unresolved nodes have an unset derivationMethod
2325 return (self.__derivationMethod is not None)
2326
2327 # Back door to allow the ur-type to re-resolve itself. Only needed when
2328 # we're generating bindings for XMLSchema itself.
2332
2334 schema = kw.get('schema')
2335 assert schema is not None
2336 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map)
2337 self.__final = schema.finalForNode(node, self._DM_Map)
2338
2339 attr_val = domutils.NodeAttribute(node, 'abstract')
2340 if attr_val is not None:
2341 self.__abstract = datatypes.boolean(attr_val)
2342
2343 # Assume we're in the short-hand case: the entire content is
2344 # implicitly wrapped in a complex restriction of the ur-type.
2345 definition_node_list = node.childNodes
2346 is_complex_content = True
2347 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
2348 method = self.DM_restriction
2349
2350 # Determine whether above assumption is correct by looking for
2351 # element content and seeing if it's one of the wrapper
2352 # elements.
2353 first_elt = domutils.LocateFirstChildElement(node)
2354 content_node = None
2355 clause2_std = None
2356 ctsc_restriction_node = None
2357 if first_elt:
2358 have_content = False
2359 if xsd.nodeIsNamed(first_elt, 'simpleContent'):
2360 have_content = True
2361 is_complex_content = False
2362 elif xsd.nodeIsNamed(first_elt, 'complexContent'):
2363 have_content = True
2364 else:
2365 # Not one of the wrappers; use implicit wrapper around
2366 # the children
2367 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'):
2368 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,))
2369 if have_content:
2370 # Repeat the search to verify that only the one child is present.
2371 content_node = domutils.LocateFirstChildElement(node, require_unique=True)
2372 assert content_node == first_elt
2373
2374 # Identify the contained restriction or extension
2375 # element, and extract the base type.
2376 ions = domutils.LocateFirstChildElement(content_node, absent_ok=False)
2377 if xsd.nodeIsNamed(ions, 'restriction'):
2378 method = self.DM_restriction
2379 if not is_complex_content:
2380 # Clause 2 of complex type with simple content
2381 ctsc_restriction_node = ions
2382 ions_st = domutils.LocateUniqueChild(ions,'simpleType')
2383 if ions_st is not None:
2384 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw)
2385 elif xsd.nodeIsNamed(ions, 'extension'):
2386 method = self.DM_extension
2387 else:
2388 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name()))
2389 self.__baseAttribute = domutils.NodeAttribute(ions, 'base')
2390 if self.__baseAttribute is None:
2391 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,))
2392 self.__baseTypeDefinition = None
2393 # The content is defined by the restriction/extension element
2394 definition_node_list = ions.childNodes
2395 # deriviationMethod is assigned after resolution completes
2396 self.__pendingDerivationMethod = method
2397 self.__isComplexContent = is_complex_content
2398 self.__ctscRestrictionNode = ctsc_restriction_node
2399 self.__ctscClause2STD = clause2_std
2400
2401 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list)
2402 self.__usesC1 = set()
2403 for cn in attributes:
2404 au = AttributeUse.CreateFromDOM(cn, **kw)
2405 self.__usesC1.add(au)
2406 self.__attributeGroupAttributes = attribute_group_attrs
2407 self.__anyAttribute = any_attribute
2408
2409 if self.__isComplexContent:
2410 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw)
2411
2412 # Creation does not attempt to do resolution. Queue up the newly created
2413 # whatsis so we can resolve it after everything's been read in.
2414 self._annotationFromDOM(node)
2415
2416 if not self.isResolved():
2417 self._queueForResolution('creation')
2418
2419 return self
2420
2421 # Resolution of a CTD can be delayed for the following reasons:
2422 #
2423 # * It extends or restricts a base type that has not been resolved
2424 # [_resolve]
2425 #
2426 # * It refers to an attribute or attribute group that has not been
2427 # resolved [__completeProcessing]
2428 #
2429 # * It includes an attribute that matches in NCName and namespace
2430 # an unresolved attribute from the base type
2431 # [__completeProcessing]
2432 #
2433 # * The content model includes a particle which cannot be resolved
2434 # (so has not contributed any local element declarations).
2435 # res:CTD
2437 if self.isResolved():
2438 return self
2439
2440 # @todo: implement prohibitedSubstitutions, final, annotations
2441
2442 # See whether we've resolved through to the base type
2443 if self.__baseTypeDefinition is None:
2444 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
2445 base_type = base_en.typeDefinition()
2446 if base_type is None:
2447 raise pyxb.SchemaValidationError('Cannot locate %s: need import?' % (base_en,))
2448 if not base_type.isResolved():
2449 # Have to delay resolution until the type this
2450 # depends on is available.
2451 self._queueForResolution('unresolved base type %s' % (base_en,), depends_on=base_type)
2452 return self
2453 self.__baseTypeDefinition = base_type
2454
2455 # Only build the content once. This will not complete if the content
2456 # is a restriction of an unresolved simple type; otherwise, it only
2457 # depends on the base type which we know is good.
2458 if self.__contentType is None:
2459 if self.__isComplexContent:
2460 content_type = self.__complexContent(self.__pendingDerivationMethod)
2461 self.__contentStyle = 'complex'
2462 else:
2463 # The definition node list is not relevant to simple content
2464 content_type = self.__simpleContent(self.__pendingDerivationMethod)
2465 if content_type is None:
2466 self._queueForResolution('restriction of unresolved simple type')
2467 return self
2468 self.__contentStyle = 'simple'
2469 assert content_type is not None
2470 self.__contentType = content_type
2471
2472 # Last chance for failure is if we haven't been able to
2473 # extract all the element declarations that might appear in
2474 # this complex type. That technically wouldn't stop this from
2475 # being resolved, but it does prevent us from using it as a
2476 # context.
2477 if isinstance(self.__contentType, tuple) and isinstance(self.__contentType[1], Particle):
2478 prt = self.__contentType[1]
2479 if not prt.isAdaptable(self):
2480 self._queueForResolution('content particle %s is not deep-resolved' % (prt,))
2481 return self
2482 self.__contentType = (self.__contentType[0], prt._adaptForScope(self, self))
2483
2484 return self.__completeProcessing(self.__pendingDerivationMethod, self.__contentStyle)
2485
2489
2491 if self.isAnonymous():
2492 return 'CTD{Anonymous}[%x]' % (id(self),)
2493 return 'CTD[%s]' % (self.expandedName(),)
2494
2496 """Subclass ensures there is only one ur-type."""
2500
2502 # The ur type is always resolved, except when it gets unresolved
2503 # through being updated from an instance read from the schema.
2504 return self._setDerivationMethod(self.DM_restriction)
2505
2506
2507 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2508 """An XMLSchema U{Attribute Group Definition<http://www.w3.org/TR/xmlschema-1/#cAttribute_Group_Definitions>} component."""
2509 __PrivateTransient = set()
2510
2511 # A frozenset of AttributeUse instances
2512 __attributeUses = None
2513
2516 #assert 'scope' in kw
2517 #assert self._scopeIsIndeterminate()
2518
2520 return 'AGD[%s]' % (self.expandedName(),)
2521
2522 @classmethod
2524 """Create an attribute declaration component for a specified namespace."""
2525 kw = { 'name' : name,
2526 'schema' : schema,
2527 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
2528 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
2529 bi = cls(**kw)
2530 bi.__attributeUses = frozenset(attribute_uses)
2531 bi.__isResolved = True
2532 return bi
2533
2534 __anyAttribute = None
2535 __attributeGroupAttributes = None
2536 __refAttribute = None
2537 __PrivateTransient.update(['anyAttribute', 'attributeGroupAttributes'])
2538
2539
2540 # CFD:AGD CFD:AttributeGroupDefinition
2541 @classmethod
2543 """Create an attribute group definition from the given DOM node.
2544
2545 """
2546
2547 assert xsd.nodeIsNamed(node, 'attributeGroup')
2548 name = domutils.NodeAttribute(node, 'name')
2549
2550 # Attribute group definitions can only appear at the top level of the
2551 # schema, and any definitions in them are scope indeterminate until
2552 # they're referenced in a complex type.
2553 kw.update({ 'scope' : _ScopedDeclaration_mixin.XSCOPE_indeterminate })
2554 rv = cls(name=name, node=node, **kw)
2555
2556 rv._annotationFromDOM(node)
2557
2558 # Attribute group definitions must not be references
2559 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
2560 if rv.__refAttribute is not None:
2561 raise pyxb.SchemaValidationError('Attribute reference at top level')
2562
2563 kw.pop('node', None)
2564 kw['owner'] = rv
2565
2566 (attributes, attribute_group_attrs, any_attribute) = rv._attributeRelevantChildren(node.childNodes)
2567 rv.__attributeUses = set()
2568 for cn in attributes:
2569 rv.__attributeUses.add(AttributeUse.CreateFromDOM(cn, **kw))
2570 rv.__attributeGroupAttributes = attribute_group_attrs
2571 rv.__anyAttribute = any_attribute
2572
2573 # Unconditionally queue for resolution, to avoid repeating the
2574 # wildcard code.
2575 rv._queueForResolution('creation')
2576
2577 return rv
2578
2579 # Indicates whether we have resolved any references
2580 __isResolved = False
2582 return self.__isResolved
2583
2585 if self.__isResolved:
2586 return self
2587
2588 uses = self.__attributeUses
2589 attribute_groups = []
2590 for ag_attr in self.__attributeGroupAttributes:
2591 ag_en = self._namespaceContext().interpretQName(ag_attr)
2592 agd = ag_en.attributeGroupDefinition()
2593 if agd is None:
2594 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,))
2595 attribute_groups.append(agd)
2596 uses = uses.union(agd.attributeUses())
2597
2598 self.__attributeUses = frozenset(uses)
2599
2600 # "Complete wildcard" per CTD
2601 local_wildcard = None
2602 if self.__anyAttribute is not None:
2603 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute)
2604 self._setAttributeWildcard(_AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), attribute_groups, local_wildcard))
2605
2606 self.__isResolved = True
2607 return self
2608
2609 # bR:AGD
2611 """Attribute group declarations require their uses, but only if lax."""
2612 if not include_lax:
2613 return frozenset()
2614 return frozenset(self.attributeUses())
2615
2617 return self.__attributeUses
2618
2620 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component."""
2621 # Reference to a _ModelGroup
2622 __modelGroup = None
2623
2627
2628 # CFD:MGD CFD:ModelGroupDefinition
2629 @classmethod
2631 """Create a Model Group Definition from a DOM element node.
2632
2633 wxs is a Schema instance within which the model group is being
2634 defined.
2635
2636 node is a DOM element. The name must be 'group', and the node
2637 must be in the XMLSchema namespace. The node must have a
2638 'name' attribute, and must not have a 'ref' attribute.
2639 """
2640 assert xsd.nodeIsNamed(node, 'group')
2641
2642 assert domutils.NodeAttribute(node, 'ref') is None
2643
2644 name = domutils.NodeAttribute(node, 'name')
2645 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate
2646 rv = cls(name=name, node=node, **kw)
2647 rv._annotationFromDOM(node)
2648
2649 kw.pop('node', None)
2650 kw['owner'] = rv
2651
2652 for cn in node.childNodes:
2653 if Node.ELEMENT_NODE != cn.nodeType:
2654 continue
2655 if ModelGroup.IsGroupMemberNode(cn):
2656 assert not rv.__modelGroup
2657 # Model group definitions always occur at the top level of the
2658 # schema, so the elements declared in them are not bound to a
2659 # scope until they are referenced in a complex type.
2660 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw)
2661 assert rv.__modelGroup is not None
2662 return rv
2663
2664 # bR:MGD
2666 """Model group definitions depend on the contained model group."""
2667 if not include_lax:
2668 return frozenset()
2669 return frozenset([self.__modelGroup])
2670
2673
2676 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component."""
2677 C_INVALID = 0
2678 C_ALL = 0x01
2679 C_CHOICE = 0x02
2680 C_SEQUENCE = 0x03
2681
2682 # One of the C_* values above. Set at construction time from the
2683 # keyword parameter "compositor".
2684 __compositor = C_INVALID
2686 return self.__compositor
2687
2688 @classmethod
2690 """Map a compositor value to a string."""
2691 if cls.C_ALL == compositor:
2692 return 'all'
2693 if cls.C_CHOICE == compositor:
2694 return 'choice'
2695 if cls.C_SEQUENCE == compositor:
2696 return 'sequence'
2697 return 'invalid'
2698
2700 """Return a string representing the compositor value."""
2701 return self.CompositorToString(self.__compositor)
2702
2703 # A list of Particle instances. Set at construction time from
2704 # the keyword parameter "particles".
2705 __particles = None
2707 return self.__particles
2708
2710 """A model group has an unresolvable particle if any of its
2711 particles is unresolvable. Duh."""
2712 for p in self.particles():
2713 if not p.isAdaptable(ctd):
2714 return False
2715 return True
2716
2718 """Return the minimum and maximum of the number of elements that can
2719 appear in a sequence matched by this particle.
2720
2721 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range}
2722 """
2723 if self.__compositor in (self.C_ALL, self.C_SEQUENCE):
2724 sum_minoccurs = 0
2725 sum_maxoccurs = 0
2726 for prt in self.__particles:
2727 (prt_min, prt_max) = prt.effectiveTotalRange()
2728 sum_minoccurs += prt_min
2729 if sum_maxoccurs is not None:
2730 if prt_max is None:
2731 sum_maxoccurs = None
2732 else:
2733 sum_maxoccurs += prt_max
2734 prod_maxoccurs = particle.maxOccurs()
2735 if prod_maxoccurs is not None:
2736 if sum_maxoccurs is None:
2737 prod_maxoccurs = None
2738 else:
2739 prod_maxoccurs *= sum_maxoccurs
2740 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs)
2741 assert self.__compositor == self.C_CHOICE
2742 if 0 == len(self.__particles):
2743 min_minoccurs = 0
2744 max_maxoccurs = 0
2745 else:
2746 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange()
2747 for prt in self.__particles[1:]:
2748 (prt_min, prt_max) = prt.effectiveTotalRange()
2749 if prt_min < min_minoccurs:
2750 min_minoccurs = prt_min
2751 if prt_max is None:
2752 max_maxoccurs = None
2753 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs):
2754 max_maxoccurs = prt_max
2755 min_minoccurs *= particle.minOccurs()
2756 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None):
2757 max_maxoccurs *= particle.maxOccurs()
2758 return (min_minoccurs, max_maxoccurs)
2759
2760 # The ModelGroupDefinition that names this ModelGroup, or None if
2761 # the ModelGroup is anonymous. This is set at construction time
2762 # from the keyword parameter "model_group_definition".
2763 __modelGroupDefinition = None
2765 """The ModelGroupDefinition that names this group, or None if it is unnamed."""
2766 return self.__modelGroupDefinition
2767
2769 """Create a new model group.
2770
2771 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE).
2772
2773 particles must be a list of zero or more Particle instances.
2774
2775 scope is the _ScopeDeclaration_mixin context into which new
2776 declarations are recorded. It can be SCOPE_global, a complex
2777 type definition, or None if this is (or is within) a named
2778 model group.
2779
2780 model_group_definition is an instance of ModelGroupDefinition
2781 if this is a named model group. It defaults to None
2782 indicating a local group.
2783 """
2784
2785 super(ModelGroup, self).__init__(*args, **kw)
2786 assert 'scope' in kw
2787 self.__compositor = compositor
2788 self.__particles = particles
2789 self.__modelGroupDefinition = kw.get('model_group_definition')
2790
2792 """Return True if the model includes a wildcard amongst its particles."""
2793 for p in self.particles():
2794 if p.hasWildcardElement():
2795 return True
2796 return False
2797
2798 # bR:MG
2803
2804 # CFD:MG CFD:ModelGroup
2805 @classmethod
2807 """Create a model group from the given DOM node.
2808
2809 wxs is a Schema instance within which the model group is being
2810 defined.
2811
2812 node is a DOM element. The name must be one of ( 'all',
2813 'choice', 'sequence' ), and the node must be in the XMLSchema
2814 namespace.
2815
2816 scope is the _ScopeDeclaration_mxin context that is assigned
2817 to declarations that appear within the model group. It can be
2818 None, indicating no scope defined, or a complex type
2819 definition.
2820 """
2821
2822 scope = kw['scope']
2823 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
2824
2825 if xsd.nodeIsNamed(node, 'all'):
2826 compositor = cls.C_ALL
2827 elif xsd.nodeIsNamed(node, 'choice'):
2828 compositor = cls.C_CHOICE
2829 else:
2830 assert xsd.nodeIsNamed(node, 'sequence')
2831 compositor = cls.C_SEQUENCE
2832 particles = []
2833 # Remove the owner from particle constructor arguments: we need to set it later
2834 kw.pop('owner', None)
2835 for cn in node.childNodes:
2836 if Node.ELEMENT_NODE != cn.nodeType:
2837 continue
2838 if Particle.IsParticleNode(cn):
2839 # NB: Ancestor of particle is set in the ModelGroup constructor
2840 particles.append(Particle.CreateFromDOM(node=cn, **kw))
2841 elif not xsd.nodeIsNamed(cn, 'annotation'):
2842 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,))
2843 rv = cls(compositor, particles, node=node, **kw)
2844 for p in particles:
2845 p._setOwner(rv)
2846 rv._annotationFromDOM(node)
2847 return rv
2848
2849 @classmethod
2852
2853 # aFS:MG
2855 rv = self
2856 assert isinstance(ctd, ComplexTypeDefinition)
2857 maybe_rv = self._clone(owner, ctd._objectOrigin())
2858 scoped_particles = [ _p._adaptForScope(maybe_rv, ctd) for _p in self.particles() ]
2859 do_clone = (self._scope() != ctd) or (self.particles() != scoped_particles)
2860 if do_clone:
2861 rv = maybe_rv
2862 rv.__particles = scoped_particles
2863 return rv
2864
2866 visit(self, True, arg)
2867 for p in self.particles():
2868 p._walkParticleTree(visit, arg)
2869 visit(self, False, arg)
2870
2872 comp = None
2873 if self.C_ALL == self.compositor():
2874 comp = 'ALL'
2875 elif self.C_CHOICE == self.compositor():
2876 comp = 'CHOICE'
2877 elif self.C_SEQUENCE == self.compositor():
2878 comp = 'SEQUENCE'
2879 return '%s:(%s)' % (comp, ",".join( [ str(_p) for _p in self.particles() ] ) )
2880
2881 -class Particle (_ParticleTree_mixin, _SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2882 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
2883
2884 # The minimum number of times the term may appear.
2885 __minOccurs = 1
2887 """The minimum number of times the term may appear.
2888
2889 Defaults to 1."""
2890 return self.__minOccurs
2891
2892 # Upper limit on number of times the term may appear.
2893 __maxOccurs = 1
2895 """Upper limit on number of times the term may appear.
2896
2897 If None, the term may appear any number of times; otherwise,
2898 this is an integral value indicating the maximum number of times
2899 the term may appear. The default value is 1; the value, unless
2900 None, must always be at least minOccurs().
2901 """
2902 return self.__maxOccurs
2903
2904 # A reference to a ModelGroup, WildCard, or ElementDeclaration
2905 __term = None
2909 __pendingTerm = None
2910
2911 __refAttribute = None
2912 __resolvableType = None
2913
2915 """Extend the concept of effective total range to all particles.
2916
2917 See U{http://www.w3.org/TR/xmlschema-1/#cos-seq-range} and
2918 U{http://www.w3.org/TR/xmlschema-1/#cos-choice-range}
2919 """
2920 if isinstance(self.__term, ModelGroup):
2921 return self.__term.effectiveTotalRange(self)
2922 return (self.minOccurs(), self.maxOccurs())
2923
2925 """Return C{True} iff this particle can legitimately match an empty
2926 sequence (no content).
2927
2928 See U{http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable}
2929 """
2930 return 0 == self.effectiveTotalRange()[0]
2931
2933 """Return True iff this particle has a wildcard in its term.
2934
2935 Note that the wildcard may be in a nested model group."""
2936 return self.term().hasWildcardElement()
2937
2939 """Create a particle from the given DOM node.
2940
2941 term is a XML Schema Component: one of ModelGroup,
2942 ElementDeclaration, and Wildcard.
2943
2944 The following keyword arguments are processed:
2945
2946 min_occurs is a non-negative integer value with default 1,
2947 denoting the minimum number of terms required by the content
2948 model.
2949
2950 max_occurs is a positive integer value with default 1, or None
2951 indicating unbounded, denoting the maximum number of terms
2952 allowed by the content model.
2953
2954 scope is the _ScopeDeclaration_mxin context that is assigned
2955 to declarations that appear within the particle. It can be
2956 None, indicating no scope defined, or a complex type
2957 definition.
2958 """
2959
2960 super(Particle, self).__init__(*args, **kw)
2961
2962 min_occurs = kw.get('min_occurs', 1)
2963 max_occurs = kw.get('max_occurs', 1)
2964
2965 assert 'scope' in kw
2966 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition)
2967
2968 if term is not None:
2969 self.__term = term
2970
2971 assert isinstance(min_occurs, (types.IntType, types.LongType))
2972 self.__minOccurs = min_occurs
2973 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType))
2974 self.__maxOccurs = max_occurs
2975 if self.__maxOccurs is not None:
2976 if self.__minOccurs > self.__maxOccurs:
2977 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
2978
2979 # res:Particle
2981 if self.isResolved():
2982 return self
2983
2984 # @RESOLUTION@
2985 if ModelGroup == self.__resolvableType:
2986 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
2987 group_decl = ref_en.modelGroupDefinition()
2988 if group_decl is None:
2989 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,))
2990
2991 self.__pendingTerm = group_decl.modelGroup()
2992 assert self.__pendingTerm is not None
2993 elif ElementDeclaration == self.__resolvableType:
2994 # 3.9.2 says use 3.3.2, which is Element. The element inside a
2995 # particle is a localElement, so we either get the one it refers
2996 # to (which is top-level), or create a local one here.
2997 if self.__refAttribute is not None:
2998 assert self.__pendingTerm is None
2999 ref_en = self._namespaceContext().interpretQName(self.__refAttribute)
3000 self.__pendingTerm = ref_en.elementDeclaration()
3001 if self.__pendingTerm is None:
3002 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,))
3003 assert self.__pendingTerm is not None
3004
3005 # Whether this is a local declaration or one pulled in from the
3006 # global type definition symbol space, its name is now reserved in
3007 # this type.
3008 assert self.__pendingTerm is not None
3009 else:
3010 assert False
3011
3012 self.__term = self.__pendingTerm
3013 assert self.__term is not None
3014 return self
3015
3017 return self.__term is not None
3018
3019 # CFD:Particle
3020 @classmethod
3022 """Create a particle from the given DOM node.
3023
3024 wxs is a Schema instance within which the model group is being
3025 defined.
3026
3027 node is a DOM element. The name must be one of ( 'group',
3028 'element', 'any', 'all', 'choice', 'sequence' ), and the node
3029 must be in the XMLSchema namespace.
3030
3031 scope is the _ScopeDeclaration_mxin context that is assigned
3032 to declarations that appear within the model group. It can be
3033 None, indicating no scope defined, or a complex type
3034 definition.
3035 """
3036 scope = kw['scope']
3037 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition)
3038
3039 kw.update({ 'min_occurs' : 1
3040 , 'max_occurs' : 1
3041 , 'node' : node })
3042
3043 if not Particle.IsParticleNode(node):
3044 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,))
3045 attr_val = domutils.NodeAttribute(node, 'minOccurs')
3046 if attr_val is not None:
3047 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val)
3048 attr_val = domutils.NodeAttribute(node, 'maxOccurs')
3049 if attr_val is not None:
3050 if 'unbounded' == attr_val:
3051 kw['max_occurs'] = None
3052 else:
3053 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val)
3054
3055 rv = cls(None, **kw)
3056
3057 kw.pop('node', None)
3058 kw['owner'] = rv
3059
3060 rv.__refAttribute = domutils.NodeAttribute(node, 'ref')
3061 rv.__pendingTerm = None
3062 rv.__resolvableType = None
3063 if xsd.nodeIsNamed(node, 'group'):
3064 # 3.9.2 says use 3.8.2, which is ModelGroup. The group
3065 # inside a particle is a groupRef. If there is no group
3066 # with that name, this throws an exception as expected.
3067 if rv.__refAttribute is None:
3068 raise pyxb.SchemaValidationError('group particle without reference')
3069 rv.__resolvableType = ModelGroup
3070 elif xsd.nodeIsNamed(node, 'element'):
3071 if rv.__refAttribute is None:
3072 schema = kw.get('schema')
3073 assert schema is not None
3074 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration)
3075 incoming_tns = kw.get('target_namespace')
3076 if incoming_tns is not None:
3077 assert incoming_tns == target_namespace
3078 else:
3079 kw['target_namespace'] = target_namespace
3080 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw)
3081 else:
3082 # NOTE: 3.3.3 clause 2.2 specifies that if ref is used, all
3083 # the other configuration attributes like nillable and default
3084 # must be absent. We don't even bother looking for them.
3085 rv.__resolvableType = ElementDeclaration
3086 assert not xsd.nodeIsNamed(node.parentNode, 'schema')
3087 elif xsd.nodeIsNamed(node, 'any'):
3088 # 3.9.2 says use 3.10.2, which is Wildcard.
3089 rv.__term = Wildcard.CreateFromDOM(node=node)
3090 elif ModelGroup.IsGroupMemberNode(node):
3091 # Choice, sequence, and all inside a particle are explicit
3092 # groups (or a restriction of explicit group, in the case
3093 # of all)
3094 rv.__term = ModelGroup.CreateFromDOM(node, **kw)
3095 else:
3096 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml("utf-8"),))
3097
3098 if not rv.isResolved():
3099 rv._queueForResolution('creation')
3100 return rv
3101
3102 # bR:PRT
3107
3108 # aFS:PRT
3110 rv = self
3111 assert isinstance(ctd, ComplexTypeDefinition)
3112 maybe_rv = self._clone(owner, ctd._objectOrigin())
3113 term = rv.__term._adaptForScope(maybe_rv, ctd)
3114 do_clone = (self._scope() != ctd) or (rv.__term != term)
3115 if do_clone:
3116 rv = maybe_rv
3117 rv.__term = term
3118 return rv
3119
3121 """A particle has an unresolvable particle if it cannot be
3122 resolved, or if it has resolved to a term which is a model
3123 group that has an unresolvable particle.
3124 """
3125 if not self.isResolved():
3126 return False
3127 return self.term().isAdaptable(ctd)
3128
3130 """The entry-point to walk a particle tree defining a content model.
3131
3132 See L{_ParticleTree_mixin._walkParticleTree}."""
3133 self._walkParticleTree(visit, arg)
3134
3136 visit(self, True, arg)
3137 self.__term._walkParticleTree(visit, arg)
3138 visit(self, False, arg)
3139
3140 @classmethod
3143
3144 @classmethod
3147
3151
3152
3153 # 3.10.1
3154 -class Wildcard (_ParticleTree_mixin, _SchemaComponent_mixin, _Annotated_mixin):
3155 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component."""
3156
3157 NC_any = '##any' #<<< The namespace constraint "##any"
3158 NC_not = '##other' #<<< A flag indicating constraint "##other"
3159 NC_targetNamespace = '##targetNamespace'
3160 NC_local = '##local'
3161
3162 __namespaceConstraint = None
3164 """A constraint on the namespace for the wildcard.
3165
3166 Valid values are:
3167 - L{Wildcard.NC_any}
3168 - A tuple ( L{Wildcard.NC_not}, a_namespace )
3169 - set(of_namespaces)
3170
3171 Note that namespace are represented by
3172 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that
3173 actually define a namespace. Absence of a namespace is represented by
3174 C{None}, both in the "not" pair and in the set.
3175 """
3176 return self.__namespaceConstraint
3177
3178 @classmethod
3180 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union"""
3181 assert 0 < len(constraints)
3182 o1 = constraints.pop(0)
3183 while 0 < len(constraints):
3184 o2 = constraints.pop(0)
3185 # 1
3186 if (o1 == o2):
3187 continue
3188 # 2
3189 if (cls.NC_any == o1) or (cls.NC_any == o2):
3190 o1 = cls.NC_any
3191 continue
3192 # 3
3193 if isinstance(o1, set) and isinstance(o2, set):
3194 o1 = o1.union(o2)
3195 continue
3196 # 4
3197 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]):
3198 o1 = ( cls.NC_not, None )
3199 continue
3200 # At this point, one must be a negated namespace and the
3201 # other a set. Identify them.
3202 c_tuple = None
3203 c_set = None
3204 if isinstance(o1, tuple):
3205 assert isinstance(o2, set)
3206 c_tuple = o1
3207 c_set = o2
3208 else:
3209 assert isinstance(o1, set)
3210 assert isinstance(o2, tuple)
3211 c_tuple = o2
3212 c_set = o1
3213 negated_ns = c_tuple[1]
3214 if negated_ns is not None:
3215 # 5.1
3216 if (negated_ns in c_set) and (None in c_set):
3217 o1 = cls.NC_any
3218 continue
3219 # 5.2
3220 if negated_ns in c_set:
3221 o1 = ( cls.NC_not, None )
3222 continue
3223 # 5.3
3224 if None in c_set:
3225 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible')
3226 o1 = c_tuple
3227 continue
3228 # 6
3229 if None in c_set:
3230 o1 = cls.NC_any
3231 else:
3232 o1 = ( cls.NC_not, None )
3233 return o1
3234
3235 @classmethod
3237 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect"""
3238 assert 0 < len(constraints)
3239 o1 = constraints.pop(0)
3240 while 0 < len(constraints):
3241 o2 = constraints.pop(0)
3242 # 1
3243 if (o1 == o2):
3244 continue
3245 # 2
3246 if (cls.NC_any == o1) or (cls.NC_any == o2):
3247 if cls.NC_any == o1:
3248 o1 = o2
3249 continue
3250 # 4
3251 if isinstance(o1, set) and isinstance(o2, set):
3252 o1 = o1.intersection(o2)
3253 continue
3254 if isinstance(o1, tuple) and isinstance(o2, tuple):
3255 ns1 = o1[1]
3256 ns2 = o2[1]
3257 # 5
3258 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2):
3259 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible')
3260 # 6
3261 assert (ns1 is None) or (ns2 is None)
3262 if ns1 is None:
3263 assert ns2 is not None
3264 o1 = ( cls.NC_not, ns2 )
3265 else:
3266 assert ns1 is not None
3267 o1 = ( cls.NC_not, ns1 )
3268 continue
3269 # 3
3270 # At this point, one must be a negated namespace and the
3271 # other a set. Identify them.
3272 c_tuple = None
3273 c_set = None
3274 if isinstance(o1, tuple):
3275 assert isinstance(o2, set)
3276 c_tuple = o1
3277 c_set = o2
3278 else:
3279 assert isinstance(o1, set)
3280 assert isinstance(o2, tuple)
3281 c_tuple = o2
3282 c_set = o1
3283 negated_ns = c_tuple[1]
3284 if negated_ns in c_set:
3285 c_set.remove(negated_ns)
3286 if None in c_set:
3287 c_set.remove(None)
3288 o1 = c_set
3289 return o1
3290
3291 PC_skip = 'skip' #<<< No constraint is applied
3292 PC_lax = 'lax' #<<< Validate against available uniquely determined declaration
3293 PC_strict = 'strict' #<<< Validate against declaration or xsi:type which must be available
3294
3295 # One of PC_*
3296 __processContents = None
3298 return self.__processContents
3299
3303
3305 assert 0 == len(args)
3306 super(Wildcard, self).__init__(*args, **kw)
3307 self.__namespaceConstraint = kw['namespace_constraint']
3308 self.__processContents = kw['process_contents']
3309
3312
3315
3316 # aFS:WC
3320
3321 # CFD:Wildcard
3322 @classmethod
3324 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
3325 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute')
3326 nc = domutils.NodeAttribute(node, 'namespace')
3327 if nc is None:
3328 namespace_constraint = cls.NC_any
3329 else:
3330 if cls.NC_any == nc:
3331 namespace_constraint = cls.NC_any
3332 elif cls.NC_not == nc:
3333 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() )
3334 else:
3335 ncs = set()
3336 for ns_uri in nc.split():
3337 if cls.NC_local == ns_uri:
3338 ncs.add(None)
3339 elif cls.NC_targetNamespace == ns_uri:
3340 ncs.add(namespace_context.targetNamespace())
3341 else:
3342 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True))
3343 namespace_constraint = frozenset(ncs)
3344
3345 pc = domutils.NodeAttribute(node, 'processContents')
3346 if pc is None:
3347 process_contents = cls.PC_strict
3348 else:
3349 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]:
3350 process_contents = pc
3351 else:
3352 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,))
3353
3354 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw)
3355 rv._annotationFromDOM(node)
3356 return rv
3357
3358 # 3.11.1
3359 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3360 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component."""
3361
3362 ICC_KEY = 0x01
3363 ICC_KEYREF = 0x02
3364 ICC_UNIQUE = 0x04
3365
3366 __identityConstraintCategory = None
3368 return self.__identityConstraintCategory
3369
3370 __selector = None
3372 return self.__selector
3373
3374 __fields = None
3376 return self.__fields
3377
3378 __referencedKey = None
3379 __referAttribute = None
3380 __icc = None
3381
3382 __annotations = None
3384 return self.__annotations
3385
3386 # CFD:ICD CFD:IdentityConstraintDefinition
3387 @classmethod
3389 name = domutils.NodeAttribute(node, 'name')
3390 scope = kw['scope']
3391 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope)
3392 rv = cls(name=name, node=node, **kw)
3393
3394 kw.pop('node', None)
3395 kw['owner'] = rv
3396
3397 #self._annotationFromDOM(node);
3398 rv.__isResolved = True
3399 icc = None
3400 if xsd.nodeIsNamed(node, 'key'):
3401 icc = rv.ICC_KEY
3402 elif xsd.nodeIsNamed(node, 'keyref'):
3403 icc = rv.ICC_KEYREF
3404 rv.__referAttribute = domutils.NodeAttribute(node, 'refer')
3405 if rv.__referAttribute is None:
3406 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements')
3407 rv.__isResolved = False
3408 elif xsd.nodeIsNamed(node, 'unique'):
3409 icc = rv.ICC_UNIQUE
3410 else:
3411 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml("utf-8"),))
3412 rv.__icc = icc
3413
3414 cn = domutils.LocateUniqueChild(node, 'selector')
3415 rv.__selector = domutils.NodeAttribute(cn, 'xpath')
3416 if rv.__selector is None:
3417 raise pyxb.SchemaValidationError('selector element missing xpath attribute')
3418
3419 rv.__fields = []
3420 for cn in domutils.LocateMatchingChildren(node, 'field'):
3421 xp_attr = domutils.NodeAttribute(cn, 'xpath')
3422 if xp_attr is None:
3423 raise pyxb.SchemaValidationError('field element missing xpath attribute')
3424 rv.__fields.append(xp_attr)
3425
3426 rv._annotationFromDOM(node)
3427 rv.__annotations = []
3428 if rv.annotation() is not None:
3429 rv.__annotations.append(rv)
3430
3431 for cn in node.childNodes:
3432 if (Node.ELEMENT_NODE != cn.nodeType):
3433 continue
3434 an = None
3435 if xsd.nodeIsNamed(cn, 'selector', 'field'):
3436 an = domutils.LocateUniqueChild(cn, 'annotation')
3437 elif xsd.nodeIsNamed(cn, 'annotation'):
3438 an = cn
3439 if an is not None:
3440 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw))
3441
3442 rv.__identityConstraintCategory = icc
3443 if rv.ICC_KEYREF != rv.__identityConstraintCategory:
3444 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv)
3445
3446 if not rv.isResolved():
3447 rv._queueForResolution('creation')
3448 return rv
3449
3450 __isResolved = False
3452 return self.__isResolved
3453
3454 # res:ICD res:IdentityConstraintDefinition
3456 if self.isResolved():
3457 return self
3458
3459 icc = self.__icc
3460 if self.ICC_KEYREF == icc:
3461 refer_en = self._namespaceContext().interpretQName(self.__referAttribute)
3462 refer = refer_en.identityConstraintDefinition()
3463 if refer is None:
3464 self._queueForResolution('Identity constraint definition %s cannot be found' % (refer_en,), depends_on=refer)
3465 return self
3466 self.__referencedKey = refer
3467 self.__isResolved = True
3468 return self
3469
3470 # bR:ICD
3472 """Constraint definitions that are by reference require the referenced constraint."""
3473 rv = set()
3474 if include_lax and (self.__referencedKey is not None):
3475 rv.add(self.__referencedKey)
3476 return frozenset(rv)
3477
3478
3479
3480 # 3.12.1
3481 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3482 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component."""
3483 __systemIdentifier = None
3485 return self.__systemIdentifier
3486
3487 __publicIdentifier = None
3489 return self.__publicIdentifier
3490
3491 # CFD:ND CFD:NotationDeclaration
3492 @classmethod
3494 name = domutils.NodeAttribute(node, 'name')
3495 rv = cls(name=name, node=node, **kw)
3496
3497 rv.__systemIdentifier = domutils.NodeAttribute(node, 'system')
3498 rv.__publicIdentifier = domutils.NodeAttribute(node, 'public')
3499
3500 rv._annotationFromDOM(node)
3501 return rv
3502
3505 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component."""
3506
3507 __applicationInformation = None
3509 return self.__applicationInformation
3510
3511 __userInformation = None
3513 return self.__userInformation
3514
3515 # Define so superclasses can take keywords
3517 application_information = kw.pop('application_information', None)
3518 user_information = kw.pop('user_information', None)
3519 super(Annotation, self).__init__(**kw)
3520 if (user_information is not None) and (not isinstance(user_information, list)):
3521 user_information = [ unicode(user_information) ]
3522 if (application_information is not None) and (not isinstance(application_information, list)):
3523 application_information = [ unicode(application_information) ]
3524 self.__userInformation = user_information
3525 self.__applicationInformation = application_information
3526
3527 # @todo: what the hell is this? From 3.13.2, I think it's a place
3528 # to stuff attributes from the annotation element, which makes
3529 # sense, as well as from the annotation's parent element, which
3530 # doesn't. Apparently it's for attributes that don't belong to
3531 # the XMLSchema namespace; so maybe we're not supposed to add
3532 # those to the other components. Note that these are attribute
3533 # information items, not attribute uses.
3534 __attributes = None
3535
3536 # CFD:Annotation
3537 @classmethod
3539 rv = cls(node=node, **kw)
3540
3541 # @todo:: Scan for attributes in the node itself that do not
3542 # belong to the XMLSchema namespace.
3543
3544 # Node should be an XMLSchema annotation node
3545 assert xsd.nodeIsNamed(node, 'annotation')
3546 app_info = []
3547 user_info = []
3548 for cn in node.childNodes:
3549 if xsd.nodeIsNamed(cn, 'appinfo'):
3550 app_info.append(cn)
3551 elif xsd.nodeIsNamed(cn, 'documentation'):
3552 user_info.append(cn)
3553 else:
3554 pass
3555 if 0 < len(app_info):
3556 rv.__applicationInformation = app_info
3557 if 0 < len(user_info):
3558 rv.__userInformation = user_info
3559
3560 return rv
3561
3562 __RemoveMultiQuote_re = re.compile('""+')
3564 """Return the text in a form suitable for embedding in a
3565 triple-double-quoted docstring.
3566
3567 Any sequence of two or more double quotes is replaced by a sequence of
3568 single quotes that is the same length. Following this, spaces are
3569 added at the start and the end as necessary to ensure a double quote
3570 does not appear in those positions."""
3571 rv = self.text()
3572 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv)
3573 if rv.startswith('"'):
3574 rv = ' ' + rv
3575 if rv.endswith('"'):
3576 rv = rv + ' '
3577 return rv
3578
3580 if self.__userInformation is None:
3581 return ''
3582 text = []
3583 # Values in userInformation are DOM "documentation" elements.
3584 # We want their combined content.
3585 for dn in self.__userInformation:
3586 for cn in dn.childNodes:
3587 if Node.TEXT_NODE == cn.nodeType:
3588 text.append(cn.data)
3589 return ''.join(text)
3590
3592 """Return the catenation of all user information elements in the
3593 annotation as a single unicode string. Returns the empty string if
3594 there are no user information elements."""
3595 return self.text()
3596
3597 # Section 3.14.
3598 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3599 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component."""
3600
3601 # Reference to the SimpleTypeDefinition on which this is based.
3602 # The value must be non-None except for the simple ur-type
3603 # definition.
3604 __baseTypeDefinition = None
3606 return self.__baseTypeDefinition
3607
3608 __memberTypes = None
3609 __itemTypeAttribute = None
3610 __baseAttribute = None
3611 __memberTypesAttribute = None
3612 __localFacets = None
3613
3614 # A map from a subclass of facets.Facet to an instance of that class.
3615 # Presence of a facet class as a key in this map is the indicator that the
3616 # type definition and its subtypes are permitted to use the corresponding
3617 # facet. All facets in force for this type are present in the map,
3618 # including those constraints inherited parent types.
3619 __facets = None
3621 assert (self.__facets is None) or (type(self.__facets) == types.DictType)
3622 return self.__facets
3623
3624 # The facets.FundamentalFacet instances that describe this type
3625 __fundamentalFacets = None
3627 """A frozenset of instances of facets.FundamentallFacet."""
3628 return self.__fundamentalFacets
3629
3630 STD_empty = 0 #<<< Marker indicating an empty set of STD forms
3631 STD_extension = 0x01 #<<< Representation for extension in a set of STD forms
3632 STD_list = 0x02 #<<< Representation for list in a set of STD forms
3633 STD_restriction = 0x04 #<<< Representation of restriction in a set of STD forms
3634 STD_union = 0x08 #<<< Representation of union in a set of STD forms
3635
3636 _STD_Map = { 'extension' : STD_extension
3637 , 'list' : STD_list
3638 , 'restriction' : STD_restriction
3639 , 'union' : STD_union }
3640
3641 # Bitmask defining the subset that comprises the final property
3642 __final = STD_empty
3643 @classmethod
3645 """Convert a final value to a string."""
3646 tags = []
3647 if final_value & cls.STD_extension:
3648 tags.append('extension')
3649 if final_value & cls.STD_list:
3650 tags.append('list')
3651 if final_value & cls.STD_restriction:
3652 tags.append('restriction')
3653 if final_value & cls.STD_union:
3654 tags.append('union')
3655 return ' '.join(tags)
3656
3657 VARIETY_absent = 0x01 #<<< Only used for the ur-type
3658 VARIETY_atomic = 0x02 #<<< Use for types based on a primitive type
3659 VARIETY_list = 0x03 #<<< Use for lists of atomic-variety types
3660 VARIETY_union = 0x04 #<<< Use for types that aggregate other types
3661
3662 # Derivation alternative
3663 _DA_empty = 'none specified'
3664 _DA_restriction = 'restriction'
3665 _DA_list = 'list'
3666 _DA_union = 'union'
3667
3669 return self.__derivationAlternative
3670 __derivationAlternative = None
3671
3672 # Identify the sort of value collection this holds. This field is
3673 # used to identify unresolved definitions.
3674 __variety = None
3676 return self.__variety
3677 @classmethod
3679 """Convert a variety value to a string."""
3680 if cls.VARIETY_absent == variety:
3681 return 'absent'
3682 if cls.VARIETY_atomic == variety:
3683 return 'atomic'
3684 if cls.VARIETY_list == variety:
3685 return 'list'
3686 if cls.VARIETY_union == variety:
3687 return 'union'
3688 return '?NoVariety?'
3689
3690 # For atomic variety only, the root (excepting ur-type) type.
3691 __primitiveTypeDefinition = None
3693 if throw_if_absent:
3694 assert self.VARIETY_atomic == self.variety()
3695 if self.__primitiveTypeDefinition is None:
3696 raise pyxb.LogicError('Expected primitive type for %s in %s', self, self.targetNamespace())
3697 return self.__primitiveTypeDefinition
3698
3699 # For list variety only, the type of items in the list
3700 __itemTypeDefinition = None
3702 assert self.VARIETY_list == self.variety()
3703 if self.__itemTypeDefinition is None:
3704 raise pyxb.LogicError('Expected item type')
3705 return self.__itemTypeDefinition
3706
3707 # For union variety only, the sequence of candidate members
3708 __memberTypeDefinitions = None
3710 assert self.VARIETY_union == self.variety()
3711 if self.__memberTypeDefinitions is None:
3712 raise pyxb.LogicError('Expected member types')
3713 return self.__memberTypeDefinitions
3714
3715 # bR:STD
3717 """Implement base class method.
3718
3719 This STD depends on its baseTypeDefinition, unless its variety
3720 is absent. Other dependencies are on item, primitive, or
3721 member type definitions."""
3722 type_definitions = set()
3723 if self != self.baseTypeDefinition():
3724 type_definitions.add(self.baseTypeDefinition())
3725 if self.VARIETY_absent == self.variety():
3726 type_definitions = set()
3727 elif self.VARIETY_atomic == self.variety():
3728 if self != self.primitiveTypeDefinition():
3729 type_definitions.add(self.primitiveTypeDefinition())
3730 elif self.VARIETY_list == self.variety():
3731 assert self != self.itemTypeDefinition()
3732 type_definitions.add(self.itemTypeDefinition())
3733 else:
3734 assert self.VARIETY_union == self.variety()
3735 assert self not in self.memberTypeDefinitions()
3736 type_definitions.update(self.memberTypeDefinitions())
3737 # NB: This type also depends on the value type definitions for
3738 # any facets that apply to it. This fact only matters when
3739 # generating the datatypes_facets source. That, and the fact
3740 # that there are dependency loops (e.g., integer requires a
3741 # nonNegativeInteger for its length facet) means we don't
3742 # bother adding in those.
3743 return frozenset(type_definitions)
3744
3745 # A non-property field that holds a reference to the DOM node from
3746 # which the type is defined. The value is held only between the
3747 # point where the simple type definition instance is created until
3748 # the point it is resolved.
3749 __domNode = None
3750
3751 # Indicate that this instance was defined as a built-in rather
3752 # than from a DOM instance.
3753 __isBuiltin = False
3754
3755 # Allocate one of these. Users should use one of the Create*
3756 # factory methods instead.
3757
3761
3763 """Extend base class unpickle support to retain link between
3764 this instance and the Python class that it describes.
3765
3766 This is because the pythonSupport value is a class reference,
3767 not an instance reference, so it wasn't deserialized, and its
3768 class member link was never set.
3769 """
3770 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state))
3771 super_fn(state)
3772 if self.__pythonSupport is not None:
3773 self.__pythonSupport._SimpleTypeDefinition(self)
3774
3776 if self.name() is not None:
3777 elts = [ self.name(), ':' ]
3778 else:
3779 elts = [ '<anonymous>:' ]
3780 if self.VARIETY_absent == self.variety():
3781 elts.append('the ur-type')
3782 elif self.VARIETY_atomic == self.variety():
3783 elts.append('restriction of %s' % (self.baseTypeDefinition().name(),))
3784 elif self.VARIETY_list == self.variety():
3785 elts.append('list of %s' % (self.itemTypeDefinition().name(),))
3786 elif self.VARIETY_union == self.variety():
3787 elts.append('union of %s' % (" ".join([str(_mtd.name()) for _mtd in self.memberTypeDefinitions()],)))
3788 else:
3789 # Gets here if the type has not been resolved.
3790 elts.append('?')
3791 #raise pyxb.LogicError('Unexpected variety %s' % (self.variety(),))
3792 if self.__facets:
3793 felts = []
3794 for (k, v) in self.__facets.items():
3795 if v is not None:
3796 felts.append(str(v))
3797 elts.append("\n %s" % (','.join(felts),))
3798 if self.__fundamentalFacets:
3799 elts.append("\n ")
3800 elts.append(','.join( [str(_f) for _f in self.__fundamentalFacets ]))
3801 return 'STD[%s]' % (''.join(elts),)
3802
3804 """Override fields in this instance with those from the other.
3805
3806 This method is invoked only by Schema._addNamedComponent, and
3807 then only when a built-in type collides with a schema-defined
3808 type. Material like facets is not (currently) held in the
3809 built-in copy, so the DOM information is copied over to the
3810 built-in STD, which is subsequently re-resolved.
3811
3812 Returns self.
3813 """
3814 assert self != other
3815 assert self.isNameEquivalent(other)
3816 super(SimpleTypeDefinition, self)._updateFromOther_csc(other)
3817
3818 # The other STD should be an unresolved schema-defined type.
3819 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,)
3820 assert other.__domNode is not None
3821 self.__domNode = other.__domNode
3822
3823 # Preserve the python support
3824 if other.__pythonSupport is not None:
3825 # @todo: ERROR multiple references
3826 self.__pythonSupport = other.__pythonSupport
3827
3828 # Mark this instance as unresolved so it is re-examined
3829 self.__variety = None
3830 return self
3831
3835
3836 __SimpleUrTypeDefinition = None
3837 @classmethod
3839 """Create the SimpleTypeDefinition instance that approximates the simple ur-type.
3840
3841 See section 3.14.7."""
3842
3843 #if in_builtin_definition and (cls.__SimpleUrTypeDefinition is not None):
3844 # raise pyxb.LogicError('Multiple definitions of SimpleUrType')
3845 if cls.__SimpleUrTypeDefinition is None:
3846 # Note: We use a singleton subclass
3847 assert schema is not None
3848
3849 ns_ctx = schema.targetNamespace().initialNamespaceContext()
3850
3851 kw = { 'name' : 'anySimpleType',
3852 'schema' : schema,
3853 'namespace_context' : ns_ctx,
3854 'binding_namespace' : schema.targetNamespace(),
3855 'variety' : cls.VARIETY_absent,
3856 'scope' : _ScopedDeclaration_mixin.SCOPE_global }
3857 bi = _SimpleUrTypeDefinition(**kw)
3858 bi._setPythonSupport(datatypes.anySimpleType)
3859
3860 # The baseTypeDefinition is the ur-type.
3861 bi.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition()
3862 # The simple ur-type has an absent variety, not an atomic
3863 # variety, so does not have a primitiveTypeDefinition
3864
3865 # No facets on the ur type
3866 bi.__facets = {}
3867 bi.__fundamentalFacets = frozenset()
3868
3869 bi.__resolveBuiltin()
3870
3871 cls.__SimpleUrTypeDefinition = bi
3872 return cls.__SimpleUrTypeDefinition
3873
3874 @classmethod
3876 """Create STD instances for built-in types.
3877
3878 For example, xml:space is a restriction of NCName; xml:lang is a union.
3879
3880 """
3881 from pyxb.binding import xml_
3882 kw = { 'schema' : schema,
3883 'binding_namespace' : schema.targetNamespace(),
3884 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
3885 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
3886 'variety' : cls.VARIETY_atomic }
3887 if 'space' == name:
3888 bi = cls(**kw)
3889 bi.__derivationAlternative = cls._DA_restriction
3890 bi.__baseTypeDefinition = datatypes.NCName.SimpleTypeDefinition()
3891 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition
3892 bi._setPythonSupport(xml_.STD_ANON_space)
3893 bi.setNameInBinding('STD_ANON_space')
3894 elif 'lang' == name:
3895 bi = cls(**kw)
3896 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
3897 bi.__memberTypes = [ datatypes.language.SimpleTypeDefinition() ]
3898 bi.__derivationAlternative = cls._DA_union
3899 bi.__primitiveTypeDefinition = bi
3900 bi._setPythonSupport(xml_.STD_ANON_lang)
3901 bi.setNameInBinding('STD_ANON_lang')
3902 else:
3903 raise pyxb.IncompleteImplementationError('No implementation for xml:%s' % (name,))
3904 bi.__facets = { }
3905 for v in bi.pythonSupport().__dict__.values():
3906 if isinstance(v, facets.ConstrainingFacet):
3907 bi.__facets[v.__class__] = v
3908 return bi
3909
3910 @classmethod
3912 """Create a primitive simple type in the target namespace.
3913
3914 This is mainly used to pre-load standard built-in primitive
3915 types, such as those defined by XMLSchema Datatypes. You can
3916 use it for your own schemas as well, if you have special types
3917 that require explicit support to for Pythonic conversion.
3918
3919 All parameters are required and must be non-None.
3920 """
3921
3922 kw = { 'name' : name,
3923 'schema' : schema,
3924 'binding_namespace' : schema.targetNamespace(),
3925 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
3926 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
3927 'variety' : cls.VARIETY_atomic }
3928
3929 bi = cls(**kw)
3930 bi._setPythonSupport(python_support)
3931
3932 # Primitive types are based on the ur-type, and have
3933 # themselves as their primitive type definition.
3934 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
3935 bi.__primitiveTypeDefinition = bi
3936
3937 # Primitive types are built-in
3938 bi.__resolveBuiltin()
3939 assert bi.isResolved()
3940 return bi
3941
3942 @classmethod
3944 """Create a derived simple type in the target namespace.
3945
3946 This is used to pre-load standard built-in derived types. You
3947 can use it for your own schemas as well, if you have special
3948 types that require explicit support to for Pythonic
3949 conversion.
3950 """
3951 assert parent_std
3952 assert parent_std.__variety in (cls.VARIETY_absent, cls.VARIETY_atomic)
3953 kw = { 'name' : name,
3954 'schema' : schema,
3955 'binding_namespace' : schema.targetNamespace(),
3956 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
3957 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
3958 'variety' : parent_std.__variety }
3959
3960 bi = cls(**kw)
3961 bi._setPythonSupport(python_support)
3962
3963 # We were told the base type. If this is atomic, we re-use
3964 # its primitive type. Note that these all may be in different
3965 # namespaces.
3966 bi.__baseTypeDefinition = parent_std
3967 if cls.VARIETY_atomic == bi.__variety:
3968 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition
3969
3970 # Derived types are built-in
3971 bi.__resolveBuiltin()
3972 return bi
3973
3974 @classmethod
3976 """Create a list simple type in the target namespace.
3977
3978 This is used to preload standard built-in list types. You can
3979 use it for your own schemas as well, if you have special types
3980 that require explicit support to for Pythonic conversion; but
3981 note that such support is identified by the item_std.
3982 """
3983
3984 kw = { 'name' : name,
3985 'schema' : schema,
3986 'binding_namespace' : schema.targetNamespace(),
3987 'namespace_context' : schema.targetNamespace().initialNamespaceContext(),
3988 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
3989 'variety' : cls.VARIETY_list }
3990 bi = cls(**kw)
3991 bi._setPythonSupport(python_support)
3992
3993 # The base type is the ur-type. We were given the item type.
3994 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition()
3995 assert item_std
3996 bi.__itemTypeDefinition = item_std
3997
3998 # List types are built-in
3999 bi.__resolveBuiltin()
4000 return bi
4001
4002 @classmethod
4004 """(Placeholder) Create a union simple type in the target namespace.
4005
4006 This function has not been implemented."""
4007 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4008
4010 simple_type_child = None
4011 for cn in body.childNodes:
4012 if (Node.ELEMENT_NODE == cn.nodeType):
4013 if not xsd.nodeIsNamed(cn, 'simpleType'):
4014 if other_elts_ok:
4015 continue
4016 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType')
4017 assert not simple_type_child
4018 simple_type_child = cn
4019 if simple_type_child is None:
4020 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)')
4021 return simple_type_child
4022
4023 # The __initializeFrom* methods are responsible for identifying
4024 # the variety and the baseTypeDefinition. The remainder of the
4025 # resolution is performed by the __completeResolution method.
4026 # Note that in some cases resolution might yet be premature, so
4027 # variety is not saved until it is complete. All this stuff is
4028 # from section 3.14.2.
4029
4031 self.__baseTypeDefinition = self.SimpleUrTypeDefinition()
4032 self.__itemTypeAttribute = domutils.NodeAttribute(body, 'itemType')
4033 if self.__itemTypeAttribute is None:
4034 # NOTE: The newly created anonymous item type will
4035 # not be resolved; the caller needs to handle
4036 # that.
4037 self.__itemTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body), **kw)
4038 return self.__completeResolution(body, self.VARIETY_list, self._DA_list)
4039
4041 if self.__baseTypeDefinition is None:
4042 self.__baseAttribute = domutils.NodeAttribute(body, 'base')
4043 if self.__baseAttribute is None:
4044 self.__baseTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body, other_elts_ok=True), **kw)
4045 return self.__completeResolution(body, None, self._DA_restriction)
4046
4047 __localMemberTypes = None
4049 self.__baseTypeDefinition = self.SimpleUrTypeDefinition()
4050 self.__memberTypesAttribute = domutils.NodeAttribute(body, 'memberTypes')
4051 if self.__localMemberTypes is None:
4052 self.__localMemberTypes = []
4053 for cn in body.childNodes:
4054 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'simpleType'):
4055 self.__localMemberTypes.append(self.CreateFromDOM(cn, **kw))
4056 return self.__completeResolution(body, self.VARIETY_union, self._DA_union)
4057
4059 if self.hasPythonSupport():
4060 self.__facets = { }
4061 for v in self.pythonSupport().__dict__.values():
4062 if isinstance(v, facets.ConstrainingFacet):
4063 self.__facets[v.__class__] = v
4064 if v.ownerTypeDefinition() is None:
4065 v.setFromKeywords(_constructor=True, owner_type_definition=self)
4066 self.__isBuiltin = True
4067 return self
4068
4070 """Create facets for varieties that can take facets that are undeclared.
4071
4072 This means unions, which per section 4.1.2.3 of
4073 http://www.w3.org/TR/xmlschema-2/ can have enumeration or
4074 pattern restrictions."""
4075 if self.VARIETY_union != variety:
4076 return self
4077 self.__facets.setdefault(facets.CF_pattern)
4078 self.__facets.setdefault(facets.CF_enumeration)
4079 return self
4080
4082 """Identify the facets and properties for this stype.
4083
4084 This method simply identifies the facets that apply to this
4085 specific type, and records property values. Only
4086 explicitly-associated facets and properties are stored; others
4087 from base types will also affect this type. The information
4088 is taken from the applicationInformation children of the
4089 definition's annotation node, if any. If there is no support
4090 for the XMLSchema_hasFacetAndProperty namespace, this is a
4091 no-op.
4092
4093 Upon return, self.__facets is a map from the class for an
4094 associated fact to None, and self.__fundamentalFacets is a
4095 frozenset of instances of FundamentalFacet.
4096
4097 The return value is self.
4098 """
4099 self.__facets = { }
4100 self.__fundamentalFacets = frozenset()
4101 if self.annotation() is None:
4102 return self.__defineDefaultFacets(variety)
4103 app_info = self.annotation().applicationInformation()
4104 if app_info is None:
4105 return self.__defineDefaultFacets(variety)
4106 facet_map = { }
4107 fundamental_facets = set()
4108 seen_facets = set()
4109 for ai in app_info:
4110 for cn in ai.childNodes:
4111 if Node.ELEMENT_NODE != cn.nodeType:
4112 continue
4113 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'):
4114 facet_name = domutils.NodeAttribute(cn, 'name')# , pyxb.namespace.XMLSchema_hfp)
4115 if facet_name is None:
4116 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,))
4117 if facet_name in seen_facets:
4118 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,))
4119 seen_facets.add(facet_name)
4120 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name)
4121 #facet_map[facet_class] = facet_class(base_type_definition=self)
4122 facet_map[facet_class] = None
4123 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'):
4124 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self))
4125 if 0 < len(facet_map):
4126 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition()
4127 self.__facets = facet_map
4128 assert type(self.__facets) == types.DictType
4129 if 0 < len(fundamental_facets):
4130 self.__fundamentalFacets = frozenset(fundamental_facets)
4131 return self
4132
4133 # NB: Must be done after resolution of the base type
4135
4136 # Create local list consisting of facet classes matched in children
4137 # and the map of keywords used to initialize the local instance.
4138
4139 local_facets = {}
4140 for fc in facets.Facet.Facets:
4141 children = domutils.LocateMatchingChildren(body, fc.Name())
4142 if 0 < len(children):
4143 fi = fc(base_type_definition=self.__baseTypeDefinition,
4144 owner_type_definition=self)
4145 if isinstance(fi, facets._LateDatatype_mixin):
4146 fi.bindValueDatatype(self)
4147 for cn in children:
4148 kw = { 'annotation': domutils.LocateUniqueChild(cn, 'annotation') }
4149 for ai in range(0, cn.attributes.length):
4150 attr = cn.attributes.item(ai)
4151 # Convert name from unicode to string
4152 kw[str(attr.localName)] = attr.value
4153 try:
4154 fi.setFromKeywords(**kw)
4155 except pyxb.PyXBException as e:
4156 raise pyxb.SchemaValidationError('Error assigning facet %s in %s: %s' % (fc.Name(), self.expandedName(), e))
4157 local_facets[fc] = fi
4158 self.__localFacets = local_facets
4159
4160 # We want a map from the union of the facet classes from this STD up
4161 # through its baseTypeDefinition (if present). Map elements should be
4162 # to None if the facet has not been constrained, or to the nearest
4163 # ConstrainingFacet instance if it is. ConstrainingFacet instances
4164 # created for local constraints also need a pointer to the
4165 # corresponding facet from the ancestor type definition, because those
4166 # constraints also affect this type.
4167 base_facets = {}
4168
4169 # Built-ins didn't get their facets() setting configured, so use the
4170 # _FacetMap() instead.
4171 if self.__baseTypeDefinition.isBuiltin():
4172 pstd = self.__baseTypeDefinition.pythonSupport()
4173 if pstd != datatypes.anySimpleType:
4174 base_facets.update(pstd._FacetMap())
4175 elif self.__baseTypeDefinition.facets():
4176 assert type(self.__baseTypeDefinition.facets()) == types.DictType
4177 base_facets.update(self.__baseTypeDefinition.facets())
4178 base_facets.update(self.facets())
4179
4180 self.__facets = self.__localFacets
4181 for fc in base_facets.keys():
4182 self.__facets.setdefault(fc, base_facets[fc])
4183 assert type(self.__facets) == types.DictType
4184
4186 """Create a new simple type with this as its base.
4187
4188 The type is owned by the provided owner, and may have facet
4189 restrictions defined by the body.
4190 @param owner: the owner for the newly created type
4191 @type owner: L{ComplexTypeDefinition}
4192 @param body: the DOM node from which facet information will be extracted
4193 @type body: C{xml.dom.Node}
4194 @rtype: L{SimpleTypeDefinition}
4195 """
4196 std = SimpleTypeDefinition(owner=owner, namespace_context=owner._namespaceContext(), variety=None, scope=self._scope(), schema=owner._schema())
4197 std.__baseTypeDefinition = self
4198 return std.__completeResolution(body, None, self._DA_restriction)
4199
4200 # Complete the resolution of some variety of STD. Note that the
4201 # variety is compounded by an alternative, since there is no
4202 # 'restriction' variety.
4204 assert self.__variety is None
4205 if self.__baseTypeDefinition is None:
4206 assert self.__baseAttribute is not None
4207 base_en = self._namespaceContext().interpretQName(self.__baseAttribute)
4208 base_type = base_en.typeDefinition()
4209 if not isinstance(base_type, SimpleTypeDefinition):
4210 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,))
4211 self.__baseTypeDefinition = base_type
4212 # If the base type exists but has not yet been resolved,
4213 # delay processing this type until the one it depends on
4214 # has been completed.
4215 assert self.__baseTypeDefinition != self
4216 if not self.__baseTypeDefinition.isResolved():
4217 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,), depends_on=self.__baseTypeDefinition)
4218 return self
4219 if variety is None:
4220 # 3.14.1 specifies that the variety is the variety of the base
4221 # type definition which, by the way, can't be the ur type.
4222 variety = self.__baseTypeDefinition.__variety
4223 assert variety is not None
4224
4225 if self.VARIETY_absent == variety:
4226 # The ur-type is always resolved. So are restrictions of it,
4227 # which is how we might get here.
4228 pass
4229 elif self.VARIETY_atomic == variety:
4230 # Atomic types (and their restrictions) use the primitive
4231 # type, which is the highest type that is below the
4232 # ur-type (which is not atomic).
4233 ptd = self
4234 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()):
4235 ptd = ptd.__baseTypeDefinition
4236
4237 self.__primitiveTypeDefinition = ptd
4238 elif self.VARIETY_list == variety:
4239 if self._DA_list == alternative:
4240 if self.__itemTypeAttribute is not None:
4241 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute)
4242 self.__itemTypeDefinition = it_en.typeDefinition()
4243 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition):
4244 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,))
4245 elif self._DA_restriction == alternative:
4246 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition
4247 else:
4248 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,))
4249 elif self.VARIETY_union == variety:
4250 if self._DA_union == alternative:
4251 # First time we try to resolve, create the member type
4252 # definitions. If something later prevents us from resolving
4253 # this type, we don't want to create them again, because we
4254 # might already have references to them.
4255 if self.__memberTypeDefinitions is None:
4256 mtd = []
4257 # If present, first extract names from memberTypes,
4258 # and add each one to the list
4259 if self.__memberTypesAttribute is not None:
4260 for mn in self.__memberTypesAttribute.split():
4261 # THROW if type has not been defined
4262 mn_en = self._namespaceContext().interpretQName(mn)
4263 std = mn_en.typeDefinition()
4264 if std is None:
4265 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,))
4266 # Note: We do not need these to be resolved (here)
4267 assert isinstance(std, SimpleTypeDefinition)
4268 mtd.append(std)
4269 # Now look for local type definitions
4270 mtd.extend(self.__localMemberTypes)
4271 self.__memberTypeDefinitions = mtd
4272 assert None not in self.__memberTypeDefinitions
4273
4274 # Replace any member types that are themselves unions with the
4275 # members of those unions, in order. Note that doing this
4276 # might indicate we can't resolve this type yet, which is why
4277 # we separated the member list creation and the substitution
4278 # phases
4279 mtd = []
4280 for mt in self.__memberTypeDefinitions:
4281 assert isinstance(mt, SimpleTypeDefinition)
4282 if not mt.isResolved():
4283 self._queueForResolution('member type not resolved', depends_on=mt)
4284 return self
4285 if self.VARIETY_union == mt.variety():
4286 mtd.extend(mt.memberTypeDefinitions())
4287 else:
4288 mtd.append(mt)
4289 elif self._DA_restriction == alternative:
4290 assert self.__baseTypeDefinition
4291 # Base type should have been resolved before we got here
4292 assert self.__baseTypeDefinition.isResolved()
4293 mtd = self.__baseTypeDefinition.__memberTypeDefinitions
4294 assert mtd is not None
4295 else:
4296 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,))
4297 # Save a unique copy
4298 self.__memberTypeDefinitions = mtd[:]
4299 else:
4300 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,))
4301
4302 # Determine what facets, if any, apply to this type. This
4303 # should only do something if this is a primitive type.
4304 self.__processHasFacetAndProperty(variety)
4305 self.__updateFacets(body)
4306
4307 self.__derivationAlternative = alternative
4308 self.__variety = variety
4309 self.__domNode = None
4310 return self
4311
4313 """Indicate whether this simple type is fully defined.
4314
4315 Type resolution for simple types means that the corresponding
4316 schema component fields have been set. Specifically, that
4317 means variety, baseTypeDefinition, and the appropriate
4318 additional fields depending on variety. See _resolve() for
4319 more information.
4320 """
4321 # Only unresolved nodes have an unset variety
4322 return (self.__variety is not None)
4323
4324 # STD:res
4326 """Attempt to resolve the type.
4327
4328 Type resolution for simple types means that the corresponding
4329 schema component fields have been set. Specifically, that
4330 means variety, baseTypeDefinition, and the appropriate
4331 additional fields depending on variety.
4332
4333 All built-in STDs are resolved upon creation. Schema-defined
4334 STDs are held unresolved until the schema has been completely
4335 read, so that references to later schema-defined STDs can be
4336 resolved. Resolution is performed after the entire schema has
4337 been scanned and STD instances created for all
4338 topLevelSimpleTypes.
4339
4340 If a built-in STD is also defined in a schema (which it should
4341 be for XMLSchema), the built-in STD is kept, with the
4342 schema-related information copied over from the matching
4343 schema-defined STD. The former then replaces the latter in
4344 the list of STDs to be resolved.
4345
4346 Types defined by restriction have the same variety as the type
4347 they restrict. If a simple type restriction depends on an
4348 unresolved type, this method simply queues it for resolution
4349 in a later pass and returns.
4350 """
4351 if self.__variety is not None:
4352 return self
4353 assert self.__domNode
4354 node = self.__domNode
4355
4356 kw = { 'owner' : self
4357 , 'schema' : self._schema() }
4358
4359 bad_instance = False
4360 # The guts of the node should be exactly one instance of
4361 # exactly one of these three types.
4362 candidate = domutils.LocateUniqueChild(node, 'list')
4363 if candidate:
4364 self.__initializeFromList(candidate, **kw)
4365
4366 candidate = domutils.LocateUniqueChild(node, 'restriction')
4367 if candidate:
4368 if self.__variety is None:
4369 self.__initializeFromRestriction(candidate, **kw)
4370 else:
4371 bad_instance = True
4372
4373 candidate = domutils.LocateUniqueChild(node, 'union')
4374 if candidate:
4375 if self.__variety is None:
4376 self.__initializeFromUnion(candidate, **kw)
4377 else:
4378 bad_instance = True
4379
4380 if self.__baseTypeDefinition is None:
4381 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child')
4382
4383 if self._schema() is not None:
4384 self.__final = self._schema().finalForNode(node, self._STD_Map)
4385
4386 # It is NOT an error to fail to resolve the type.
4387 if bad_instance:
4388 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType')
4389
4390 return self
4391
4392 # CFD:STD CFD:SimpleTypeDefinition
4393 @classmethod
4395 # Node should be an XMLSchema simpleType node
4396 assert xsd.nodeIsNamed(node, 'simpleType')
4397
4398 name = domutils.NodeAttribute(node, 'name')
4399
4400 rv = cls(name=name, node=node, variety=None, **kw)
4401 rv._annotationFromDOM(node)
4402
4403 # Creation does not attempt to do resolution. Queue up the newly created
4404 # whatsis so we can resolve it after everything's been read in.
4405 rv.__domNode = node
4406 rv._queueForResolution('creation')
4407
4408 return rv
4409
4410 # pythonSupport is None, or a subclass of datatypes.simpleTypeDefinition.
4411 # When set, this simple type definition instance must be uniquely
4412 # associated with the python support type.
4413 __pythonSupport = None
4414
4416 # Includes check that python_support is not None
4417 assert issubclass(python_support, basis.simpleTypeDefinition)
4418 # Can't share support instances
4419 self.__pythonSupport = python_support
4420 self.__pythonSupport._SimpleTypeDefinition(self)
4421 if self.nameInBinding() is None:
4422 self.setNameInBinding(self.__pythonSupport.__name__)
4423 return self.__pythonSupport
4424
4426 return self.__pythonSupport is not None
4427
4429 if self.__pythonSupport is None:
4430 raise pyxb.LogicError('%s: No support defined' % (self.name(),))
4431 return self.__pythonSupport
4432
4435
4438
4442
4444 """Data associated with an
4445 U{import<http://www.w3.org/TR/xmlschema-1/#composition-schemaImport>}
4446 statement within a schema."""
4447
4451 __id = None
4452
4454 """The L{pyxb.namespace.Namespace} instance corresponding to the value
4455 of the C{namespace} attribute from the import statement."""
4456 return self.__namespace
4457 __namespace = None
4458
4460 """The value of the C{schemaLocation} attribute from the import
4461 statement, normalized relative to the location of the importing
4462 schema."""
4463 return self.__schemaLocation
4464 __schemaLocation = None
4465
4467 """The prefix from a namespace declaration for L{namespace} that was
4468 active in the context of the import element, or C{None} if there was
4469 no relevant namespace declaration in scope at that point.
4470
4471 This is propagated to be used as the default prefix for the
4472 corresponding namespace if no prefix had been assigned.
4473 """
4474 return self.__prefix
4475 __prefix = None
4476
4478 """The L{Schema} instance corresponding to the imported schema, if
4479 available.
4480
4481 Normally C{import} statements will be fulfilled by loading components
4482 from a L{namespace archive<pyxb.namespace.NamespaceArchive>} in which
4483 the corresponding namespace is marked as public. Where there are
4484 cycles in the namespace dependency graph, or the schema for a
4485 namespace are associated with a restricted profile of another
4486 namespace, there may be no such archive and instead the components are
4487 obtained using this schema."""
4488 return self.__schema
4489 __schema = None
4490
4492 """Gather the information relative to an C{import} statement.
4493
4494 If the imported namespace can be loaded from an archive, the
4495 C{schemaLocation} attribute is ignored. Otherwise, it attempts to
4496 retrieve and parse the corresponding schema (if this has not already
4497 been done).
4498
4499 @param importing_schema: The L{Schema} instance in which the import
4500 was found.
4501 @param node: The C{xml.dom.DOM} node incorporating the schema
4502 information.
4503
4504 @raise Exception: Any exception raised when attempting to retrieve and
4505 parse data from the schema location.
4506 """
4507
4508 super(_ImportElementInformationItem, self).__init__(**kw)
4509 uri = domutils.NodeAttribute(node, 'namespace')
4510 if uri is None:
4511 raise pyxb.IncompleteImplementationError('import statements without namespace not supported')
4512 schema_location = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), importing_schema.location())
4513 self.__schemaLocation = schema_location
4514 ns = self.__namespace = pyxb.namespace.NamespaceForURI(uri, create_if_missing=True)
4515 need_schema = not (ns.isLoadable() or ns.isBuiltinNamespace())
4516 if not need_schema:
4517 # Discard location if we expect to be able to learn about this
4518 # namespace from an archive or a built-in description
4519 self.__schemaLocation = None
4520
4521 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
4522 if self.schemaLocation() is not None:
4523 # @todo: NOTICE
4524 (has_schema, schema_instance) = self.__namespace.lookupSchemaByLocation(schema_location)
4525 if not has_schema:
4526 ckw = { 'absolute_schema_location' : schema_location,
4527 'generation_uid' : importing_schema.generationUID(),
4528 'uri_content_archive_directory' : importing_schema._uriContentArchiveDirectory(),
4529 }
4530 try:
4531 schema_instance = Schema.CreateFromLocation(**ckw)
4532 except Exception as e:
4533 _log.exception('Import %s cannot read schema location %s (%s)', ns, self.__schemaLocation, schema_location)
4534 raise
4535 self.__schema = schema_instance
4536 elif need_schema:
4537 _log.warning('No information available on imported namespace %s', uri)
4538
4539 # If we think we found a schema, make sure it's in the right
4540 # namespace.
4541 if self.__schema is not None:
4542 if ns != self.__schema.targetNamespace():
4543 raise pyxb.SchemaValidationError('Import expected namespace %s but got %s' % (ns, self.__schema.targetNamespace()))
4544
4545 self.__prefix = ns_ctx.prefixForNamespace(self.namespace())
4546
4547 self._annotationFromDOM(node)
4548
4550 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}."""
4551
4554
4555 # List of annotations
4556 __annotations = None
4557
4558 # True when we have started seeing elements, attributes, or
4559 # notations.
4560 __pastProlog = False
4561
4563 """URI or path to where the schema can be found.
4564
4565 For schema created by a user, the location should be provided to the
4566 constructor using the C{schema_location} keyword. In the case of
4567 imported or included schema, the including schema's location is used
4568 as the base URI for determining the absolute URI of the included
4569 schema from its (possibly relative) location value. For files,
4570 the scheme and authority portions are generally absent, as is often
4571 the abs_path part."""
4572 return self.__location
4573 __location = None
4574
4576 return self.__locationTag
4577 __locationTag = None
4578
4580 return self.__signature
4581 __signature = None
4582
4584 return self.__generationUID
4585 __generationUID = None
4586
4588 return self.__originRecord
4589 __originRecord = None
4590
4592 """The targetNamespace of a componen.
4593
4594 This is None, or a reference to a Namespace in which the
4595 component is declared (either as a global or local to one of
4596 the namespace's complex type definitions). This is immutable
4597 after creation.
4598 """
4599 return self.__targetNamespace
4600 __targetNamespace = None
4601
4603 """Default namespace of the schema.
4604
4605 Will be None unless the schema has an 'xmlns' attribute. The
4606 value must currently be provided as a keyword parameter to the
4607 constructor. """
4608 return self.__defaultNamespace
4609 __defaultNamespace = None
4610
4612 return self.__referencedNamespaces
4613 __referencedNamespaces = None
4614
4615 __namespaceData = None
4616
4618 return self.__importEIIs
4619 __importEIIs = None
4620
4622 return self.__importedSchema
4623 __importedSchema = None
4625 return self.__includedSchema
4626 __includedSchema = None
4627
4628 _QUALIFIED = "qualified"
4629 _UNQUALIFIED = "unqualified"
4630
4631 # Default values for standard recognized schema attributes
4632 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED
4633 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED
4634 , pyxb.namespace.ExpandedName(None, 'blockDefault') : ''
4635 , pyxb.namespace.ExpandedName(None, 'finalDefault') : ''
4636 , pyxb.namespace.ExpandedName(None, 'id') : None
4637 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None
4638 , pyxb.namespace.ExpandedName(None, 'version') : None
4639 , pyxb.namespace.XML.createExpandedName('lang') : None
4640 }
4641
4643 """Override the schema attribute with the given DOM value."""
4644 self.__attributeMap[pyxb.namespace.ExpandedName(attr.name)] = attr.nodeValue
4645 return self
4646
4648 """Override the schema attributes with values from the given map."""
4649 self.__attributeMap.update(attr_map)
4650 return self
4651
4653 """Return True iff the schema has an attribute with the given (nc)name."""
4654 if isinstance(attr_name, basestring):
4655 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4656 return self.__attributeMap.has_key(attr_name)
4657
4659 """Return the schema attribute value associated with the given (nc)name.
4660
4661 @param attr_name: local name for the attribute in the schema element.
4662 @return: the value of the corresponding attribute, or C{None} if it
4663 has not been defined and has no default.
4664 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element.
4665 """
4666 if isinstance(attr_name, basestring):
4667 attr_name = pyxb.namespace.ExpandedName(None, attr_name)
4668 return self.__attributeMap[attr_name]
4669
4670 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition',
4671 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration',
4672 'identityConstraintDefinition' )
4673
4675 return self.__uriContentArchiveDirectory
4676 __uriContentArchiveDirectory = None
4677
4679 # Force resolution of available namespaces if not already done
4680 if not kw.get('_bypass_preload', False):
4681 pyxb.namespace.archive.NamespaceArchive.PreLoadArchives()
4682
4683 assert 'schema' not in kw
4684 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
4685 self.__location = kw.get('schema_location')
4686 if self.__location is not None:
4687 schema_path = self.__location
4688 if 0 <= schema_path.find(':'):
4689 schema_path = urlparse.urlparse(schema_path)[2] # .path
4690 self.__locationTag = os.path.split(schema_path)[1].split('.')[0]
4691
4692 self.__generationUID = kw.get('generation_uid')
4693 if self.__generationUID is None:
4694 _log.warning('No generationUID provided')
4695 self.__generationUID = pyxb.utils.utility.UniqueIdentifier()
4696
4697 self.__signature = kw.get('schema_signature')
4698
4699 super(Schema, self).__init__(*args, **kw)
4700 self.__importEIIs = set()
4701 self.__includedSchema = set()
4702 self.__importedSchema = set()
4703 self.__targetNamespace = self._namespaceContext().targetNamespace()
4704 if not isinstance(self.__targetNamespace, pyxb.namespace.Namespace):
4705 raise pyxb.LogicError('Schema constructor requires valid Namespace instance as target_namespace')
4706
4707 # NB: This will raise pyxb.SchemaUniquenessError if it appears this
4708 # schema has already been incorporated into the target namespace.
4709 self.__originRecord = self.__targetNamespace.addSchema(self)
4710
4711 self.__targetNamespace.configureCategories(self.__SchemaCategories)
4712 if self.__defaultNamespace is not None:
4713 self.__defaultNamespace.configureCategories(self.__SchemaCategories)
4714
4715 self.__attributeMap = self.__attributeMap.copy()
4716 self.__annotations = []
4717 # @todo: This isn't right if namespaces are introduced deeper in the document
4718 self.__referencedNamespaces = self._namespaceContext().inScopeNamespaces().values()
4719
4720 __TopLevelComponentMap = {
4721 'element' : ElementDeclaration,
4722 'attribute' : AttributeDeclaration,
4723 'notation' : NotationDeclaration,
4724 'simpleType' : SimpleTypeDefinition,
4725 'complexType' : ComplexTypeDefinition,
4726 'group' : ModelGroupDefinition,
4727 'attributeGroup' : AttributeGroupDefinition
4728 }
4729
4730 @classmethod
4732 if not ('schema_signature' in kw):
4733 kw['schema_signature'] = pyxb.utils.utility.HashForText(xmls)
4734 return cls.CreateFromDOM(domutils.StringToDOM(xmls, **kw), **kw)
4735
4736 @classmethod
4738 """Create a schema from a schema location.
4739
4740 Reads an XML document from the schema location and creates a schema
4741 using it. All keyword parameters are passed to L{CreateFromDOM}.
4742
4743 @keyword schema_location: A file path or a URI. If this is a relative
4744 URI and C{parent_uri} is present, the actual location will be
4745 L{normallzed<pyxb.utils.utility.NormalizeLocation>}.
4746 @keyword parent_uri: The context within which schema_location will be
4747 normalized, if necessary.
4748 @keyword absolute_schema_location: A file path or URI. This value is
4749 not normalized, and supersedes C{schema_location}.
4750 """
4751 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'), kw.get('prefix_map')))
4752 kw['location_base'] = kw['schema_location'] = schema_location
4753 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location))
4754 uri_content_archive_directory = kw.get('uri_content_archive_directory')
4755 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4756
4757 @classmethod
4759 return cls.CreateFromDocument(stream.read(), **kw)
4760
4761 @classmethod
4762 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4763 """Take the root element of the document, and scan its attributes under
4764 the assumption it is an XMLSchema schema element. That means
4765 recognize namespace declarations and process them. Also look for
4766 and set the default namespace. All other attributes are passed up
4767 to the parent class for storage."""
4768
4769 # Get the context of any schema that is including (not importing) this
4770 # one.
4771 including_context = kw.get('including_context')
4772
4773 root_node = node
4774 if Node.DOCUMENT_NODE == node.nodeType:
4775 root_node = root_node.documentElement
4776 if Node.ELEMENT_NODE != root_node.nodeType:
4777 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT')
4778
4779 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext)
4780 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node,
4781 parent_context=namespace_context,
4782 including_context=including_context)
4783
4784 tns = ns_ctx.targetNamespace()
4785 if tns is None:
4786 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)')
4787 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw)
4788 schema.__namespaceData = ns_ctx
4789
4790 if schema.targetNamespace() != ns_ctx.targetNamespace():
4791 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace()))
4792
4793 # Update the attribute map
4794 for ai in range(root_node.attributes.length):
4795 schema._setAttributeFromDOM(root_node.attributes.item(ai))
4796
4797 # Verify that the root node is an XML schema element
4798 if not xsd.nodeIsNamed(root_node, 'schema'):
4799 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,))
4800
4801 for cn in root_node.childNodes:
4802 if Node.ELEMENT_NODE == cn.nodeType:
4803 rv = schema.__processTopLevelNode(cn)
4804 if rv is None:
4805 _log.info('Unrecognized: %s %s', cn.nodeName, cn.toxml("utf-8"))
4806 elif Node.TEXT_NODE == cn.nodeType:
4807 # Non-element content really should just be whitespace.
4808 # If something else is seen, print it for inspection.
4809 text = cn.data.strip()
4810 if text:
4811 _log.info('Ignored text: %s', text)
4812 elif Node.COMMENT_NODE == cn.nodeType:
4813 pass
4814 else:
4815 # ATTRIBUTE_NODE
4816 # CDATA_SECTION_NODE
4817 # ENTITY_NODE
4818 # PROCESSING_INSTRUCTION
4819 # DOCUMENT_NODE
4820 # DOCUMENT_TYPE_NODE
4821 # NOTATION_NODE
4822 _log.info('Ignoring non-element: %s', cn)
4823
4824 # Do not perform resolution yet: we may be done with this schema, but
4825 # the namespace may incorporate additional ones, and we can't resolve
4826 # until everything's present.
4827 return schema
4828
4829 _SA_All = '#all'
4830
4832 ebv = domutils.NodeAttribute(dom_node, attr)
4833 if ebv is None:
4834 ebv = self.schemaAttribute('%sDefault' % (attr,))
4835 rv = 0
4836 if ebv == self._SA_All:
4837 for v in candidate_map.values():
4838 rv += v
4839 else:
4840 for candidate in ebv.split():
4841 rv += candidate_map.get(candidate, 0)
4842 return rv
4843
4845 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute.
4846
4847 A value of '#all' means enable every options; otherwise, the attribute
4848 value should be a list of tokens, for which the corresponding value
4849 will be added to the return value.
4850
4851 @param dom_node: the node from which the "block" attribute will be retrieved
4852 @type dom_node: C{xml.dom.Node}
4853 @param candidate_map: map from strings to bitmask values
4854 """
4855 return self.__ebvForNode('block', dom_node, candidate_map)
4856
4858 """Return a bit mask indicating a set of options read from the node's
4859 "final" attribute or the schema's "finalDefault" attribute.
4860
4861 A value of '#all' means enable every options; otherwise, the attribute
4862 value should be a list of tokens, for which the corresponding value
4863 will be added to the return value.
4864
4865 @param dom_node: the node from which the "final" attribute will be retrieved
4866 @type dom_node: C{xml.dom.Node}
4867 @param candidate_map: map from strings to bitmask values
4868 """
4869 return self.__ebvForNode('final', dom_node, candidate_map)
4870
4872 """Determine the target namespace for a local attribute or element declaration.
4873
4874 Look at the node's C{form} attribute, or if none the schema's
4875 C{attributeFormDefault} or C{elementFormDefault} value. If the
4876 resulting value is C{"qualified"} and the parent schema has a
4877 non-absent target namespace, return it to use as the declaration
4878 target namespace. Otherwise, return None to indicate that the
4879 declaration has no namespace.
4880
4881 @param dom_node: The node defining an element or attribute declaration
4882 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration}
4883 @return: L{pyxb.namespace.Namespace} or None
4884 """
4885
4886 form_type = domutils.NodeAttribute(dom_node, 'form')
4887 if form_type is None:
4888 if declaration_type == ElementDeclaration:
4889 form_type = self.schemaAttribute('elementFormDefault')
4890 elif declaration_type == AttributeDeclaration:
4891 form_type = self.schemaAttribute('attributeFormDefault')
4892 else:
4893 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,))
4894 tns = None
4895 if (self._QUALIFIED == form_type):
4896 tns = self.targetNamespace()
4897 if tns.isAbsentNamespace():
4898 tns = None
4899 else:
4900 if (self._UNQUALIFIED != form_type):
4901 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED))
4902 return tns
4903
4905 """Throw a SchemaValidationException referencing the given
4906 node if we have passed the sequence point representing the end
4907 of prolog elements."""
4908
4909 if self.__pastProlog:
4910 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4911
4913 self.__requireInProlog(node.nodeName)
4914 # See section 4.2.1 of Structures.
4915 abs_uri = pyxb.utils.utility.NormalizeLocation(domutils.NodeAttribute(node, 'schemaLocation'), self.__location)
4916 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri)
4917 if not has_schema:
4918 kw = { 'absolute_schema_location': abs_uri,
4919 'including_context': self.__namespaceData,
4920 'generation_uid': self.generationUID(),
4921 'uri_content_archive_directory': self._uriContentArchiveDirectory(),
4922 }
4923 try:
4924 schema_instance = self.CreateFromLocation(**kw)
4925 except pyxb.SchemaUniquenessError as e:
4926 _log.warning('Skipping apparent redundant inclusion of %s defining %s (hash matches %s)', e.schemaLocation(), e.namespace(), e.existingSchema().location())
4927 except Exception as e:
4928 _log.exception('INCLUDE %s caught', abs_uri)
4929 raise
4930 if schema_instance:
4931 if self.targetNamespace() != schema_instance.targetNamespace():
4932 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace()))
4933 self.__includedSchema.add(schema_instance)
4934 return node
4935
4937 """Process an import directive.
4938
4939 This attempts to locate schema (named entity) information for
4940 a namespace that is referenced by this schema.
4941 """
4942
4943 self.__requireInProlog(node.nodeName)
4944 import_eii = _ImportElementInformationItem(self, node)
4945 if import_eii.schema() is not None:
4946 self.__importedSchema.add(import_eii.schema())
4947 self.targetNamespace().importNamespace(import_eii.namespace())
4948 ins = import_eii.namespace()
4949 if ins.prefix() is None:
4950 ins.setPrefix(import_eii.prefix())
4951 self.__importEIIs.add(import_eii)
4952 return node
4953
4955 self.__requireInProlog(node.nodeName)
4956 raise pyxb.IncompleteImplementationError('redefine not implemented')
4957
4961
4963 """Process a DOM node from the top level of the schema.
4964
4965 This should return a non-None value if the node was
4966 successfully recognized."""
4967 if xsd.nodeIsNamed(node, 'include'):
4968 return self.__processInclude(node)
4969 if xsd.nodeIsNamed(node, 'import'):
4970 return self.__processImport(node)
4971 if xsd.nodeIsNamed(node, 'redefine'):
4972 return self.__processRedefine(node)
4973 if xsd.nodeIsNamed(node, 'annotation'):
4974 return self.__processAnnotation(node)
4975
4976 component = self.__TopLevelComponentMap.get(node.localName)
4977 if component is not None:
4978 self.__pastProlog = True
4979 kw = { 'scope' : _ScopedDeclaration_mixin.SCOPE_global,
4980 'schema' : self,
4981 'owner' : self }
4982 return self._addNamedComponent(component.CreateFromDOM(node, **kw))
4983
4984 raise pyxb.SchemaValidationError('Unexpected top-level element %s' % (node.nodeName,))
4985
4989
4991 tns = self.targetNamespace()
4992 assert tns is not None
4993 if not isinstance(nc, _NamedComponent_mixin):
4994 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,))
4995 if nc.isAnonymous():
4996 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,))
4997 if isinstance(nc, _ScopedDeclaration_mixin):
4998 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope()
4999 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)):
5000 return self.__addTypeDefinition(nc)
5001 if isinstance(nc, AttributeDeclaration):
5002 return self.__addAttributeDeclaration(nc)
5003 if isinstance(nc, AttributeGroupDefinition):
5004 return self.__addAttributeGroupDefinition(nc)
5005 if isinstance(nc, ModelGroupDefinition):
5006 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc)
5007 if isinstance(nc, ElementDeclaration):
5008 return tns.addCategoryObject('elementDeclaration', nc.name(), nc)
5009 if isinstance(nc, NotationDeclaration):
5010 return tns.addCategoryObject('notationDeclaration', nc.name(), nc)
5011 if isinstance(nc, IdentityConstraintDefinition):
5012 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc)
5013 assert False, 'No support to record named component of type %s' % (nc.__class__,)
5014
5016 local_name = td.name()
5017 assert self.__targetNamespace
5018 tns = self.targetNamespace()
5019 old_td = tns.typeDefinitions().get(local_name)
5020 if (old_td is not None) and (old_td != td):
5021 if isinstance(td, ComplexTypeDefinition) != isinstance(old_td, ComplexTypeDefinition):
5022 raise pyxb.SchemaValidationError('Name %s used for both simple and complex types' % (td.name(),))
5023
5024 if not old_td._allowUpdateFromOther(td):
5025 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin type definition %s' % (tns.createExpandedName(local_name),))
5026
5027 # Copy schema-related information from the new definition
5028 # into the old one, and continue to use the old one.
5029 td = tns._replaceComponent(td, old_td._updateFromOther(td))
5030 else:
5031 tns.addCategoryObject('typeDefinition', td.name(), td)
5032 assert td is not None
5033 return td
5034
5036 local_name = ad.name()
5037 assert self.__targetNamespace
5038 tns = self.targetNamespace()
5039 old_ad = tns.attributeDeclarations().get(local_name)
5040 if (old_ad is not None) and (old_ad != ad):
5041 if not old_ad._allowUpdateFromOther(ad):
5042 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute declaration %s' % (tns.createExpandedName(local_name),))
5043
5044 # Copy schema-related information from the new definition
5045 # into the old one, and continue to use the old one.
5046 ad = tns._replaceComponent(ad, old_ad._updateFromOther(ad))
5047 else:
5048 tns.addCategoryObject('attributeDeclaration', ad.name(), ad)
5049 assert ad is not None
5050 return ad
5051
5053 local_name = agd.name()
5054 assert self.__targetNamespace
5055 tns = self.targetNamespace()
5056 old_agd = tns.attributeGroupDefinitions().get(local_name)
5057 if (old_agd is not None) and (old_agd != agd):
5058 if not old_agd._allowUpdateFromOther(agd):
5059 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute group definition %s' % (tns.createExpandedName(local_name),))
5060
5061 # Copy schema-related information from the new definition
5062 # into the old one, and continue to use the old one.
5063 tns._replaceComponent(agd, old_agd._updateFromOther(agd))
5064 else:
5065 tns.addCategoryObject('attributeGroupDefinition', agd.name(), agd)
5066 assert agd is not None
5067 return agd
5068
5070 return 'SCH[%s]' % (self.location(),)
5071
5074 """Add to the schema the definitions of the built-in types of XMLSchema.
5075 This should only be invoked by L{pyxb.namespace} when the built-in
5076 namespaces are initialized. """
5077 # Add the ur type
5078 #schema = namespace.schema()
5079 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True)
5080 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True))
5081 assert td.isResolved()
5082 # Add the simple ur type
5083 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True))
5084 assert td.isResolved()
5085 # Add definitions for all primitive and derived simple types
5086 pts_std_map = {}
5087 for dtc in datatypes._PrimitiveDatatypes:
5088 name = dtc.__name__.rstrip('_')
5089 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc))
5090 assert td.isResolved()
5091 assert dtc.SimpleTypeDefinition() == td
5092 pts_std_map.setdefault(dtc, td)
5093 for dtc in datatypes._DerivedDatatypes:
5094 name = dtc.__name__.rstrip('_')
5095 parent_std = pts_std_map[dtc.XsdSuperType()]
5096 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc))
5097 assert td.isResolved()
5098 assert dtc.SimpleTypeDefinition() == td
5099 pts_std_map.setdefault(dtc, td)
5100 for dtc in datatypes._ListDatatypes:
5101 list_name = dtc.__name__.rstrip('_')
5102 element_name = dtc._ItemType.__name__.rstrip('_')
5103 element_std = schema.targetNamespace().typeDefinitions().get(element_name)
5104 assert element_std is not None
5105 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc))
5106 assert td.isResolved()
5107 global _PastAddBuiltInTypes
5108 _PastAddBuiltInTypes = True
5109
5110 return schema
5111
5112 import sys
5113 import pyxb.namespace.builtin
5114 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__])
5115
5116 ## Local Variables:
5117 ## fill-column:78
5118 ## End:
5119
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Wed Nov 7 19:27:38 2012 | http://epydoc.sourceforge.net |