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