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