1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """This module contains support classes from which schema-specific bindings
17 inherit, and that describe the content models of those schema."""
18
19 import logging
20 import pyxb
21 import xml.dom
22 import pyxb.utils.domutils as domutils
23 import pyxb.utils.utility as utility
24 import types
25 import pyxb.namespace
26 import collections
27 from pyxb.namespace.builtin import XMLSchema_instance as XSI
28
29 _log = logging.getLogger(__name__)
32
33
34
35
36 _validationConfig_ = pyxb.GlobalValidationConfig
37
38 @classmethod
40 """Set the validation configuration for this class."""
41 cls._validationConfig_ = validation_config
42
43 @classmethod
45 """The L{pyxb.ValidationConfig} instance that applies to this class.
46
47 By default this will reference L{pyxb.GlobalValidationConfig}."""
48 return cls._validationConfig_
49
51 """Set the validation configuration for this instance."""
52 self._validationConfig_ = validation_config
53
55 """The L{pyxb.ValidationConfig} instance that applies to this instance.
56
57 By default this will reference the class value from
58 L{_GetValidationConfig}, which defaults to
59 L{pyxb.GlobalValidationConfig}."""
60 return self._validationConfig_
61
62
63 _validationConfig = property(__getValidationConfig)
64
65 @classmethod
76
87
88 _ExpandedName = None
89 """The expanded name of the component."""
90
91 _XSDLocation = None
92 """Where the definition can be found in the originating schema."""
93
94 _ReservedSymbols = set([ 'validateBinding', 'toDOM', 'toxml', 'Factory', 'property' ])
95
96 if pyxb._CorruptionDetectionEnabled:
101
102 _PyXBFactoryKeywords = ( '_dom_node', '_fallback_namespace', '_from_xml',
103 '_apply_whitespace_facet', '_validate_constraints',
104 '_require_value', '_nil', '_element', '_apply_attributes',
105 '_convert_string_values', '_location' )
106 """Keywords that are interpreted by __new__ or __init__ in one or more
107 classes in the PyXB type hierarchy. All these keywords must be removed
108 before invoking base Python __init__ or __new__."""
109
110
111
112
113 _Abstract = False
114
116 """Return a L{namespace context <pyxb.binding.NamespaceContext>}
117 associated with the binding instance.
118
119 This will return C{None} unless something has provided a context to
120 the instance. Context is provided when instances are generated by the
121 DOM and SAX-based translators."""
122 return self.__namespaceContext
123 - def _setNamespaceContext (self, namespace_context):
124 """Associate a L{namespace context <pyxb.binding.NamespaceContext>}
125 with the binding instance."""
126 self.__namespaceContext = namespace_context
127 return self
128 __namespaceContext = None
129
131 """Associate an element binding with the instance.
132
133 Since the value of a binding instance reflects only its content, an
134 associated element is necessary to generate an XML document or DOM
135 tree.
136
137 @param elt: the L{pyxb.binding.basis.element} instance associated with
138 the value. This may be C{None} when disassociating a value from a
139 specific element."""
140 import pyxb.binding.content
141 assert (elt is None) or isinstance(elt, element)
142 self.__element = elt
143 return self
145 """Return a L{pyxb.binding.basis.element} associated with the binding
146 instance.
147
148 This will return C{None} unless an element has been associated.
149 Constructing a binding instance using the element instance will add
150 this association.
151 """
152 return self.__element
153 __element = None
154
155 __xsiNil = None
157 """Indicate whether this instance is U{nil
158 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
159
160 The value is set by the DOM and SAX parsers when building an instance
161 from a DOM element with U{xsi:nil
162 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set to C{true}.
163
164 @return: C{None} if the element used to create the instance is not
165 U{nillable<http://www.w3.org/TR/xmlschema-1/#nillable>}.
166 If it is nillable, returns C{True} or C{False} depending on
167 whether the instance itself is U{nil<http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
168 """
169 return self.__xsiNil
171 """Set the xsi:nil property of the instance.
172
173 @param nil: C{True} if the value of xsi:nil should be C{true},
174 C{False} if the value of xsi:nil should be C{false}.
175
176 @raise pyxb.NoNillableSupportError: the instance is not associated
177 with an element that is L{nillable
178 <pyxb.binding.basis.element.nillable>}.
179 """
180 if self.__xsiNil is None:
181 raise pyxb.NoNillableSupportError(self)
182 self.__xsiNil = not not nil
183 if self.__xsiNil:
184
185
186 self._resetContent(reset_elements=True)
187
188 - def _resetContent (self, reset_elements=False):
189 """Reset the content of an element value.
190
191 This is not a public method.
192
193 For simple types, this does nothing. For complex types, this clears the
194 L{content<complexTypeDefinition.content>} array, removing all
195 non-element content from the instance. It optionally also removes all
196 element content.
197
198 @param reset_elements: If C{False} (default) only the content array is
199 cleared, which has the effect of removing any preference for element
200 order when generating a document. If C{True}, the element content
201 stored within the binding is also cleared, leaving it with no content
202 at all.
203
204 @note: This is not the same thing as L{complexTypeDefinition.reset},
205 which unconditionally resets attributes and element and non-element
206 content.
207 """
208 pass
209
210 __constructedWithValue = False
224
225
226
227
228 __WarnedUnassociatedElement = False
229
240
241 @classmethod
243 """Method invoked upon entry to the Factory method.
244
245 This method is entitled to modify the keywords array. It can also
246 return a state value which is passed to _postFactory_vx."""
247 return None
248
249 - def _postFactory_vx (cls, state):
250 """Method invoked prior to leaving the Factory method.
251
252 This is an instance method, and is given the state that was returned
253 by _PreFactory_vx."""
254 return None
255
256 @classmethod
258 """Provide a common mechanism to create new instances of this type.
259
260 The class constructor won't do, because you can't create
261 instances of union types.
262
263 This method may be overridden in subclasses (like STD_union). Pre-
264 and post-creation actions can be customized on a per-class instance by
265 overriding the L{_PreFactory_vx} and L{_postFactory_vx} methods.
266
267 @keyword _dom_node: If provided, the value must be a DOM node, the
268 content of which will be used to set the value of the instance.
269
270 @keyword _location: An optional instance of
271 L{pyxb.utils.utility.Location} showing the origin the binding. If
272 C{None}, a value from C{_dom_node} is used if available.
273
274 @keyword _from_xml: If C{True}, the input must be either a DOM node or
275 a unicode string comprising a lexical representation of a value. This
276 is a further control on C{_apply_whitespace_facet} and arises from
277 cases where the lexical and value representations cannot be
278 distinguished by type. The default value is C{True} iff C{_dom_node}
279 is not C{None}.
280
281 @keyword _apply_whitespace_facet: If C{True} and this is a
282 simpleTypeDefinition with a whiteSpace facet, the first argument will
283 be normalized in accordance with that facet prior to invoking the
284 parent constructor. The value is always C{True} if text content is
285 extracted from a C{_dom_node}, and otherwise defaults to the defaulted
286 value of C{_from_xml}.
287
288 @keyword _validate_constraints: If C{True}, any constructed value is
289 checked against constraints applied to the union as well as the member
290 type.
291
292 @keyword _require_value: If C{False} (default), it is permitted to
293 create a value without an initial value. If C{True} and no initial
294 value was provided, causes L{pyxb.SimpleContentAbsentError} to be raised.
295 Only applies to simpleTypeDefinition instances; this is used when
296 creating values from DOM nodes.
297 """
298
299
300 dom_node = kw.get('_dom_node')
301 location = kw.get('_location')
302 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
303 location = dom_node._location()
304 kw.setdefault('_from_xml', dom_node is not None)
305 used_cls = cls._SupersedingClass()
306 state = used_cls._PreFactory_vx(args, kw)
307 rv = cls._DynamicCreate(*args, **kw)
308 rv._postFactory_vx(state)
309 if (rv._location is None) and (location is not None):
310 rv._setLocation(location)
311 return rv
312
317
318 @classmethod
320 """Return C{True} iff this is the ur-type.
321
322 The only ur-type is {http://www.w3.org/2001/XMLSchema}anyType. The
323 implementation of this method is overridden for
324 L{pyxb.binding.datatypes.anyType}."""
325 return False
326
327 @classmethod
333
334 @classmethod
336 """Return a variant of the value that is compatible with this type.
337
338 Compatibility is defined relative to the type definition associated
339 with the element. The value C{None} is always compatible. If
340 C{value} has a Python type (e.g., C{int}) that is a superclass of the
341 required L{_TypeBinding_mixin} class (e.g., C{xs:byte}), C{value} is
342 used as a constructor parameter to return a new instance of the
343 required type. Note that constraining facets are applied here if
344 necessary (e.g., although a Python C{int} with value C{500} is
345 type-compatible with C{xs:byte}, it is outside the value space, and
346 compatibility will fail).
347
348 @keyword _convert_string_values: If C{True} (default) and the incoming value is
349 a string, an attempt will be made to form a compatible value by using
350 the string as a constructor argument to the this class. This flag is
351 set to C{False} when testing automaton transitions.
352
353 @raise pyxb.SimpleTypeValueError: if the value is not both
354 type-consistent and value-consistent with the element's type.
355 """
356 convert_string_values = kw.get('_convert_string_values', True)
357
358 if value is None:
359 return None
360
361 if isinstance(value, cls):
362
363
364 return value
365 value_type = type(value)
366
367 if str == value_type:
368 value_type = unicode
369
370
371
372 if issubclass(cls, value_type):
373 return cls(value)
374
375
376
377 if isinstance(value, int) and issubclass(cls, long):
378 return cls(value)
379
380
381 if isinstance(value, bool) and issubclass(cls, pyxb.binding.datatypes.boolean):
382 return cls(value)
383
384
385
386 if convert_string_values and (unicode == value_type):
387 return cls(value)
388
389
390 if issubclass(cls, STD_union):
391 for mt in cls._MemberTypes:
392 try:
393 return mt._CompatibleValue(value, **kw)
394 except:
395 pass
396
397
398 if (pyxb.binding.datatypes.anySimpleType == cls) and issubclass(value_type, simpleTypeDefinition):
399 return value
400 if pyxb.binding.datatypes.anyType == cls:
401 if not isinstance(value, _TypeBinding_mixin):
402 _log.info('Created %s instance from value of type %s', cls._ExpandedName, type(value))
403 value = cls(value)
404 return value
405
406
407
408 if isinstance(value, pyxb.BIND):
409 return value.createInstance(cls.Factory, **kw)
410
411
412 if cls._IsSimpleTypeContent():
413
414
415
416 rv = cls.Factory(value)
417 if isinstance(rv, simpleTypeDefinition) and (rv == value):
418 return rv
419 if isinstance(rv, complexTypeDefinition) and (rv.value() == value):
420 return rv
421
422
423
424
425
426
427 raise pyxb.SimpleTypeValueError(cls, value)
428
429 @classmethod
431 """Return True iff the content of this binding object is a simple type.
432
433 This is true only for descendents of simpleTypeDefinition and instances
434 of complexTypeDefinition that have simple type content."""
435 raise pyxb.LogicError('Failed to override _TypeBinding_mixin._IsSimpleTypeContent')
436
437
438
439
440 _AttributeWildcard = None
441
442 _AttributeMap = { }
443 """Map from expanded names to AttributeUse instances. Non-empty only in
444 L{complexTypeDefinition} subclasses."""
445
446 @classmethod
461
463 """Invoke self._setAttribute based on node attributes and keywords.
464
465 Though attributes can only legally appear in complexTypeDefinition
466 instances, delayed conditional validation requires caching them in
467 simpleTypeDefinition.
468
469 @param kw: keywords passed to the constructor. This map is mutated by
470 the call: keywords corresponding to recognized attributes are removed.
471
472 @param dom_node: an xml.dom Node instance, possibly C{None}
473 """
474
475
476 attribute_settings = { }
477 if dom_node is not None:
478 attribute_settings.update(self.__AttributesFromDOM(dom_node))
479 for fu in self._AttributeMap.itervalues():
480 iv = kw.pop(fu.id(), None)
481 if iv is not None:
482 attribute_settings[fu.name()] = iv
483 for (attr_en, value_lex) in attribute_settings.iteritems():
484 self._setAttribute(attr_en, value_lex)
485
486 - def toDOM (self, bds=None, parent=None, element_name=None):
487 """Convert this instance to a DOM node.
488
489 The name of the top-level element is either the name of the L{element}
490 instance associated with this instance, or the XML name of the type of
491 this instance.
492
493 @param bds: Support for customizing the generated document
494 @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
495 @param parent: If C{None}, a standalone document is created;
496 otherwise, the created element is a child of the given element.
497 @type parent: C{xml.dom.Element} or C{None}
498 @rtype: C{xml.dom.Document}
499 """
500
501 if bds is None:
502 bds = domutils.BindingDOMSupport()
503 need_xsi_type = bds.requireXSIType()
504 if isinstance(element_name, (str, unicode)):
505 element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
506 if (element_name is None) and (self._element() is not None):
507 element_binding = self._element()
508 element_name = element_binding.name()
509 need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
510 if element_name is None:
511 raise pyxb.UnboundElementError(self)
512 element = bds.createChildElement(element_name, parent)
513 if need_xsi_type:
514 val_type_qname = self._ExpandedName.localName()
515 tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
516 if tns_prefix is not None:
517 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
518 bds.addAttribute(element, XSI.type, val_type_qname)
519 self._toDOM_csc(bds, element)
520 bds.finalize()
521 return bds.document()
522
523 - def toxml (self, encoding=None, bds=None, root_only=False):
524 """Shorthand to get the object as an XML document.
525
526 If you want to set the default namespace, pass in a pre-configured
527 C{bds}.
528
529 @param encoding: The encoding to be used. See
530 @C{xml.dom.Node.toxml()} for a description of why you should always
531 pass @C{'utf-8'} here. Because this method follows the contract of
532 the corresponding C{xml.dom.Node} method, it does not automatically
533 get the default PyXB output encoding.
534
535 @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
536 to use for creation. If not provided (default), a new generic one is
537 created.
538 """
539 dom = self.toDOM(bds)
540 if root_only:
541 dom = dom.documentElement
542 return dom.toxml(encoding)
543
549
551 """Override in subclasses for type-specific validation of instance
552 content.
553
554 @return: C{True} if the instance validates
555 @raise pyxb.BatchContentValidationError: complex content does not match model
556 @raise pyxb.SimpleTypeValueError: simple content fails to satisfy constraints
557 """
558 raise NotImplementedError('%s._validateBinding_vx' % (type(self).__name__,))
559
561 """Check whether the binding content matches its content model.
562
563 @return: C{True} if validation succeeds.
564 @raise pyxb.BatchContentValidationError: complex content does not match model
565 @raise pyxb.SimpleTypeValueError: attribute or simple content fails to satisfy constraints
566 """
567 if self._performValidation():
568 self._validateBinding_vx()
569 return True
570
572 """Inform content model that all additions have been provided.
573
574 This is used to resolve any pending non-determinism when the content
575 of an element is provided through a DOM assignment or through
576 positional arguments in a constructor."""
577 return self
578
579 - def _postDOMValidate (self):
580 self.validateBinding()
581 return self
582
583 @classmethod
585 """Return the best descriptive name for the type of the instance.
586
587 This is intended to be a human-readable value used in diagnostics, and
588 is the expanded name if the type has one, or the Python type name if
589 it does not."""
590 if cls._ExpandedName is not None:
591 return unicode(cls._ExpandedName)
592 return unicode(cls)
593
595 """The best name available for this instance in diagnostics.
596
597 If the instance is associated with an element, it is the element name;
598 otherwise it is the best name for the type of the instance per L{_Name}."""
599 if self.__element is None:
600 return self._Name()
601 return unicode(self.__element.name())
602
604 """Helper to allow overriding the implementation class.
605
606 Generally we'll want to augment the generated bindings by subclassing
607 them, and adding functionality to the subclass. This mix-in provides a
608 way to communicate the existence of the superseding subclass back to the
609 binding infrastructure, so that when it creates an instance it uses the
610 subclass rather than the unaugmented binding class.
611
612 When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
613 invoked on the raw class passing in the superseding subclass. E.g.::
614
615 class mywsdl (raw.wsdl):
616 pass
617 raw.wsdl._SetSupersedingClass(mywsdl)
618
619 """
620
621 @classmethod
623 return '_%s__SupersedingClass' % (cls.__name__,)
624
625 @classmethod
627 return '_%s__AlternativeConstructor' % (cls.__name__,)
628
629 @classmethod
633
634 @classmethod
636 """Return the class stored in the class reference attribute."""
637 rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
638 if isinstance(rv, tuple):
639 rv = rv[0]
640 return rv
641
642 @classmethod
644 """Set the class reference attribute.
645
646 @param superseding: A Python class that is a subclass of this class.
647 """
648 assert (superseding is None) or issubclass(superseding, cls)
649 if superseding is None:
650 cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
651 else:
652 setattr(cls, cls.__SupersedingClassAttribute(), superseding)
653 return superseding
654
655 @classmethod
657 attr = cls.__AlternativeConstructorAttribute()
658 if alternative_constructor is None:
659 cls.__dict__.pop(attr, None)
660 else:
661
662
663
664 setattr(cls, attr, (alternative_constructor,))
665 assert cls._AlternativeConstructor() == alternative_constructor
666 return alternative_constructor
667
668 @classmethod
678
679 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
680 """L{simpleTypeDefinition} is a base class that is part of the
681 hierarchy of any class that represents the Python datatype for a
682 L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
683
684 @note: This class, or a descendent of it, must be the first class
685 in the method resolution order when a subclass has multiple
686 parents. Otherwise, constructor keyword arguments may not be
687 removed before passing them on to Python classes that do not
688 accept them.
689 """
690
691
692
693
694 __FacetMap = {}
695
696 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
697 'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
698 'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
699 'PythonLiteral', 'pythonLiteral',
700 'SimpleTypeDefinition' ]))
701 """Symbols that remain the responsibility of this class. Any
702 public symbols in generated binding subclasses are deconflicted
703 by providing an alternative name in the subclass. (There
704 currently are no public symbols in generated SimpleTypeDefinion
705 bindings."""
706
707
708
709
710
711 __FacetMapAttributeNameMap = { }
712 @classmethod
714 """ """
715 '''
716 if cls == simpleTypeDefinition:
717 return '_%s__FacetMap' % (cls.__name__.strip('_'),)
718
719 # It is not uncommon for a class in one namespace to extend a class of
720 # the same name in a different namespace, so encode the namespace URI
721 # in the attribute name (if it is part of a namespace).
722 ns_uri = ''
723 try:
724 ns_uri = cls._ExpandedName.namespaceURI()
725 except Exception:
726 pass
727 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
728 '''
729 nm = cls.__FacetMapAttributeNameMap.get(cls)
730 if nm is None:
731 nm = cls.__name__
732 if nm.endswith('_'):
733 nm += '1'
734 if cls == simpleTypeDefinition:
735 nm = '_%s__FacetMap' % (nm,)
736 else:
737
738
739
740 ns_uri = ''
741 try:
742 ns_uri = cls._ExpandedName.namespaceURI()
743 except Exception:
744 pass
745 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
746 cls.__FacetMapAttributeNameMap[cls] = nm
747 return nm
748
749 @classmethod
751 """Return a reference to the facet map for this datatype.
752
753 The facet map is a map from leaf facet classes to instances of those
754 classes that constrain or otherwise apply to the lexical or value
755 space of the datatype. Classes may inherit their facet map from their
756 superclass, or may create a new class instance if the class adds a new
757 constraint type.
758
759 @raise AttributeError: if the facet map has not been defined"""
760 return getattr(cls, cls.__FacetMapAttributeName())
761
762 @classmethod
764 """Initialize the facet map for this datatype.
765
766 This must be called exactly once, after all facets belonging to the
767 datatype have been created.
768
769 @raise pyxb.LogicError: if called multiple times (on the same class)
770 @raise pyxb.LogicError: if called when a parent class facet map has not been initialized
771 :return: the facet map"""
772 fm = None
773 try:
774 fm = cls._FacetMap()
775 except AttributeError:
776 pass
777 if fm is not None:
778 raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
779
780
781
782
783
784 source_class = cls
785 while fm is None:
786
787
788 for super_class in source_class.mro():
789 assert super_class is not None
790 if (super_class == simpleTypeDefinition):
791 break
792 if issubclass(super_class, simpleTypeDefinition):
793 try:
794 fm = super_class._FacetMap()
795 break
796 except AttributeError:
797 pass
798 if fm is None:
799 try:
800 source_class = source_class.XsdSuperType()
801 except AttributeError:
802 source_class = None
803 if source_class is None:
804 fm = { }
805 if fm is None:
806 raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
807 fm = fm.copy()
808 for facet in args:
809 fm[type(facet)] = facet
810 setattr(cls, cls.__FacetMapAttributeName(), fm)
811 return fm
812
813 @classmethod
816
817 @classmethod
819 """Pre-process the arguments.
820
821 This is used before invoking the parent constructor. One application
822 is to apply the whitespace facet processing; if such a request is in
823 the keywords, it is removed so it does not propagate to the
824 superclass. Another application is to convert the arguments from a
825 string to a list. Binding-specific applications are performed in the
826 overloaded L{_ConvertArguments_vx} method."""
827 dom_node = kw.pop('_dom_node', None)
828 from_xml = kw.get('_from_xml', dom_node is not None)
829 if dom_node is not None:
830 text_content = domutils.ExtractTextContent(dom_node)
831 if text_content is not None:
832 args = (domutils.ExtractTextContent(dom_node),) + args
833 kw['_apply_whitespace_facet'] = True
834 apply_whitespace_facet = kw.pop('_apply_whitespace_facet', from_xml)
835 if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
836 cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
837 if cf_whitespace is not None:
838 norm_str = unicode(cf_whitespace.normalizeString(args[0]))
839 args = (norm_str,) + args[1:]
840 kw['_from_xml'] = from_xml
841 return cls._ConvertArguments_vx(args, kw)
842
843
844
845
846
847
848
849
850
851
852
854
855 kw.pop('_validate_constraints', None)
856 kw.pop('_require_value', None)
857 kw.pop('_element', None)
858 kw.pop('_fallback_namespace', None)
859 kw.pop('_apply_attributes', None)
860 kw.pop('_nil', None)
861
862 dom_node = kw.get('_dom_node')
863 args = cls._ConvertArguments(args, kw)
864 kw.pop('_from_xml', dom_node is not None)
865 kw.pop('_location', None)
866 assert issubclass(cls, _TypeBinding_mixin)
867 try:
868 return super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
869 except ValueError:
870 raise pyxb.SimpleTypeValueError(cls, args)
871 except OverflowError:
872 raise pyxb.SimpleTypeValueError(cls, args)
873
874
875
877 """Initialize a newly created STD instance.
878
879 Usually there is one positional argument, which is a value that can be
880 converted to the underlying Python type.
881
882 @keyword _validate_constraints: If True (default if validation is
883 enabled), the newly constructed value is checked against its
884 constraining facets.
885 @type _validate_constraints: C{bool}
886
887 @keyword _apply_attributes: If C{True} (default), any attributes
888 present in the keywords or DOM node are applied. Normally presence of
889 such an attribute should produce an error; when creating simple
890 content for a complex type we need the DOM node, but do not want to
891 apply the attributes, so we bypass the application.
892 """
893
894 validate_constraints = kw.pop('_validate_constraints', self._validationConfig.forBinding)
895 require_value = kw.pop('_require_value', False)
896
897 dom_node = kw.get('_dom_node')
898 location = kw.get('_location')
899 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
900 location = dom_node._location()
901 apply_attributes = kw.pop('_apply_attributes', True)
902
903
904 args = self._ConvertArguments(args, kw)
905 try:
906 super(simpleTypeDefinition, self).__init__(*args, **kw)
907 except OverflowError:
908 raise pyxb.SimpleTypeValueError(type(self), args)
909 if apply_attributes and (dom_node is not None):
910 self._setAttributesFromKeywordsAndDOM(kw, dom_node)
911 if require_value and (not self._constructedWithValue()):
912 if location is None:
913 location = self._location()
914 raise pyxb.SimpleContentAbsentError(self, location)
915 if validate_constraints and not kw.pop('_nil', False):
916 self.xsdConstraintsOK(location)
917
918
919
920
921
922
923 @classmethod
925 return '_%s__SimpleTypeDefinition' % (cls.__name__,)
926
927 @classmethod
929 """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
930 associated with this binding."""
931 attr_name = cls.__STDAttrName()
932 if hasattr(cls, attr_name):
933 old_value = getattr(cls, attr_name)
934 if old_value != std:
935 raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
936 setattr(cls, attr_name, std)
937
938 @classmethod
940 """Return the SimpleTypeDefinition instance for the given
941 class.
942
943 This should only be invoked when generating bindings. An STD must
944 have been associated with the class using L{_SimpleTypeDefinition}."""
945 attr_name = cls.__STDAttrName()
946 assert hasattr(cls, attr_name)
947 return getattr(cls, attr_name)
948
949 @classmethod
951 """Convert from a python value to a string usable in an XML
952 document.
953
954 This should be implemented in the subclass."""
955 raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
956
958 """Return text suitable for representing the value of this
959 instance in an XML document.
960
961 The base class implementation delegates to the object class's
962 XsdLiteral method."""
963 if self._isNil():
964 return ''
965 return self.XsdLiteral(self)
966
967 @classmethod
969 """Find the nearest parent class in the PST hierarchy.
970
971 The value for anySimpleType is None; for all others, it's a
972 primitive or derived PST descendent (including anySimpleType)."""
973 for sc in cls.mro():
974 if sc == cls:
975 continue
976 if simpleTypeDefinition == sc:
977
978
979
980 return cls._XsdBaseType
981 if issubclass(sc, simpleTypeDefinition):
982 return sc
983 raise pyxb.LogicError('No supertype found for %s' % (cls,))
984
985 @classmethod
987 """Pre-extended class method to verify other things before
988 checking constraints.
989
990 This is used for list types, to verify that the values in the
991 list are acceptable, and for token descendents, to check the
992 lexical/value space conformance of the input.
993 """
994 super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
995 return super_fn(value)
996
997
998
999 __ClassFacetSequence = { }
1000
1001 @classmethod
1003 """Validate the given value against the constraints on this class.
1004
1005 @raise pyxb.SimpleTypeValueError: if any constraint is violated.
1006 """
1007
1008 value = cls._XsdConstraintsPreCheck_vb(value)
1009
1010 facet_values = cls.__ClassFacetSequence.get(cls)
1011 if facet_values is None:
1012
1013
1014 classes = [ _x for _x in cls.mro() if issubclass(_x, simpleTypeDefinition) ]
1015 classes.reverse()
1016 cache_result = True
1017 facet_values = []
1018 for clazz in classes:
1019
1020
1021
1022
1023
1024
1025 try:
1026 clazz_facets = clazz._FacetMap().values()
1027 except AttributeError:
1028 cache_result = False
1029 clazz_facets = []
1030 for v in clazz_facets:
1031 if not (v in facet_values):
1032 facet_values.append(v)
1033 if cache_result:
1034 cls.__ClassFacetSequence[cls] = facet_values
1035 for f in facet_values:
1036 if not f.validateConstraint(value):
1037 raise pyxb.SimpleFacetValueError(cls, value, f, location)
1038 return value
1039
1041 """Validate the value of this instance against its constraints."""
1042 return self.XsdConstraintsOK(self, location)
1043
1048
1049 @classmethod
1051 """Return the length of the given value.
1052
1053 The length is calculated by a subclass implementation of
1054 _XsdValueLength_vx in accordance with
1055 http://www.w3.org/TR/xmlschema-2/#rf-length.
1056
1057 The return value is a non-negative integer, or C{None} if length
1058 constraints should be considered trivially satisfied (as with
1059 QName and NOTATION).
1060
1061 @raise pyxb.LogicError: the provided value is not an instance of cls.
1062 @raise pyxb.LogicError: an attempt is made to calculate a length for
1063 an instance of a type that does not support length calculations.
1064 """
1065 assert isinstance(value, cls)
1066 if not hasattr(cls, '_XsdValueLength_vx'):
1067 raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
1068 return cls._XsdValueLength_vx(value)
1069
1071 """Return the length of this instance within its value space.
1072
1073 See XsdValueLength."""
1074 return self.XsdValueLength(self)
1075
1076 @classmethod
1078 """Return a string which can be embedded into Python source to
1079 represent the given value as an instance of this class."""
1080 class_name = cls.__name__
1081 return '%s(%s)' % (class_name, repr(value))
1082
1084 """Return a string which can be embedded into Python source to
1085 represent the value of this instance."""
1086 return self.PythonLiteral(self)
1087
1092
1093 @classmethod
1095 """STDs have simple type content."""
1096 return True
1097
1098 @classmethod
1106
1107 @classmethod
1109
1110 """NB: Invoking this on a value that is a list will, if necessary,
1111 replace the members of the list with new values that are of the
1112 correct item type. This is permitted because only with lists is it
1113 possible to bypass the normal content validation (by invoking
1114 append/extend on the list instance)."""
1115 if value is None:
1116 raise pyxb.SimpleTypeValueError(cls, value)
1117 value_class = cls
1118 if issubclass(cls, STD_list):
1119 if not isinstance(value, collections.Iterable):
1120 raise pyxb.SimpleTypeValueError(cls, value)
1121 for v in value:
1122 if not cls._ItemType._IsValidValue(v):
1123 raise pyxb.SimpleListValueError(cls, v)
1124 else:
1125 if issubclass(cls, STD_union):
1126 value_class = None
1127 for mt in cls._MemberTypes:
1128 if mt._IsValidValue(value):
1129 value_class = mt
1130 break
1131 if value_class is None:
1132 raise pyxb.SimpleUnionValueError(cls, value)
1133
1134 if not isinstance(value, value_class):
1135 raise pyxb.SimpleTypeValueError(cls, value)
1136 value_class.XsdConstraintsOK(value)
1137
1140
1143
1149
1150 @classmethod
1151 - def _description (cls, name_only=False, user_documentation=True):
1152 name = cls._Name()
1153 if name_only:
1154 return name
1155 desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
1156 if user_documentation and (cls._Documentation is not None):
1157 desc.extend(["\n", cls._Documentation])
1158 return ''.join(desc)
1159
1161 """Base class for union datatypes.
1162
1163 This class descends only from simpleTypeDefinition. A pyxb.LogicError is
1164 raised if an attempt is made to construct an instance of a subclass of
1165 STD_union. Values consistent with the member types are constructed using
1166 the Factory class method. Values are validated using the _ValidatedMember
1167 class method.
1168
1169 Subclasses must provide a class variable _MemberTypes which is a
1170 tuple of legal members of the union."""
1171
1172 _MemberTypes = None
1173 """A list of classes which are permitted as values of the union."""
1174
1175
1176
1177
1178 __FacetMap = {}
1179
1180 @classmethod
1182 """Given a value, attempt to create an instance of some member of this
1183 union. The first instance which can be legally created is returned.
1184
1185 @keyword _validate_constraints: If C{True} (default if validation is
1186 enabled), any constructed value is checked against constraints applied
1187 to the union as well as the member type.
1188
1189 @raise pyxb.SimpleTypeValueError: no member type will permit creation of
1190 an instance from the parameters in C{args} and C{kw}.
1191 """
1192
1193 used_cls = cls._SupersedingClass()
1194 state = used_cls._PreFactory_vx(args, kw)
1195
1196 rv = None
1197
1198 validate_constraints = kw.get('_validate_constraints', cls._GetValidationConfig().forBinding)
1199 assert isinstance(validate_constraints, bool)
1200 if 0 < len(args):
1201 arg = args[0]
1202 try:
1203 rv = cls._ValidatedMember(arg)
1204 except pyxb.SimpleTypeValueError:
1205 pass
1206 if rv is None:
1207 kw['_validate_constraints'] = True
1208 for mt in cls._MemberTypes:
1209 try:
1210 rv = mt.Factory(*args, **kw)
1211 break
1212 except pyxb.SimpleTypeValueError:
1213 pass
1214 except (ValueError, OverflowError):
1215 pass
1216 except:
1217 pass
1218 location = None
1219 if kw is not None:
1220 location = kw.get('_location')
1221 if rv is not None:
1222 if validate_constraints:
1223 cls.XsdConstraintsOK(rv, location)
1224 rv._postFactory_vx(state)
1225 return rv
1226
1227
1228 raise pyxb.SimpleUnionValueError(cls, args, location)
1229
1230 @classmethod
1247
1249 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1250
1252 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1253
1254 @classmethod
1255 - def _description (cls, name_only=False, user_documentation=True):
1262
1263 @classmethod
1267
1268
1269 -class STD_list (simpleTypeDefinition, types.ListType):
1270 """Base class for collection datatypes.
1271
1272 This class descends from the Python list type, and incorporates
1273 simpleTypeDefinition. Subclasses must define a class variable _ItemType
1274 which is a reference to the class of which members must be instances."""
1275
1276 _ItemType = None
1277 """A reference to the binding class for items within this list."""
1278
1279
1280
1281 __FacetMap = {}
1282
1283 @classmethod
1285 """Verify that the given value is permitted as an item of this list.
1286
1287 This may convert the value to the proper type, if it is
1288 compatible but not an instance of the item type. Returns the
1289 value that should be used as the item, or raises an exception
1290 if the value cannot be converted.
1291
1292 @param kw: optional dictionary of standard constructor keywords used
1293 when exceptions must be built. In particular, C{_location} may be
1294 useful.
1295 """
1296 if isinstance(value, cls._ItemType):
1297 pass
1298 elif issubclass(cls._ItemType, STD_union):
1299 value = cls._ItemType._ValidatedMember(value)
1300 else:
1301 try:
1302 value = cls._ItemType(value)
1303 except (pyxb.SimpleTypeValueError, TypeError):
1304 location = None
1305 if kw is not None:
1306 location = kw.get('_location')
1307 raise pyxb.SimpleListValueError(cls, value, location)
1308 return value
1309
1310 @classmethod
1312
1313
1314 if 0 < len(args):
1315 arg1 = args[0]
1316 if isinstance(arg1, types.StringTypes):
1317 args = (arg1.split(),) + args[1:]
1318 arg1 = args[0]
1319 if isinstance(arg1, collections.Iterable):
1320 new_arg1 = [ cls._ValidatedItem(_v, kw) for _v in arg1 ]
1321 args = (new_arg1,) + args[1:]
1322 super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
1323 return super_fn(args, kw)
1324
1325 @classmethod
1328
1329 @classmethod
1331 """Convert from a binding value to a string usable in an XML document."""
1332 return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
1333
1334 @classmethod
1335 - def _description (cls, name_only=False, user_documentation=True):
1341
1342
1343 @classmethod
1346
1347
1350
1356
1357
1360
1361
1364
1365
1366
1369
1370 - def extend (self, x, _from_xml=False):
1372
1375
1376 - def index (self, x, *args):
1378
1381
1384
1385 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1386 """Class that represents a schema element within a binding.
1387
1388 This gets a little confusing. Within a schema, the
1389 L{pyxb.xmlschema.structures.ElementDeclaration} type represents an
1390 U{element
1391 declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>}.
1392 Those declarations may be global (have a name that is visible in the
1393 namespace), or local (have a name that is visible only within a complex
1394 type definition). Further, local (but not global) declarations may have a
1395 reference to a global declaration (which might be in a different
1396 namespace).
1397
1398 Within a PyXB binding, the element declarations from the original complex
1399 type definition that have the same
1400 U{QName<http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-qname>}
1401 (after deconflicting the
1402 U{LocalPart<http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-LocalPart>})
1403 are associated with an attribute in the class for the complex type. Each
1404 of these attributes is defined via a
1405 L{pyxb.binding.content.ElementDeclaration} which provides the mechanism by
1406 which the binding holds values associated with that element.
1407
1408 Furthermore, in the FAC-based content model each schema element
1409 declaration is associated with an
1410 L{ElementUse<pyxb.binding.content.ElementUse>} instance to locate the
1411 point in the schema where content came from. Instances that refer to the
1412 same schema element declaration share the same underlying
1413 L{pyxb.binding.content.ElementDeclaration}.
1414
1415 This element isn't any of those elements. This element is the type used
1416 for an attribute which associates the name of a element with data required
1417 to represent it, all within a particular scope (a module for global scope,
1418 the binding class for a complex type definition for local scope). From
1419 the perspective of a PyXB user they look almost like a class, in that you
1420 can call them to create instances of the underlying complex type.
1421
1422 Global and local elements are represented by instances of this class.
1423 """
1424
1426 """The expanded name of the element within its scope."""
1427 return self.__name
1428 __name = None
1429
1433 __typeDefinition = None
1434
1436 """The L{pyxb.utils.utility.Location} where the element appears in the schema."""
1437 return self.__xsdLocation
1438 __xsdLocation = None
1439
1441 """The scope of the element. This is either C{None}, representing a
1442 top-level element, or an instance of C{complexTypeDefinition} for
1443 local elements."""
1444 return self.__scope
1445 __scope = None
1446
1448 """Indicate whether values matching this element can have U{nil
1449 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
1450 return self.__nillable
1451 __nillable = False
1452
1454 """Indicate whether this element is abstract (must use substitution
1455 group members for matches)."""
1456 return self.__abstract
1457 __abstract = False
1458
1460 """Contents of any documentation annotation in the definition."""
1461 return self.__documentation
1462 __documentation = None
1463
1465 """The default value of the element.
1466
1467 C{None} if the element has no default value.
1468
1469 @note: A non-C{None} value is always an instance of a simple type,
1470 even if the element has complex content."""
1471 return self.__defaultValue
1472 __defaultValue = None
1473
1475 """C{True} if the element content cannot be changed"""
1476 return self.__fixed
1477 __fixed = False
1478
1480 """The L{element} instance to whose substitution group this element
1481 belongs. C{None} if this element is not part of a substitution
1482 group."""
1483 return self.__substitutionGroup
1489 __substitutionGroup = None
1490
1498
1500 """Determine whether an instance of this element can substitute for the other element.
1501
1502 See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>}.
1503
1504 @todo: Do something about blocking constraints. This ignores them, as
1505 does everything leading to this point.
1506 """
1507 if self.substitutionGroup() is None:
1508 return False
1509 if other is None:
1510 return False
1511 assert isinstance(other, element)
1512
1513
1514 if other.scope() is not None:
1515 other = other.name().elementBinding()
1516 if other is None:
1517 return False
1518 assert other.scope() is None
1519
1520 if self.name().elementBinding() == other:
1521 return True
1522 return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
1523
1525 """Stub replaced by _real_substitutesFor when element supports substitution groups."""
1526 return False
1527
1529 """Return a reference to the element instance used for the given name
1530 within this element.
1531
1532 The type for this element must be a complex type definition."""
1533 return self.typeDefinition()._UseForTag(name).elementBinding()
1534
1535 - def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, unicode_default=None, fixed=False, substitution_group=None, documentation=None, location=None):
1555
1557 """Invoke the Factory method on the type associated with this element.
1558
1559 @keyword _dom_node: This keyword is removed. If present, it must be C{None}.
1560
1561 @note: Other keywords are passed to L{_TypeBinding_mixin.Factory}.
1562
1563 @raise pyxb.AbstractElementError: This element is abstract and no DOM
1564 node was provided.
1565 """
1566 dom_node = kw.pop('_dom_node', None)
1567 assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
1568 if '_element' in kw:
1569 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1570 kw['_element'] = self
1571
1572 if self.abstract():
1573 location = kw.get('_location')
1574 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
1575 location = dom_node._location()
1576 raise pyxb.AbstractElementError(self, location, args)
1577 if self.__defaultValue is not None:
1578 if 0 == len(args):
1579
1580 args = [ self.__defaultValue ]
1581 elif self.__fixed:
1582
1583 if 1 < len(args):
1584 raise ValueError(*args)
1585 args = [ self.compatibleValue(args[0], **kw) ]
1586 rv = self.typeDefinition().Factory(*args, **kw)
1587 rv._setElement(self)
1588 return rv
1589
1616
1617 @classmethod
1619 """Create a binding from a DOM node.
1620
1621 @param node: The DOM node
1622
1623 @param element_binding: An instance of L{element} that would normally
1624 be used to determine the type of the binding. The actual type of
1625 object returned is determined by the type definition associated with
1626 the C{element_binding} and the value of any U{xsi:type
1627 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in
1628 C{node}, modulated by
1629 L{XSI._InterpretTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance._InterpretTypeAttribute>}.
1630
1631 @keyword _fallback_namespace: The namespace to use as the namespace for
1632 the node, if the node name is unqualified. This should be an absent
1633 namespace.
1634
1635 @return: A binding for the DOM node.
1636
1637 @raises pyxb.UnrecognizedDOMRootNodeError: if no underlying element or
1638 type for the node can be identified.
1639 """
1640
1641 if xml.dom.Node.ELEMENT_NODE != node.nodeType:
1642 raise ValueError('node is not an element')
1643
1644 fallback_namespace = kw.get('_fallback_namespace')
1645
1646
1647
1648 if '_element' in kw:
1649 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1650
1651 type_class = None
1652 if element_binding is not None:
1653
1654
1655
1656 if element_binding.abstract():
1657 location = kw.get('location')
1658 if (location is None) and isinstance(node, utility.Locatable_mixin):
1659 location = node._location()
1660 raise pyxb.AbstractElementError(element_binding, location, node)
1661 kw['_element'] = element_binding
1662 type_class = element_binding.typeDefinition()
1663
1664
1665
1666
1667
1668 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
1669 (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
1670
1671 if type_class is None:
1672 raise pyxb.UnrecognizedDOMRootNodeError(node)
1673
1674
1675
1676
1677 is_nil = XSI.nil.getAttribute(node)
1678 if is_nil is not None:
1679 kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1680
1681 rv = type_class.Factory(_dom_node=node, **kw)
1682 assert rv._element() == element_binding
1683 rv._setNamespaceContext(pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node))
1684 return rv._postDOMValidate()
1685
1686
1687 @classmethod
1689 """Create an instance of an element from a DOM node.
1690
1691 This method does minimal processing of C{node} and delegates to
1692 L{CreateDOMBinding}.
1693
1694 @param node: An C{xml.dom.Node} representing a root element. If the
1695 node is a document, that document's root node will be substituted.
1696 The name of the node is extracted as the name of the element to be
1697 created, and the node and the name are passed to L{CreateDOMBinding}.
1698
1699 @param fallback_namespace: The value to pass as C{_fallback_namespace}
1700 to L{CreateDOMBinding}
1701
1702 @return: As with L{CreateDOMBinding}"""
1703 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1704 node = node.documentElement
1705 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1706 return cls.CreateDOMBinding(node, expanded_name.elementBinding(), _fallback_namespace=fallback_namespace)
1707
1709 """Return the element that should be used if this element binding is
1710 permitted and an element with the given name is encountered.
1711
1712 Normally, the incoming name matches the name of this binding, and
1713 C{self} is returned. If the incoming name is different, it is
1714 expected to be the name of a global element which is within this
1715 element's substitution group. In that case, the binding corresponding
1716 to the named element is return.
1717
1718 @return: An instance of L{element}, or C{None} if no element with the
1719 given name can be found.
1720 """
1721
1722
1723 if self.name() == name:
1724 return self
1725
1726
1727 top_elt = self.name().elementBinding()
1728 if top_elt is None:
1729 return None
1730
1731
1732
1733
1734 elt_en = top_elt.name().adoptName(name)
1735 assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
1736 named_elt = elt_en.elementBinding()
1737 if (named_elt is None) or (named_elt == top_elt):
1738 return None
1739 if named_elt.substitutesFor(top_elt):
1740 return named_elt
1741 return None
1742
1744 """Create an instance of this element using a DOM node as the source
1745 of its content.
1746
1747 This method does minimal processing of C{node} and delegates to
1748 L{_createFromDOM}.
1749
1750 @param node: An C{xml.dom.Node} representing a root element. If the
1751 node is a document, that document's root node will be substituted.
1752 The name of the node is extracted as the name of the element to be
1753 created, and the node and the name are passed to L{_createFromDOM}
1754
1755 @keyword fallback_namespace: Used as default for
1756 C{_fallback_namespace} in call to L{_createFromDOM}
1757
1758 @note: Keyword parameters are passed to L{CreateDOMBinding}.
1759
1760 @return: As with L{_createFromDOM}
1761 """
1762 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1763 node = node.documentElement
1764 if fallback_namespace is not None:
1765 kw.setdefault('_fallback_namespace', fallback_namespace)
1766 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1767 return self._createFromDOM(node, expanded_name, **kw)
1768
1770 """Create an instance from a DOM node given the name of an element.
1771
1772 This method does minimal processing of C{node} and C{expanded_name}
1773 and delegates to L{CreateDOMBinding}.
1774
1775 @param node: An C{xml.dom.Node} representing a root element. If the
1776 node is a document, that document's root node will be substituted.
1777 The value is passed to L{CreateDOMBinding}.
1778
1779 @param expanded_name: The expanded name of the element to be used for
1780 content. This is passed to L{elementForName} to obtain the binding
1781 that is passed to L{CreateDOMBinding}, superseding any identification
1782 that might be inferred from C{node}. If no name is available, use
1783 L{createFromDOM}.
1784
1785 @note: Keyword parameters are passed to L{CreateDOMBinding}.
1786
1787 @return: As with L{CreateDOMBinding}.
1788 """
1789 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1790 node = node.documentElement
1791 return element.CreateDOMBinding(node, self.elementForName(expanded_name), **kw)
1792
1794 return 'Element %s' % (self.name(),)
1795
1796 - def _description (self, name_only=False, user_documentation=True):
1810
1812 """Marker in case we need to know that a PST has an enumeration constraint facet."""
1813
1814 @classmethod
1816 """Return a list of values that the enumeration can take."""
1817 return cls._CF_enumeration.values()
1818
1819 @classmethod
1823
1824 @classmethod
1826 """Return the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1827 return cls._CF_enumeration.items()
1828
1829 @classmethod
1831 """Generate the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1832 return cls._CF_enumeration.iteritems()
1833
1834 -class _Content (object):
1835 """Base for any wrapper added to L{complexTypeDefinition.orderedContent}."""
1836
1837 - def __getValue (self):
1838 """The value of the content.
1839
1840 This is a unicode string for L{NonElementContent}, and (ideally) an
1841 instance of L{_TypeBinding_mixin} for L{ElementContent}."""
1842 return self.__value
1843 __value = None
1844 value = property(__getValue)
1845
1846 @classmethod
1847 - def ContentIterator (cls, input):
1848 """Return an iterator that filters and maps a sequence of L{_Content}
1849 instances.
1850
1851 The returned iterator will filter out sequence members that are not
1852 instances of the class from which the iterator was created. Further,
1853 only the L{value} field of the sequence member is returned.
1854
1855 Thus the catenated text of the non-element content of an instance can
1856 be obtained with::
1857
1858 text = u''.join(NonElementContent.ContentIterator(instance.orderedContent()))
1859
1860 See also L{pyxb.NonElementContent}
1861 """
1862 class _Iterator:
1863 def __init__ (self, input):
1864 self.__input = iter(input)
1865 def __iter__ (self):
1866 return self
1867 def next (self):
1868 while True:
1869 content = self.__input.next()
1870 if isinstance(content, cls):
1871 return content.value
1872 return _Iterator(input)
1873
1874 - def __init__ (self, value):
1875 self.__value = value
1876
1877 -class ElementContent (_Content):
1878 """Marking wrapper for element content.
1879
1880 The value should be translated into XML and made a child of its parent."""
1881
1883 """The L{pyxb.binding.content.ElementDeclaration} associated with the element content.
1884 This may be C{None} if the value is a wildcard."""
1885 return self.__elementDeclaration
1886 __elementDeclaration = None
1887
1888 elementDeclaration = property(__getElementDeclaration)
1889
1890 - def __init__ (self, value, element_declaration=None, instance=None, tag=None):
1891 """Create a wrapper associating a value with its element declaration.
1892
1893 Normally the element declaration is determined by consulting the
1894 content model when creating a binding instance. When manipulating the
1895 preferred content list, this may be inconvenient to obtain; in that case
1896 provide the C{instance} in which the content appears immediately,
1897 along with the C{tag} that is used for the Python attribute that holds
1898 the element.
1899
1900 @param value: the value of the element. Should be an instance of
1901 L{_TypeBinding_mixin}, but for simple types might be a Python native
1902 type.
1903
1904 @keyword element_declaration: The
1905 L{pyxb.binding.content.ElementDeclaration} associated with the element
1906 value. Should be C{None} if the element matches wildcard content.
1907
1908 @keyword instance: Alternative path to providing C{element_declaration}
1909 @keyword tag: Alternative path to providing C{element_declaration}
1910 """
1911
1912 import pyxb.binding.content
1913 super(ElementContent, self).__init__(value)
1914 if instance is not None:
1915 if not isinstance(instance, complexTypeDefinition):
1916 raise pyxb.UsageError('Unable to determine element declaration')
1917 element_declaration = instance._UseForTag(tag)
1918 assert (element_declaration is None) or isinstance(element_declaration, pyxb.binding.content.ElementDeclaration)
1919 self.__elementDeclaration = element_declaration
1920
1921 -class NonElementContent (_Content):
1922 """Marking wrapper for non-element content.
1923
1924 The value will be unicode text, and should be appended as character
1925 data."""
1926 - def __init__ (self, value):
1928
1929 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1930 """Base for any Python class that serves as the binding for an
1931 XMLSchema complexType.
1932
1933 Subclasses should define a class-level _AttributeMap variable which maps
1934 from the unicode tag of an attribute to the AttributeUse instance that
1935 defines it. Similarly, subclasses should define an _ElementMap variable.
1936 """
1937
1938 _CT_EMPTY = 'EMPTY'
1939 _CT_SIMPLE = 'SIMPLE'
1940 _CT_MIXED = 'MIXED'
1941 _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1942
1943 _ContentTypeTag = None
1944
1945 _TypeDefinition = None
1946 """Subclass of simpleTypeDefinition that corresponds to the type content.
1947 Only valid if _ContentTypeTag is _CT_SIMPLE"""
1948
1949
1950
1951 _HasWildcardElement = False
1952
1953
1954 _ElementMap = { }
1955 """Map from expanded names to ElementDeclaration instances."""
1956
1957
1958
1959 __wildcardAttributeMap = None
1960
1962 """Obtain access to wildcard attributes.
1963
1964 The return value is C{None} if this type does not support wildcard
1965 attributes. If wildcard attributes are allowed, the return value is a
1966 map from QNames to the unicode string value of the corresponding
1967 attribute.
1968
1969 @todo: The map keys should be namespace extended names rather than
1970 QNames, as the in-scope namespace may not be readily available to the
1971 user.
1972 """
1973 return self.__wildcardAttributeMap
1974
1975
1976
1977 __wildcardElements = None
1978
1980 """Obtain access to wildcard elements.
1981
1982 The return value is C{None} if the content model for this type does not
1983 support wildcard elements. If wildcard elements are allowed, the
1984 return value is a list of values corresponding to conformant
1985 unrecognized elements, in the order in which they were encountered.
1986 If the containing binding was created from an XML document and enough
1987 information was present to determine the binding of the member
1988 element, the value is a binding instance. Otherwise, the value is the
1989 original DOM Element node.
1990 """
1991 return self.__wildcardElements
1992
1994 """Create a new instance of this binding.
1995
1996 Arguments are used as transition values along the content model.
1997 Keywords are passed to the constructor of any simple content, or used
1998 to initialize attribute and element values whose L{id
1999 <content.ElementDeclaration.id>} (not L{name <content.ElementDeclaration.name>})
2000 matches the keyword.
2001
2002 @keyword _dom_node: The node to use as the source of binding content.
2003 @type _dom_node: C{xml.dom.Element}
2004
2005 @keyword _location: An optional instance of
2006 L{pyxb.utils.utility.Location} showing the origin the binding. If
2007 C{None}, a value from C{_dom_node} is used if available.
2008
2009 @keyword _from_xml: See L{_TypeBinding_mixin.Factory}
2010
2011 @keyword _finalize_content_model: If C{True} the constructor invokes
2012 L{_TypeBinding_mixin._finalizeContentModel} prior to return. The
2013 value defaults to C{False} when content is assigned through keyword
2014 parameters (bypassing the content model) or neither a C{_dom_node} nor
2015 positional element parameters have been provided, and to C{True} in
2016 all other cases.
2017 """
2018
2019 fallback_namespace = kw.pop('_fallback_namespace', None)
2020 is_nil = False
2021 dom_node = kw.pop('_dom_node', None)
2022 location = kw.pop('_location', None)
2023 from_xml = kw.pop('_from_xml', dom_node is not None)
2024 do_finalize_content_model = kw.pop('_finalize_content_model', None)
2025 if dom_node is not None:
2026 if (location is None) and isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
2027 location = dom_node._location()
2028 if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
2029 dom_node = dom_node.documentElement
2030
2031 is_nil = XSI.nil.getAttribute(dom_node)
2032 if is_nil is not None:
2033 is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
2034 if location is not None:
2035 self._setLocation(location)
2036 if self._AttributeWildcard is not None:
2037 self.__wildcardAttributeMap = { }
2038 if self._HasWildcardElement:
2039 self.__wildcardElements = []
2040 if self._Abstract:
2041 raise pyxb.AbstractInstantiationError(type(self), location, dom_node)
2042 super(complexTypeDefinition, self).__init__(**kw)
2043 self.reset()
2044 self._setAttributesFromKeywordsAndDOM(kw, dom_node)
2045 did_set_kw_elt = False
2046 for fu in self._ElementMap.itervalues():
2047 iv = kw.pop(fu.id(), None)
2048 if iv is not None:
2049 did_set_kw_elt = True
2050 fu.set(self, iv)
2051 if do_finalize_content_model is None:
2052 do_finalize_content_model = not did_set_kw_elt
2053 if kw and kw.pop('_strict_keywords', True):
2054 [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
2055 if kw:
2056 raise pyxb.UnprocessedKeywordContentError(self, kw)
2057 if 0 < len(args):
2058 if did_set_kw_elt:
2059 raise pyxb.UsageError('Cannot mix keyword and positional args for element initialization')
2060 self.extend(args, _from_xml=from_xml, _location=location)
2061 elif self._CT_SIMPLE == self._ContentTypeTag:
2062 value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _location=location, _nil=self._isNil(), _apply_attributes=False, *args)
2063 if value._constructedWithValue():
2064 self.append(value)
2065 elif dom_node is not None:
2066 self.extend(dom_node.childNodes[:], fallback_namespace)
2067 else:
2068 do_finalize_content_model = False
2069 if do_finalize_content_model:
2070 self._finalizeContentModel()
2071
2072
2073 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
2074 'xsdConstraintsOK', 'content', 'orderedContent', 'append', 'extend', 'value', 'reset' ]))
2075
2076
2077
2078 _Automaton = None
2079
2080 @classmethod
2082 """Method used by generated code to associate the element binding with a use in this type.
2083
2084 This is necessary because all complex type classes appear in the
2085 module prior to any of the element instances (which reference type
2086 classes), so the association must be formed after the element
2087 instances are available."""
2088 return cls._UseForTag(element.name())._setElementBinding(element)
2089
2090 @classmethod
2092 """Return the ElementDeclaration object corresponding to the element name.
2093
2094 @param tag: The L{ExpandedName} of an element in the class."""
2095 try:
2096 rv = cls._ElementMap[tag]
2097 except KeyError:
2098 if raise_if_fail:
2099 raise
2100 rv = None
2101 return rv
2102
2104 """Generate a list of children in the order in which they should be
2105 added to the parent when creating a DOM representation of this
2106 object.
2107
2108 @note: This is only used when L{pyxb.RequireValidWhenGenerating} has
2109 disabled validation. Consequently, it may not generate valid XML.
2110 """
2111 order = []
2112 for ed in self._ElementMap.itervalues():
2113 value = ed.value(self)
2114 if value is None:
2115 continue
2116 if isinstance(value, list) and ed.isPlural():
2117 order.extend([ ElementContent(_v, ed) for _v in value ])
2118 continue
2119 order.append(ElementContent(value, ed))
2120 return order
2121
2123 """Provide the child elements and non-element content in an order
2124 consistent with the content model.
2125
2126 Returns a sequence of tuples representing a valid path through the
2127 content model where each transition corresponds to one of the member
2128 element instances within this instance. The tuple is a pair
2129 comprising the L{content.ElementDeclaration} instance and the value for the
2130 transition.
2131
2132 If the content of the instance does not validate against the content
2133 model, an exception is raised.
2134
2135 @return: C{None} or a list as described above.
2136 """
2137 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
2138 return []
2139 self._resetAutomaton()
2140 return self.__automatonConfiguration.sequencedChildren()
2141
2143 """Return a map from L{content.ElementDeclaration} instances to a list of
2144 values associated with that use.
2145
2146 This is used as the set of symbols available for transitions when
2147 validating content against a model. Note that the original
2148 L{content.ElementUse} that may have validated the assignment of the
2149 symbol to the content is no longer available, which may result in a
2150 different order being generated by the content model. Preservation of
2151 the original order mitigates this risk.
2152
2153 The value C{None} is used to provide the wildcard members, if any.
2154
2155 If an element use has no associated values, it must not appear in the
2156 returned map.
2157
2158 @raise pyxb.SimpleTypeValueError: when unable to convert element
2159 content to the binding declaration type.
2160 """
2161 rv = { }
2162 for eu in self._ElementMap.itervalues():
2163 value = eu.value(self)
2164 if value is None:
2165 continue
2166 converter = eu.elementBinding().compatibleValue
2167 if eu.isPlural():
2168 if 0 < len(value):
2169 rv[eu] = [ converter(_v) for _v in value ]
2170 else:
2171 rv[eu] = [ converter(value)]
2172 wce = self.__wildcardElements
2173 if (wce is not None) and (0 < len(wce)):
2174 rv[None] = wce[:]
2175 return rv
2176
2180
2198
2208
2226
2227
2228
2229
2230 __content = None
2231
2232 - def orderedContent (self):
2233 """Return the element and non-element content of the instance in order.
2234
2235 This must be a complex type with complex content. The return value is
2236 a list of the element and non-element content in a preferred order.
2237
2238 The returned list contains L{element<ElementContent>} and
2239 L{non-element<NonElementContent>} content in the order which it was
2240 added to the instance. This may have been through parsing a document,
2241 constructing an instance using positional arguments, invoking the
2242 L{append} or L{extend} methods, or assigning directly to an instance
2243 attribute associated with an element binding.
2244
2245 @note: Be aware that assigning directly to an element attribute does not
2246 remove any previous value for the element from the content list.
2247
2248 @note: Be aware that element values directly appended to an instance
2249 attribute with list type (viz., that corresponds to an element that
2250 allows more than one occurrence) will not appear in the ordered
2251 content list.
2252
2253 The order in the list may influence the generation of documents
2254 depending on L{pyxb.ValidationConfig} values that apply to an
2255 instance. Non-element content is emitted immediately prior to the
2256 following element in this list. Any trailing non-element content is
2257 emitted after the last element in the content. The list should
2258 include all element content. Element content in this list that is not
2259 present within an element member of the binding instance may result in
2260 an error, or may be ignored.
2261
2262 @note: The returned value is mutable, allowing the caller to change
2263 the order to be used.
2264
2265 @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
2266 """
2267 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
2268 raise pyxb.NotComplexContentError(self)
2269 return self.__content
2270
2271 @classmethod
2272 - def __WarnOnContent (cls):
2273 if cls.__NeedWarnOnContent:
2274 import traceback
2275 cls.__NeedWarnOnContent = False
2276 _log.warning('Deprecated complexTypeDefinition method "content" invoked\nPlease use "orderedContent"\n%s', ''.join(traceback.format_stack()[:-2]))
2277 pass
2278 __NeedWarnOnContent = True
2279
2280 - def content (self):
2281 """Legacy interface for ordered content.
2282
2283 This version does not accurately distinguish non-element content from
2284 element content that happens to have unicode type.
2285
2286 @deprecated: use L{orderedContent}."""
2287 self.__WarnOnContent()
2288 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
2289 raise pyxb.NotComplexContentError(self)
2290 return [ _v.value for _v in self.__content ]
2291
2293 """Return the value of the element.
2294
2295 This must be a complex type with simple content. The returned value
2296 is expected to be an instance of some L{simpleTypeDefinition} class.
2297
2298 @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
2299 """
2300 if self._CT_SIMPLE != self._ContentTypeTag:
2301 raise pyxb.NotSimpleContentError(self)
2302 return self.__content
2303
2304 - def _resetContent (self, reset_elements=False):
2305 if reset_elements:
2306 for eu in self._ElementMap.itervalues():
2307 eu.reset(self)
2308 nv = None
2309 if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
2310 nv = []
2311 return self.__setContent(nv)
2312
2313 __automatonConfiguration = None
2321
2325
2327 """Reset the instance.
2328
2329 This resets all element and attribute fields, and discards any
2330 recorded content. It resets the content model automaton to its
2331 initial state.
2332
2333 @see: Manipulate the return value of L{orderedContent} if your intent is
2334 to influence the generation of documents from the binding instance
2335 without changing its (element) content.
2336 """
2337
2338 self._resetContent(reset_elements=True)
2339 for au in self._AttributeMap.itervalues():
2340 au.reset(self)
2341 self._resetAutomaton()
2342 return self
2343
2344 @classmethod
2346 """Determine what the given name means as an element in this type.
2347
2348 Normally, C{element_name} identifies an element definition within this
2349 type. If so, the returned C{element_decl} identifies that definition,
2350 and the C{element_binding} is extracted from that use.
2351
2352 It may also be that the C{element_name} does not appear as an element
2353 definition, but that it identifies a global element. In that case,
2354 the returned C{element_binding} identifies the global element. If,
2355 further, that element is a member of a substitution group which does
2356 have an element definition in this class, then the returned
2357 C{element_decl} identifies that definition.
2358
2359 If a non-C{None} C{element_decl} is returned, there will be an
2360 associated C{element_binding}. However, it is possible to return a
2361 non-C{None} C{element_binding}, but C{None} as the C{element_decl}. In
2362 that case, the C{element_binding} can be used to create a binding
2363 instance, but the content model will have to treat it as a wildcard.
2364
2365 @param element_name: The name of the element in this type, either an
2366 expanded name or a local name if the element has an absent namespace.
2367
2368 @return: C{( element_binding, element_decl )}
2369 """
2370 element_decl = cls._ElementMap.get(element_name)
2371 element_binding = None
2372 if element_decl is None:
2373 try:
2374 element_binding = element_name.elementBinding()
2375 except pyxb.NamespaceError:
2376 pass
2377 if element_binding is not None:
2378 element_decl = element_binding.findSubstituendDecl(cls)
2379 else:
2380 element_binding = element_decl.elementBinding()
2381 return (element_binding, element_decl)
2382
2383 - def append (self, value, **kw):
2384 """Add the value to the instance.
2385
2386 The value should be a DOM node or other value that is or can be
2387 converted to a binding instance, or a string if the instance allows
2388 mixed content. The value must be permitted by the content model.
2389
2390 @raise pyxb.ContentValidationError: the value is not permitted at the current
2391 state of the content model.
2392 """
2393
2394
2395
2396 element_decl = kw.get('_element_decl', None)
2397 maybe_element = kw.get('_maybe_element', True)
2398 location = kw.get('_location', None)
2399 if self._isNil():
2400 raise pyxb.ContentInNilInstanceError(self, value, location)
2401 fallback_namespace = kw.get('_fallback_namespace', None)
2402 require_validation = kw.get('_require_validation', self._validationConfig.forBinding)
2403 from_xml = kw.get('_from_xml', False)
2404 element_binding = None
2405 if element_decl is not None:
2406 from pyxb.binding import content
2407 assert isinstance(element_decl, content.ElementDeclaration)
2408 element_binding = element_decl.elementBinding()
2409 assert element_binding is not None
2410
2411 if isinstance(value, xml.dom.Node):
2412 from_xml = True
2413 assert maybe_element
2414 assert element_binding is None
2415 node = value
2416 require_validation = pyxb.GlobalValidationConfig.forBinding
2417 if xml.dom.Node.COMMENT_NODE == node.nodeType:
2418
2419
2420 return self
2421 if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
2422 value = node.data
2423 maybe_element = False
2424 else:
2425
2426 assert xml.dom.Node.ELEMENT_NODE == node.nodeType
2427 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
2428 (element_binding, element_decl) = self._ElementBindingDeclForName(expanded_name)
2429 if element_binding is not None:
2430
2431
2432 value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=fallback_namespace)
2433 else:
2434
2435
2436
2437 xsi_type = XSI.type.getAttribute(node)
2438 try_create = False
2439 if xsi_type is not None:
2440 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
2441 (try_create, type_class) = XSI._InterpretTypeAttribute(xsi_type, ns_ctx, fallback_namespace, None)
2442 if try_create:
2443 value = element.CreateDOMBinding(node, None, _fallback_namespace=fallback_namespace)
2444 else:
2445 _log.warning('Unable to convert DOM node %s at %s to binding', expanded_name, getattr(node, 'location', '[UNAVAILABLE]'))
2446 if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
2447 if (0 == len(value.strip())) and not self._isNil():
2448 return self
2449 if maybe_element and (self.__automatonConfiguration is not None):
2450
2451 if not require_validation:
2452 if element_decl is not None:
2453 element_decl.setOrAppend(self, value)
2454 return self
2455 if self.__wildcardElements is not None:
2456 self._appendWildcardElement(value)
2457 return self
2458 raise pyxb.StructuralBadDocumentError(container=self, content=value)
2459
2460 num_cand = self.__automatonConfiguration.step(value, element_decl)
2461 if 1 <= num_cand:
2462
2463 return self
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477 if ((element_binding is not None)
2478 or isinstance(value, (xml.dom.Node, complexTypeDefinition, pyxb.BIND))
2479 or (isinstance(value, simpleTypeDefinition) and not (self._IsSimpleTypeContent() or self._IsMixed()))):
2480
2481
2482
2483 if self.__automatonConfiguration:
2484 raise pyxb.UnrecognizedContentError(self, self.__automatonConfiguration, value, location)
2485 raise pyxb.NonElementValidationError(value, location)
2486
2487
2488
2489 if self._IsSimpleTypeContent():
2490 if self.__content is not None:
2491 raise pyxb.ExtraSimpleContentError(self, value)
2492 if not self._isNil():
2493 if not isinstance(value, self._TypeDefinition):
2494 value = self._TypeDefinition.Factory(value, _from_xml=from_xml)
2495 self.__setContent(value)
2496 if require_validation:
2497
2498
2499
2500 self.xsdConstraintsOK(location)
2501 return self
2502
2503
2504 if not self._IsMixed():
2505 raise pyxb.MixedContentError(self, value, location)
2506
2507
2508 self._addContent(NonElementContent(value))
2509 return self
2510
2514
2515 - def extend (self, value_list, _fallback_namespace=None, _from_xml=False, _location=None):
2516 """Invoke L{append} for each value in the list, in turn."""
2517 [ self.append(_v, _fallback_namespace=_fallback_namespace, _from_xml=_from_xml, _location=_location) for _v in value_list ]
2518 return self
2519
2520 - def __setContent (self, value):
2521 self.__content = value
2522 return self.__content
2523
2524 - def _addContent (self, wrapped_value):
2525
2526
2527
2528 assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
2529 assert isinstance(wrapped_value, _Content)
2530 self.__content.append(wrapped_value)
2531 if isinstance(wrapped_value, ElementContent):
2532 value = wrapped_value.value
2533 ed = wrapped_value.elementDeclaration
2534 if isinstance(value, _TypeBinding_mixin) and (ed is not None) and (value._element() is None):
2535 assert isinstance(ed.elementBinding(), element)
2536 value._setElement(ed.elementBinding())
2537
2538 @classmethod
2541
2546
2547 - def _postDOMValidate (self):
2559
2567
2569 """Create a DOM element with the given tag holding the content of this instance."""
2570 element = parent
2571 self._setDOMFromAttributes(dom_support, element)
2572 if self._isNil():
2573 pass
2574 elif self._CT_EMPTY == self._ContentTypeTag:
2575 pass
2576 elif self._CT_SIMPLE == self._ContentTypeTag:
2577 if self.__content is None:
2578 raise pyxb.SimpleContentAbsentError(self, self._location())
2579 dom_support.appendTextChild(self.value().xsdLiteral(), element)
2580 else:
2581 if pyxb.GlobalValidationConfig.forDocument:
2582 order = self._validatedChildren()
2583 else:
2584 order = self.__childrenForDOM()
2585 for content in order:
2586 assert content.value != self
2587 if isinstance(content, NonElementContent):
2588 dom_support.appendTextChild(content.value, element)
2589 continue
2590 if content.elementDeclaration is None:
2591 if isinstance(content.value, xml.dom.Node):
2592 dom_support.appendChild(content.value, element)
2593 else:
2594 content.value.toDOM(dom_support, parent)
2595 else:
2596 content.elementDeclaration.toDOM(dom_support, parent, content.value)
2597 mixed_content = self.orderedContent()
2598 for mc in mixed_content:
2599 pass
2600 return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
2601
2602 @classmethod
2604 """CTDs with simple content are simple; other CTDs are not."""
2605 return cls._CT_SIMPLE == cls._ContentTypeTag
2606
2607 @classmethod
2608 - def _description (cls, name_only=False, user_documentation=True):
2634
2635
2636
2637
2638