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 from pyxb.namespace.builtin import XMLSchema_instance as XSI
27
28 _log = logging.getLogger(__name__)
31
32 @classmethod
43
44 _ExpandedName = None
45 """The expanded name of the component."""
46
47 _XSDLocation = None
48 """Where the definition can be found in the originating schema."""
49
50 _ReservedSymbols = set([ 'validateBinding', 'toDOM', 'toxml', 'Factory', 'property' ])
51
52 if pyxb._CorruptionDetectionEnabled:
57
58 _PyXBFactoryKeywords = ( '_dom_node', '_fallback_namespace', '_from_xml',
59 '_apply_whitespace_facet', '_validate_constraints',
60 '_require_value', '_nil', '_element', '_apply_attributes',
61 '_convert_string_values', '_location' )
62 """Keywords that are interpreted by __new__ or __init__ in one or more
63 classes in the PyXB type hierarchy. All these keywords must be removed
64 before invoking base Python __init__ or __new__."""
65
66
67
68
69 _Abstract = False
70
72 """Return a L{namespace context <pyxb.binding.NamespaceContext>}
73 associated with the binding instance.
74
75 This will return C{None} unless something has provided a context to
76 the instance. Context is provided when instances are generated by the
77 DOM and SAX-based translators."""
78 return self.__namespaceContext
79 - def _setNamespaceContext (self, namespace_context):
80 """Associate a L{namespace context <pyxb.binding.NamespaceContext>}
81 with the binding instance."""
82 self.__namespaceContext = namespace_context
83 return self
84 __namespaceContext = None
85
87 """Associate a L{pyxb.binding.basis.element} with the instance."""
88 self.__element = element
89 return self
91 """Return a L{pyxb.binding.basis.element} associated with the binding
92 instance.
93
94 This will return C{None} unless an element has been associated.
95 Constructing a binding instance using the element instance will add
96 this association.
97 """
98 return self.__element
99 __element = None
100
101 __xsiNil = None
103 """Indicate whether this instance is U{nil
104 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
105
106 The value is set by the DOM and SAX parsers when building an instance
107 from a DOM element with U{xsi:nil
108 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set to C{true}.
109
110 @return: C{None} if the element used to create the instance is not
111 U{nillable<http://www.w3.org/TR/xmlschema-1/#nillable>}.
112 If it is nillable, returns C{True} or C{False} depending on
113 whether the instance itself is U{nil<http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
114 """
115 return self.__xsiNil
117 """Set the xsi:nil property of the instance.
118
119 @param nil: C{True} if the value of xsi:nil should be C{true},
120 C{False} if the value of xsi:nil should be C{false}.
121
122 @raise pyxb.NoNillableSupportError: the instance is not associated
123 with an element that is L{nillable
124 <pyxb.binding.basis.element.nillable>}.
125 """
126 if self.__xsiNil is None:
127 raise pyxb.NoNillableSupportError(self)
128 self.__xsiNil = not not nil
129 if self.__xsiNil:
130 self._resetContent()
131
132 - def _resetContent (self):
134
135 __constructedWithValue = False
149
150
151
152
153 __WarnedUnassociatedElement = False
154
165
166 @classmethod
168 """Method invoked upon entry to the Factory method.
169
170 This method is entitled to modify the keywords array. It can also
171 return a state value which is passed to _postFactory_vx."""
172 return None
173
174 - def _postFactory_vx (cls, state):
175 """Method invoked prior to leaving the Factory method.
176
177 This is an instance method, and is given the state that was returned
178 by _PreFactory_vx."""
179 return None
180
181 @classmethod
183 """Provide a common mechanism to create new instances of this type.
184
185 The class constructor won't do, because you can't create
186 instances of union types.
187
188 This method may be overridden in subclasses (like STD_union). Pre-
189 and post-creation actions can be customized on a per-class instance by
190 overriding the L{_PreFactory_vx} and L{_postFactory_vx} methods.
191
192 @keyword _dom_node: If provided, the value must be a DOM node, the
193 content of which will be used to set the value of the instance.
194
195 @keyword _location: An optional instance of
196 L{pyxb.utils.utility.Location} showing the origin the binding. If
197 C{None}, a value from C{_dom_node} is used if available.
198
199 @keyword _from_xml: If C{True}, the input must be either a DOM node or
200 a unicode string comprising a lexical representation of a value. This
201 is a further control on C{_apply_whitespace_facet} and arises from
202 cases where the lexical and value representations cannot be
203 distinguished by type. The default value is C{True} iff C{_dom_node}
204 is not C{None}.
205
206 @keyword _apply_whitespace_facet: If C{True} and this is a
207 simpleTypeDefinition with a whiteSpace facet, the first argument will
208 be normalized in accordance with that facet prior to invoking the
209 parent constructor. The value is always C{True} if text content is
210 extracted from a C{_dom_node}, and otherwise defaults to the defaulted
211 value of C{_from_xml}.
212
213 @keyword _validate_constraints: If C{True}, any constructed value is
214 checked against constraints applied to the union as well as the member
215 type.
216
217 @keyword _require_value: If C{False} (default), it is permitted to
218 create a value without an initial value. If C{True} and no initial
219 value was provided, causes L{pyxb.SimpleContentAbsentError} to be raised.
220 Only applies to simpleTypeDefinition instances; this is used when
221 creating values from DOM nodes.
222 """
223
224
225 dom_node = kw.get('_dom_node')
226 location = kw.get('_location')
227 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
228 location = dom_node._location()
229 kw.setdefault('_from_xml', dom_node is not None)
230 used_cls = cls._SupersedingClass()
231 state = used_cls._PreFactory_vx(args, kw)
232 rv = cls._DynamicCreate(*args, **kw)
233 rv._postFactory_vx(state)
234 if (rv._location is None) and (location is not None):
235 rv._setLocation(location)
236 return rv
237
242
243 @classmethod
245 """Return C{True} iff this is the ur-type.
246
247 The only ur-type is {http://www.w3.org/2001/XMLSchema}anyType. The
248 implementation of this method is overridden for
249 L{pyxb.binding.datatypes.anyType}."""
250 return False
251
252 @classmethod
258
259 @classmethod
261 """Return a variant of the value that is compatible with this type.
262
263 Compatibility is defined relative to the type definition associated
264 with the element. The value C{None} is always compatible. If
265 C{value} has a Python type (e.g., C{int}) that is a superclass of the
266 required L{_TypeBinding_mixin} class (e.g., C{xs:byte}), C{value} is
267 used as a constructor parameter to return a new instance of the
268 required type. Note that constraining facets are applied here if
269 necessary (e.g., although a Python C{int} with value C{500} is
270 type-compatible with C{xs:byte}, it is outside the value space, and
271 compatibility will fail).
272
273 @keyword _convert_string_values: If C{True} (default) and the incoming value is
274 a string, an attempt will be made to form a compatible value by using
275 the string as a constructor argument to the this class. This flag is
276 set to C{False} when testing automaton transitions.
277
278 @raise pyxb.SimpleTypeValueError: if the value is not both
279 type-consistent and value-consistent with the element's type.
280 """
281 convert_string_values = kw.get('_convert_string_values', True)
282
283 if value is None:
284 return None
285
286 if isinstance(value, cls):
287
288
289 return value
290 value_type = type(value)
291
292 if str == value_type:
293 value_type = unicode
294
295
296
297 if issubclass(cls, value_type):
298 return cls(value)
299
300
301
302 if isinstance(value, int) and issubclass(cls, long):
303 return cls(value)
304
305
306 if isinstance(value, bool) and issubclass(cls, pyxb.binding.datatypes.boolean):
307 return cls(value)
308
309
310
311 if convert_string_values and (unicode == value_type):
312 return cls(value)
313
314
315 if issubclass(cls, STD_union):
316 for mt in cls._MemberTypes:
317 try:
318 return mt._CompatibleValue(value, **kw)
319 except:
320 pass
321
322
323 if (pyxb.binding.datatypes.anySimpleType == cls) and issubclass(value_type, simpleTypeDefinition):
324 return value
325 if pyxb.binding.datatypes.anyType == cls:
326 if not isinstance(value, _TypeBinding_mixin):
327 _log.info('Created %s instance from value of type %s', cls._ExpandedName, type(value))
328 value = cls(value)
329 return value
330
331
332
333 if isinstance(value, pyxb.BIND):
334 return value.createInstance(cls.Factory, **kw)
335
336
337
338
339
340
341 raise pyxb.SimpleTypeValueError(cls, value)
342
343 @classmethod
345 """Return True iff the content of this binding object is a simple type.
346
347 This is true only for descendents of simpleTypeDefinition and instances
348 of complexTypeDefinition that have simple type content."""
349 raise pyxb.LogicError('Failed to override _TypeBinding_mixin._IsSimpleTypeContent')
350
351
352
353
354 _AttributeWildcard = None
355
356 _AttributeMap = { }
357 """Map from expanded names to AttributeUse instances. Non-empty only in
358 L{complexTypeDefinition} subclasses."""
359
360 @classmethod
380
382 """Invoke self._setAttribute based on node attributes and keywords.
383
384 Though attributes can only legally appear in complexTypeDefinition
385 instances, delayed conditional validation requires caching them in
386 simpleTypeDefinition.
387
388 @param kw: keywords passed to the constructor. This map is mutated by
389 the call: keywords corresponding to recognized attributes are removed.
390
391 @param dom_node: an xml.dom Node instance, possibly C{None}
392 """
393
394
395 attribute_settings = { }
396 if dom_node is not None:
397 attribute_settings.update(self.__AttributesFromDOM(dom_node))
398 for fu in self._AttributeMap.values():
399 iv = kw.pop(fu.id(), None)
400 if iv is not None:
401 attribute_settings[fu.name()] = iv
402 for (attr_en, value) in attribute_settings.items():
403 self._setAttribute(attr_en, value)
404
405 - def toDOM (self, bds=None, parent=None, element_name=None):
406 """Convert this instance to a DOM node.
407
408 The name of the top-level element is either the name of the L{element}
409 instance associated with this instance, or the XML name of the type of
410 this instance.
411
412 @param bds: Support for customizing the generated document
413 @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
414 @param parent: If C{None}, a standalone document is created;
415 otherwise, the created element is a child of the given element.
416 @type parent: C{xml.dom.Element} or C{None}
417 @rtype: C{xml.dom.Document}
418 """
419
420 if bds is None:
421 bds = domutils.BindingDOMSupport()
422 need_xsi_type = bds.requireXSIType()
423 if isinstance(element_name, (str, unicode)):
424 element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
425 if (element_name is None) and (self._element() is not None):
426 element_binding = self._element()
427 element_name = element_binding.name()
428 need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
429 if element_name is None:
430 element_name = self._ExpandedName
431 element = bds.createChildElement(element_name, parent)
432 if need_xsi_type:
433 val_type_qname = self._ExpandedName.localName()
434 tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
435 if tns_prefix is not None:
436 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
437 bds.addAttribute(element, XSI.type, val_type_qname)
438 self._toDOM_csc(bds, element)
439 bds.finalize()
440 return bds.document()
441
442 - def toxml (self, encoding=None, bds=None, root_only=False):
443 """Shorthand to get the object as an XML document.
444
445 If you want to set the default namespace, pass in a pre-configured
446 C{bds}.
447
448 @param encoding: The encoding to be used. See
449 @C{xml.dom.Node.toxml()} for a description of why you should always
450 pass @C{'utf-8'} here. Because this method follows the contract of
451 the corresponding C{xml.dom.Node} method, it does not automatically
452 get the default PyXB output encoding.
453
454 @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
455 to use for creation. If not provided (default), a new generic one is
456 created.
457 """
458 dom = self.toDOM(bds)
459 if root_only:
460 dom = dom.documentElement
461 return dom.toxml(encoding)
462
468
470 """Override in subclasses for type-specific validation of instance
471 content.
472
473 @return: C{True} if the instance validates
474 @raise pyxb.BatchContentValidationError: complex content does not match model
475 @raise pyxb.SimpleTypeValueError: simple content fails to satisfy constraints
476 """
477 raise NotImplementedError('%s._validateBinding_vx' % (type(self).__name__,))
478
480 """Check whether the binding content matches its content model.
481
482 @return: C{True} if validation succeeds.
483 @raise pyxb.BatchContentValidationError: complex content does not match model
484 @raise pyxb.SimpleTypeValueError: attribute or simple content fails to satisfy constraints
485 """
486 if self._PerformValidation():
487 self._validateBinding_vx()
488 return True
489
491 """Inform content model that all additions have been provided.
492
493 This is used to resolve any pending non-determinism when the content
494 of an element is provided through a DOM assignment or through
495 positional arguments in a constructor."""
496 return self
497
498 - def _postDOMValidate (self):
499 self.validateBinding()
500 return self
501
502 @classmethod
504 """Return the best descriptive name for the type of the instance.
505
506 This is intended to be a human-readable value used in diagnostics, and
507 is the expanded name if the type has one, or the Python type name if
508 it does not."""
509 if cls._ExpandedName is not None:
510 return str(cls._ExpandedName)
511 return str(cls)
512
514 """The best name available for this instance in diagnostics.
515
516 If the instance is associated with an element, it is the element name;
517 otherwise it is the best name for the type of the instance per L{_Name}."""
518 if self.__element is None:
519 return self._Name()
520 return str(self.__element.name())
521
523 """Helper to allow overriding the implementation class.
524
525 Generally we'll want to augment the generated bindings by subclassing
526 them, and adding functionality to the subclass. This mix-in provides a
527 way to communicate the existence of the superseding subclass back to the
528 binding infrastructure, so that when it creates an instance it uses the
529 subclass rather than the unaugmented binding class.
530
531 When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
532 invoked on the raw class passing in the superseding subclass. E.g.::
533
534 class mywsdl (raw.wsdl):
535 pass
536 raw.wsdl._SetSupersedingClass(mywsdl)
537
538 """
539
540 @classmethod
542 return '_%s__SupersedingClass' % (cls.__name__,)
543
544 @classmethod
546 return '_%s__AlternativeConstructor' % (cls.__name__,)
547
548 @classmethod
552
553 @classmethod
555 """Return the class stored in the class reference attribute."""
556 rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
557 if isinstance(rv, tuple):
558 rv = rv[0]
559 return rv
560
561 @classmethod
563 """Set the class reference attribute.
564
565 @param superseding: A Python class that is a subclass of this class.
566 """
567 assert (superseding is None) or issubclass(superseding, cls)
568 if superseding is None:
569 cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
570 else:
571 setattr(cls, cls.__SupersedingClassAttribute(), superseding)
572 return superseding
573
574 @classmethod
576 attr = cls.__AlternativeConstructorAttribute()
577 if alternative_constructor is None:
578 cls.__dict__.pop(attr, None)
579 else:
580
581
582
583 setattr(cls, attr, (alternative_constructor,))
584 assert cls._AlternativeConstructor() == alternative_constructor
585 return alternative_constructor
586
587 @classmethod
597
598 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
599 """L{simpleTypeDefinition} is a base class that is part of the
600 hierarchy of any class that represents the Python datatype for a
601 L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
602
603 @note: This class, or a descendent of it, must be the first class
604 in the method resolution order when a subclass has multiple
605 parents. Otherwise, constructor keyword arguments may not be
606 removed before passing them on to Python classes that do not
607 accept them.
608 """
609
610
611
612
613 __FacetMap = {}
614
615 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
616 'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
617 'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
618 'PythonLiteral', 'pythonLiteral',
619 'SimpleTypeDefinition' ]))
620 """Symbols that remain the responsibility of this class. Any
621 public symbols in generated binding subclasses are deconflicted
622 by providing an alternative name in the subclass. (There
623 currently are no public symbols in generated SimpleTypeDefinion
624 bindings."""
625
626
627
628
629
630 __FacetMapAttributeNameMap = { }
631 @classmethod
633 """ """
634 '''
635 if cls == simpleTypeDefinition:
636 return '_%s__FacetMap' % (cls.__name__.strip('_'),)
637
638 # It is not uncommon for a class in one namespace to extend a class of
639 # the same name in a different namespace, so encode the namespace URI
640 # in the attribute name (if it is part of a namespace).
641 ns_uri = ''
642 try:
643 ns_uri = cls._ExpandedName.namespaceURI()
644 except Exception:
645 pass
646 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
647 '''
648 nm = cls.__FacetMapAttributeNameMap.get(cls)
649 if nm is None:
650 nm = cls.__name__
651 if nm.endswith('_'):
652 nm += '1'
653 if cls == simpleTypeDefinition:
654 nm = '_%s__FacetMap' % (nm,)
655 else:
656
657
658
659 ns_uri = ''
660 try:
661 ns_uri = cls._ExpandedName.namespaceURI()
662 except Exception:
663 pass
664 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
665 cls.__FacetMapAttributeNameMap[cls] = nm
666 return nm
667
668 @classmethod
670 """Return a reference to the facet map for this datatype.
671
672 The facet map is a map from leaf facet classes to instances of those
673 classes that constrain or otherwise apply to the lexical or value
674 space of the datatype. Classes may inherit their facet map from their
675 superclass, or may create a new class instance if the class adds a new
676 constraint type.
677
678 @raise AttributeError: if the facet map has not been defined"""
679 return getattr(cls, cls.__FacetMapAttributeName())
680
681 @classmethod
683 """Initialize the facet map for this datatype.
684
685 This must be called exactly once, after all facets belonging to the
686 datatype have been created.
687
688 @raise pyxb.LogicError: if called multiple times (on the same class)
689 @raise pyxb.LogicError: if called when a parent class facet map has not been initialized
690 :return: the facet map"""
691 fm = None
692 try:
693 fm = cls._FacetMap()
694 except AttributeError:
695 pass
696 if fm is not None:
697 raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
698
699
700
701
702
703 source_class = cls
704 while fm is None:
705
706
707 for super_class in source_class.mro():
708 assert super_class is not None
709 if (super_class == simpleTypeDefinition):
710 break
711 if issubclass(super_class, simpleTypeDefinition):
712 try:
713 fm = super_class._FacetMap()
714 break
715 except AttributeError:
716 pass
717 if fm is None:
718 try:
719 source_class = source_class.XsdSuperType()
720 except AttributeError:
721 source_class = None
722 if source_class is None:
723 fm = { }
724 if fm is None:
725 raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
726 fm = fm.copy()
727 for facet in args:
728 fm[type(facet)] = facet
729 setattr(cls, cls.__FacetMapAttributeName(), fm)
730 return fm
731
732 @classmethod
735
736 @classmethod
738 """Pre-process the arguments.
739
740 This is used before invoking the parent constructor. One application
741 is to apply the whitespace facet processing; if such a request is in
742 the keywords, it is removed so it does not propagate to the
743 superclass. Another application is to convert the arguments from a
744 string to a list. Binding-specific applications are performed in the
745 overloaded L{_ConvertArguments_vx} method."""
746 dom_node = kw.pop('_dom_node', None)
747 from_xml = kw.get('_from_xml', dom_node is not None)
748 if dom_node is not None:
749 text_content = domutils.ExtractTextContent(dom_node)
750 if text_content is not None:
751 args = (domutils.ExtractTextContent(dom_node),) + args
752 kw['_apply_whitespace_facet'] = True
753 apply_whitespace_facet = kw.pop('_apply_whitespace_facet', from_xml)
754 if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
755 cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
756 if cf_whitespace is not None:
757 norm_str = unicode(cf_whitespace.normalizeString(args[0]))
758 args = (norm_str,) + args[1:]
759 kw['_from_xml'] = from_xml
760 return cls._ConvertArguments_vx(args, kw)
761
762
763
764
765
766
767
768
769
770
771
773
774 kw.pop('_validate_constraints', None)
775 kw.pop('_require_value', None)
776 kw.pop('_element', None)
777 kw.pop('_fallback_namespace', None)
778 kw.pop('_apply_attributes', None)
779 kw.pop('_nil', None)
780
781 dom_node = kw.get('_dom_node')
782 args = cls._ConvertArguments(args, kw)
783 kw.pop('_from_xml', dom_node is not None)
784 kw.pop('_location', None)
785 assert issubclass(cls, _TypeBinding_mixin)
786 try:
787 return super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
788 except ValueError as e:
789 raise pyxb.SimpleTypeValueError(cls, args)
790 except OverflowError as e:
791 raise pyxb.SimpleTypeValueError(cls, args)
792
793
794
796 """Initialize a newly created STD instance.
797
798 Usually there is one positional argument, which is a value that can be
799 converted to the underlying Python type.
800
801 @keyword _validate_constraints: If True (default if validation is
802 enabled), the newly constructed value is checked against its
803 constraining facets.
804 @type _validate_constraints: C{bool}
805
806 @keyword _apply_attributes: If C{True} (default), any attributes
807 present in the keywords or DOM node are applied. Normally presence of
808 such an attribute should produce an error; when creating simple
809 content for a complex type we need the DOM node, but do not want to
810 apply the attributes, so we bypass the application.
811 """
812
813 validate_constraints = kw.pop('_validate_constraints', self._PerformValidation())
814 require_value = kw.pop('_require_value', False)
815
816 dom_node = kw.get('_dom_node')
817 location = kw.get('_location')
818 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
819 location = dom_node._location()
820 apply_attributes = kw.pop('_apply_attributes', True)
821
822
823 args = self._ConvertArguments(args, kw)
824 try:
825 super(simpleTypeDefinition, self).__init__(*args, **kw)
826 except OverflowError as e:
827 raise pyxb.SimpleTypeValueError(type(self), args)
828 if apply_attributes and (dom_node is not None):
829 self._setAttributesFromKeywordsAndDOM(kw, dom_node)
830 if require_value and (not self._constructedWithValue()):
831 if location is None:
832 location = self._location()
833 raise pyxb.SimpleContentAbsentError(self, location)
834 if validate_constraints:
835 self.xsdConstraintsOK(location)
836
837
838
839
840
841
842
843 @classmethod
845 return '_%s__SimpleTypeDefinition' % (cls.__name__,)
846
847 @classmethod
849 """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
850 associated with this binding."""
851 attr_name = cls.__STDAttrName()
852 if hasattr(cls, attr_name):
853 old_value = getattr(cls, attr_name)
854 if old_value != std:
855 raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
856 setattr(cls, attr_name, std)
857
858 @classmethod
860 """Return the SimpleTypeDefinition instance for the given
861 class.
862
863 This should only be invoked when generating bindings. An STD must
864 have been associated with the class using L{_SimpleTypeDefinition}."""
865 attr_name = cls.__STDAttrName()
866 assert hasattr(cls, attr_name)
867 return getattr(cls, attr_name)
868
869 @classmethod
871 """Convert from a python value to a string usable in an XML
872 document.
873
874 This should be implemented in the subclass."""
875 raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
876
878 """Return text suitable for representing the value of this
879 instance in an XML document.
880
881 The base class implementation delegates to the object class's
882 XsdLiteral method."""
883 if self._isNil():
884 return ''
885 return self.XsdLiteral(self)
886
887 @classmethod
889 """Find the nearest parent class in the PST hierarchy.
890
891 The value for anySimpleType is None; for all others, it's a
892 primitive or derived PST descendent (including anySimpleType)."""
893 for sc in cls.mro():
894 if sc == cls:
895 continue
896 if simpleTypeDefinition == sc:
897
898
899
900 return cls._XsdBaseType
901 if issubclass(sc, simpleTypeDefinition):
902 return sc
903 raise pyxb.LogicError('No supertype found for %s' % (cls,))
904
905 @classmethod
907 """Pre-extended class method to verify other things before
908 checking constraints.
909
910 This is used for list types, to verify that the values in the
911 list are acceptable, and for token descendents, to check the
912 lexical/value space conformance of the input.
913 """
914 super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
915 return super_fn(value)
916
917
918
919 __ClassFacetSequence = { }
920
921 @classmethod
959
963
968
969 @classmethod
971 """Return the length of the given value.
972
973 The length is calculated by a subclass implementation of
974 _XsdValueLength_vx in accordance with
975 http://www.w3.org/TR/xmlschema-2/#rf-length.
976
977 The return value is a non-negative integer, or C{None} if length
978 constraints should be considered trivially satisfied (as with
979 QName and NOTATION).
980
981 @raise pyxb.LogicError: the provided value is not an instance of cls.
982 @raise pyxb.LogicError: an attempt is made to calculate a length for
983 an instance of a type that does not support length calculations.
984 """
985 assert isinstance(value, cls)
986 if not hasattr(cls, '_XsdValueLength_vx'):
987 raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
988 return cls._XsdValueLength_vx(value)
989
991 """Return the length of this instance within its value space.
992
993 See XsdValueLength."""
994 return self.XsdValueLength(self)
995
996 @classmethod
998 """Return a string which can be embedded into Python source to
999 represent the given value as an instance of this class."""
1000 class_name = cls.__name__
1001 return '%s(%s)' % (class_name, repr(value))
1002
1004 """Return a string which can be embedded into Python source to
1005 represent the value of this instance."""
1006 return self.PythonLiteral(self)
1007
1012
1013 @classmethod
1015 """STDs have simple type content."""
1016 return True
1017
1018 @classmethod
1026
1027 @classmethod
1029
1030 """NB: Invoking this on a value that is a list will, if necessary,
1031 replace the members of the list with new values that are of the
1032 correct item type. This is permitted because only with lists is it
1033 possible to bypass the normal content validation (by invoking
1034 append/extend on the list instance)."""
1035 if value is None:
1036 raise pyxb.SimpleTypeValueError(cls, value)
1037 value_class = cls
1038 if issubclass(cls, STD_list):
1039 try:
1040 iter(value)
1041 except TypeError:
1042 raise pyxb.SimpleTypeValueError(cls, value)
1043 for v in value:
1044 if not cls._ItemType._IsValidValue(v):
1045 raise pyxb.SimpleListValueError(cls, v)
1046 else:
1047 if issubclass(cls, STD_union):
1048 value_class = None
1049 for mt in cls._MemberTypes:
1050 if mt._IsValidValue(value):
1051 value_class = mt
1052 break
1053 if value_class is None:
1054 raise pyxb.SimpleUnionValueError(cls, value)
1055
1056 if not isinstance(value, value_class):
1057 raise pyxb.SimpleTypeValueError(cls, value)
1058 value_class.XsdConstraintsOK(value)
1059
1062
1065
1071
1072 @classmethod
1073 - def _description (cls, name_only=False, user_documentation=True):
1074 name = cls._Name()
1075 if name_only:
1076 return name
1077 desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
1078 if user_documentation and (cls._Documentation is not None):
1079 desc.extend(["\n", cls._Documentation])
1080 return ''.join(desc)
1081
1083 """Base class for union datatypes.
1084
1085 This class descends only from simpleTypeDefinition. A pyxb.LogicError is
1086 raised if an attempt is made to construct an instance of a subclass of
1087 STD_union. Values consistent with the member types are constructed using
1088 the Factory class method. Values are validated using the _ValidatedMember
1089 class method.
1090
1091 Subclasses must provide a class variable _MemberTypes which is a
1092 tuple of legal members of the union."""
1093
1094 _MemberTypes = None
1095 """A list of classes which are permitted as values of the union."""
1096
1097
1098
1099
1100 __FacetMap = {}
1101
1102 @classmethod
1104 """Given a value, attempt to create an instance of some member of this
1105 union. The first instance which can be legally created is returned.
1106
1107 @keyword _validate_constraints: If C{True} (default if validation is
1108 enabled), any constructed value is checked against constraints applied
1109 to the union as well as the member type.
1110
1111 @raise pyxb.SimpleTypeValueError: no member type will permit creation of
1112 an instance from the parameters in C{args} and C{kw}.
1113 """
1114
1115 used_cls = cls._SupersedingClass()
1116 state = used_cls._PreFactory_vx(args, kw)
1117
1118 rv = None
1119
1120 validate_constraints = kw.get('_validate_constraints', cls._PerformValidation())
1121 assert isinstance(validate_constraints, bool)
1122 if 0 < len(args):
1123 arg = args[0]
1124 try:
1125 rv = cls._ValidatedMember(arg)
1126 except pyxb.SimpleTypeValueError:
1127 pass
1128 if rv is None:
1129 kw['_validate_constraints'] = True
1130 for mt in cls._MemberTypes:
1131 try:
1132 rv = mt.Factory(*args, **kw)
1133 break
1134 except pyxb.SimpleTypeValueError:
1135 pass
1136 except (ValueError, OverflowError):
1137 pass
1138 except:
1139 pass
1140 location = None
1141 if kw is not None:
1142 location = kw.get('_location')
1143 if rv is not None:
1144 if validate_constraints:
1145 cls.XsdConstraintsOK(rv, location)
1146 rv._postFactory_vx(state)
1147 return rv
1148
1149
1150 raise pyxb.SimpleUnionValueError(cls, args, location)
1151
1152 @classmethod
1169
1171 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1172
1173 @classmethod
1174 - def _description (cls, name_only=False, user_documentation=True):
1181
1182 @classmethod
1186
1187
1188 -class STD_list (simpleTypeDefinition, types.ListType):
1189 """Base class for collection datatypes.
1190
1191 This class descends from the Python list type, and incorporates
1192 simpleTypeDefinition. Subclasses must define a class variable _ItemType
1193 which is a reference to the class of which members must be instances."""
1194
1195 _ItemType = None
1196 """A reference to the binding class for items within this list."""
1197
1198
1199
1200 __FacetMap = {}
1201
1202 @classmethod
1204 """Verify that the given value is permitted as an item of this list.
1205
1206 This may convert the value to the proper type, if it is
1207 compatible but not an instance of the item type. Returns the
1208 value that should be used as the item, or raises an exception
1209 if the value cannot be converted.
1210
1211 @param kw: optional dictionary of standard constructor keywords used
1212 when exceptions must be built. In particular, C{_location} may be
1213 useful.
1214 """
1215 if isinstance(value, cls._ItemType):
1216 pass
1217 elif issubclass(cls._ItemType, STD_union):
1218 value = cls._ItemType._ValidatedMember(value)
1219 else:
1220 try:
1221 value = cls._ItemType(value)
1222 except (pyxb.SimpleTypeValueError, TypeError):
1223 location = None
1224 if kw is not None:
1225 location = kw.get('_location')
1226 raise pyxb.SimpleListValueError(cls, value, location)
1227 return value
1228
1229 @classmethod
1231
1232
1233 if 0 < len(args):
1234 arg1 = args[0]
1235 if isinstance(arg1, types.StringTypes):
1236 args = (arg1.split(),) + args[1:]
1237 arg1 = args[0]
1238 is_iterable = False
1239 try:
1240 iter(arg1)
1241 is_iterable = True
1242 except TypeError:
1243 pass
1244 if is_iterable:
1245 new_arg1 = []
1246 for i in range(len(arg1)):
1247 new_arg1.append(cls._ValidatedItem(arg1[i], kw))
1248 args = (new_arg1,) + args[1:]
1249 super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
1250 return super_fn(args, kw)
1251
1252 @classmethod
1255
1256 @classmethod
1258 """Convert from a binding value to a string usable in an XML document."""
1259 return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
1260
1261 @classmethod
1262 - def _description (cls, name_only=False, user_documentation=True):
1268
1269
1270 @classmethod
1273
1274
1277
1283
1286
1289
1290
1291
1294
1295 - def extend (self, x, _from_xml=False):
1297
1300
1301 - def index (self, x, *args):
1303
1306
1309
1310 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1311 """Class that represents a schema element within a binding.
1312
1313 This gets a little confusing. Within a schema, the
1314 L{pyxb.xmlschema.structures.ElementDeclaration} type represents an
1315 U{element
1316 declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>}.
1317 Those declarations may be global (have a name that is visible in the
1318 namespace), or local (have a name that is visible only within a complex
1319 type definition). Further, local (but not global) declarations may have a
1320 reference to a global declaration (which might be in a different
1321 namespace).
1322
1323 Within a PyXB binding, the element declarations from the original complex
1324 type definition that have the same
1325 U{QName<http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-qname>}
1326 (after deconflicting the
1327 U{LocalPart<http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-LocalPart>})
1328 are associated with an attribute in the class for the complex type. Each
1329 of these attributes is defined via a
1330 L{pyxb.binding.content.ElementDeclaration} which provides the mechanism by
1331 which the binding holds values associated with that element.
1332
1333 Furthermore, in the FAC-based content model each schema element
1334 declaration is associated with an
1335 L{ElementUse<pyxb.binding.content.ElementUse>} instance to locate the
1336 point in the schema where content came from. Instances that refer to the
1337 same schema element declaration share the same underlying
1338 L{pyxb.binding.content.ElementDeclaration}.
1339
1340 This element isn't any of those elements. This element is the type used
1341 for an attribute which associates the name of a element with data required
1342 to represent it, all within a particular scope (a module for global scope,
1343 the binding class for a complex type definition for local scope). From
1344 the perspective of a PyXB user they look almost like a class, in that you
1345 can call them to create instances of the underlying complex type.
1346
1347 Global and local elements are represented by instances of this class.
1348 """
1349
1351 """The expanded name of the element within its scope."""
1352 return self.__name
1353 __name = None
1354
1358 __typeDefinition = None
1359
1361 """The L{pyxb.utils.utility.Location} where the element appears in the schema."""
1362 return self.__xsdLocation
1363 __xsdLocation = None
1364
1366 """The scope of the element. This is either C{None}, representing a
1367 top-level element, or an instance of C{complexTypeDefinition} for
1368 local elements."""
1369 return self.__scope
1370 __scope = None
1371
1373 """Indicate whether values matching this element can have U{nil
1374 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
1375 return self.__nillable
1376 __nillable = False
1377
1379 """Indicate whether this element is abstract (must use substitution
1380 group members for matches)."""
1381 return self.__abstract
1382 __abstract = False
1383
1385 """Contents of any documentation annotation in the definition."""
1386 return self.__documentation
1387 __documentation = None
1388
1391 __defaultValue = None
1392
1394 """The L{element} instance to whose substitution group this element
1395 belongs. C{None} if this element is not part of a substitution
1396 group."""
1397 return self.__substitutionGroup
1403 __substitutionGroup = None
1404
1412
1414 """Determine whether an instance of this element can substitute for the other element.
1415
1416 See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>}.
1417
1418 @todo: Do something about blocking constraints. This ignores them, as
1419 does everything leading to this point.
1420 """
1421 if self.substitutionGroup() is None:
1422 return False
1423 if other is None:
1424 return False
1425 assert isinstance(other, element)
1426
1427
1428 if other.scope() is not None:
1429 other = other.name().elementBinding()
1430 if other is None:
1431 return False
1432 assert other.scope() is None
1433
1434 if self.name().elementBinding() == other:
1435 return True
1436 return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
1437
1439 """Stub replaced by _real_substitutesFor when element supports substitution groups."""
1440 return False
1441
1443 """Return a reference to the element instance used for the given name
1444 within this element.
1445
1446 The type for this element must be a complex type definition."""
1447 return self.typeDefinition()._UseForTag(name).elementBinding()
1448
1449 - def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, default_value=None, substitution_group=None, documentation=None, location=None):
1463
1465 """Invoke the Factory method on the type associated with this element.
1466
1467 @keyword _dom_node: This keyword is removed. If present, it must be C{None}.
1468
1469 @note: Other keywords are passed to L{_TypeBinding_mixin.Factory}.
1470
1471 @raise pyxb.AbstractElementError: This element is abstract and no DOM
1472 node was provided.
1473 """
1474 dom_node = kw.pop('_dom_node', None)
1475 assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
1476 if '_element' in kw:
1477 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1478 kw['_element'] = self
1479
1480 if self.abstract():
1481 location = kw.get('_location')
1482 if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
1483 location = dom_node._location()
1484 raise pyxb.AbstractElementError(self, location, args)
1485 rv = self.typeDefinition().Factory(*args, **kw)
1486 rv._setElement(self)
1487 return rv
1488
1515
1516 @classmethod
1518 """Create a binding from a DOM node.
1519
1520 @param node: The DOM node
1521
1522 @param element_binding: An instance of L{element} that would normally
1523 be used to determine the type of the binding. The actual type of
1524 object returned is determined by the type definition associated with
1525 the C{element_binding} and the value of any U{xsi:type
1526 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in
1527 C{node}, modulated by
1528 L{XSI._InterpretTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance._InterpretTypeAttribute>}.
1529
1530 @keyword _fallback_namespace: The namespace to use as the namespace for
1531 the node, if the node name is unqualified. This should be an absent
1532 namespace.
1533
1534 @return: A binding for the DOM node.
1535
1536 @raises pyxb.UnrecognizedDOMRootNodeError: if no underlying element or
1537 type for the node can be identified.
1538 """
1539
1540 if xml.dom.Node.ELEMENT_NODE != node.nodeType:
1541 raise ValueError('node is not an element')
1542
1543 fallback_namespace = kw.get('_fallback_namespace')
1544
1545
1546
1547 if '_element' in kw:
1548 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1549
1550 type_class = None
1551 if element_binding is not None:
1552
1553
1554
1555 if element_binding.abstract():
1556 location = kw.get('location')
1557 if (location is None) and isinstance(node, utility.Locatable_mixin):
1558 location = node._location()
1559 raise pyxb.AbstractElementError(element_binding, location, node)
1560 kw['_element'] = element_binding
1561 type_class = element_binding.typeDefinition()
1562
1563
1564
1565
1566
1567 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
1568 (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
1569
1570 if type_class is None:
1571 raise pyxb.UnrecognizedDOMRootNodeError(node)
1572
1573
1574
1575
1576 is_nil = XSI.nil.getAttribute(node)
1577 if is_nil is not None:
1578 kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1579
1580 rv = type_class.Factory(_dom_node=node, **kw)
1581 assert rv._element() == element_binding
1582 rv._setNamespaceContext(pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node))
1583 return rv._postDOMValidate()
1584
1585
1586 @classmethod
1588 """Create an instance of an element from a DOM node.
1589
1590 This method does minimal processing of C{node} and delegates to
1591 L{CreateDOMBinding}.
1592
1593 @param node: An C{xml.dom.Node} representing a root element. If the
1594 node is a document, that document's root node will be substituted.
1595 The name of the node is extracted as the name of the element to be
1596 created, and the node and the name are passed to L{CreateDOMBinding}.
1597
1598 @param fallback_namespace: The value to pass as C{_fallback_namespace}
1599 to L{CreateDOMBinding}
1600
1601 @return: As with L{CreateDOMBinding}"""
1602 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1603 node = node.documentElement
1604 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1605 return cls.CreateDOMBinding(node, expanded_name.elementBinding(), _fallback_namespace=fallback_namespace)
1606
1608 """Return the element that should be used if this element binding is
1609 permitted and an element with the given name is encountered.
1610
1611 Normally, the incoming name matches the name of this binding, and
1612 C{self} is returned. If the incoming name is different, it is
1613 expected to be the name of a global element which is within this
1614 element's substitution group. In that case, the binding corresponding
1615 to the named element is return.
1616
1617 @return: An instance of L{element}, or C{None} if no element with the
1618 given name can be found.
1619 """
1620
1621
1622 if self.name() == name:
1623 return self
1624
1625
1626 top_elt = self.name().elementBinding()
1627 if top_elt is None:
1628 return None
1629
1630
1631
1632
1633 elt_en = top_elt.name().adoptName(name)
1634 assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
1635 named_elt = elt_en.elementBinding()
1636 if (named_elt is None) or (named_elt == top_elt):
1637 return None
1638 if named_elt.substitutesFor(top_elt):
1639 return named_elt
1640 return None
1641
1643 """Create an instance of this element using a DOM node as the source
1644 of its content.
1645
1646 This method does minimal processing of C{node} and delegates to
1647 L{_createFromDOM}.
1648
1649 @param node: An C{xml.dom.Node} representing a root element. If the
1650 node is a document, that document's root node will be substituted.
1651 The name of the node is extracted as the name of the element to be
1652 created, and the node and the name are passed to L{_createFromDOM}
1653
1654 @keyword fallback_namespace: Used as default for
1655 C{_fallback_namespace} in call to L{_createFromDOM}
1656
1657 @note: Keyword parameters are passed to L{CreateDOMBinding}.
1658
1659 @return: As with L{_createFromDOM}
1660 """
1661 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1662 node = node.documentElement
1663 if fallback_namespace is not None:
1664 kw.setdefault('_fallback_namespace', fallback_namespace)
1665 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1666 return self._createFromDOM(node, expanded_name, **kw)
1667
1669 """Create an instance from a DOM node given the name of an element.
1670
1671 This method does minimal processing of C{node} and C{expanded_name}
1672 and delegates to L{CreateDOMBinding}.
1673
1674 @param node: An C{xml.dom.Node} representing a root element. If the
1675 node is a document, that document's root node will be substituted.
1676 The value is passed to L{CreateDOMBinding}.
1677
1678 @param expanded_name: The expanded name of the element to be used for
1679 content. This is passed to L{elementForName} to obtain the binding
1680 that is passed to L{CreateDOMBinding}, superseding any identification
1681 that might be inferred from C{node}. If no name is available, use
1682 L{createFromDOM}.
1683
1684 @note: Keyword parameters are passed to L{CreateDOMBinding}.
1685
1686 @return: As with L{CreateDOMBinding}.
1687 """
1688 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1689 node = node.documentElement
1690 return element.CreateDOMBinding(node, self.elementForName(expanded_name), **kw)
1691
1693 return 'Element %s' % (self.name(),)
1694
1695 - def _description (self, name_only=False, user_documentation=True):
1709
1711 """Marker in case we need to know that a PST has an enumeration constraint facet."""
1712
1713 @classmethod
1715 """Return a list of values that the enumeration can take."""
1716 return cls._CF_enumeration.values()
1717
1718 @classmethod
1722
1723 @classmethod
1725 """Return the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1726 return cls._CF_enumeration.items()
1727
1728 @classmethod
1730 """Generate the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1731 return cls._CF_enumeration.iteritems()
1732
1733 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1734 """Base for any Python class that serves as the binding for an
1735 XMLSchema complexType.
1736
1737 Subclasses should define a class-level _AttributeMap variable which maps
1738 from the unicode tag of an attribute to the AttributeUse instance that
1739 defines it. Similarly, subclasses should define an _ElementMap variable.
1740 """
1741
1742 _CT_EMPTY = 'EMPTY'
1743 _CT_SIMPLE = 'SIMPLE'
1744 _CT_MIXED = 'MIXED'
1745 _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1746
1747 _ContentTypeTag = None
1748
1749 _TypeDefinition = None
1750 """Subclass of simpleTypeDefinition that corresponds to the type content.
1751 Only valid if _ContentTypeTag is _CT_SIMPLE"""
1752
1753
1754
1755 _HasWildcardElement = False
1756
1757
1758 _ElementMap = { }
1759 """Map from expanded names to ElementDeclaration instances."""
1760
1761
1762
1763 __wildcardAttributeMap = None
1764
1766 """Obtain access to wildcard attributes.
1767
1768 The return value is C{None} if this type does not support wildcard
1769 attributes. If wildcard attributes are allowed, the return value is a
1770 map from QNames to the unicode string value of the corresponding
1771 attribute.
1772
1773 @todo: The map keys should be namespace extended names rather than
1774 QNames, as the in-scope namespace may not be readily available to the
1775 user.
1776 """
1777 return self.__wildcardAttributeMap
1778
1779
1780
1781 __wildcardElements = None
1782
1784 """Obtain access to wildcard elements.
1785
1786 The return value is C{None} if the content model for this type does not
1787 support wildcard elements. If wildcard elements are allowed, the
1788 return value is a list of values corresponding to conformant
1789 unrecognized elements, in the order in which they were encountered.
1790 If the containing binding was created from an XML document and enough
1791 information was present to determine the binding of the member
1792 element, the value is a binding instance. Otherwise, the value is the
1793 original DOM Element node.
1794 """
1795 return self.__wildcardElements
1796
1798 """Create a new instance of this binding.
1799
1800 Arguments are used as transition values along the content model.
1801 Keywords are passed to the constructor of any simple content, or used
1802 to initialize attribute and element values whose L{id
1803 <content.ElementDeclaration.id>} (not L{name <content.ElementDeclaration.name>})
1804 matches the keyword.
1805
1806 @keyword _dom_node: The node to use as the source of binding content.
1807 @type _dom_node: C{xml.dom.Element}
1808
1809 @keyword _location: An optional instance of
1810 L{pyxb.utils.utility.Location} showing the origin the binding. If
1811 C{None}, a value from C{_dom_node} is used if available.
1812
1813 @keyword _from_xml: See L{_TypeBinding_mixin.Factory}
1814
1815 @keyword _finalize_content_model: If C{True} the constructor invokes
1816 L{_TypeBinding_mixin._finalizeContentModel} prior to return. The
1817 value defaults to C{False} when content is assigned through keyword
1818 parameters (bypassing the content model) or neither a C{_dom_node} nor
1819 positional element parameters have been provided, and to C{True} in
1820 all other cases.
1821 """
1822
1823 fallback_namespace = kw.pop('_fallback_namespace', None)
1824 is_nil = False
1825 dom_node = kw.pop('_dom_node', None)
1826 location = kw.pop('_location', None)
1827 from_xml = kw.pop('_from_xml', dom_node is not None)
1828 do_finalize_content_model = kw.pop('_finalize_content_model', None)
1829 if dom_node is not None:
1830 if (location is None) and isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
1831 location = dom_node._location()
1832 if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
1833 dom_node = dom_node.documentElement
1834
1835 is_nil = XSI.nil.getAttribute(dom_node)
1836 if is_nil is not None:
1837 is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1838 if location is not None:
1839 self._setLocation(location)
1840 if self._AttributeWildcard is not None:
1841 self.__wildcardAttributeMap = { }
1842 if self._HasWildcardElement:
1843 self.__wildcardElements = []
1844 if self._Abstract:
1845 raise pyxb.AbstractInstantiationError(type(self), location, dom_node)
1846 super(complexTypeDefinition, self).__init__(**kw)
1847 self.reset()
1848 self._setAttributesFromKeywordsAndDOM(kw, dom_node)
1849 did_set_kw_elt = False
1850 for fu in self._ElementMap.values():
1851 iv = kw.pop(fu.id(), None)
1852 if iv is not None:
1853 did_set_kw_elt = True
1854 fu.set(self, iv)
1855 if do_finalize_content_model is None:
1856 do_finalize_content_model = not did_set_kw_elt
1857 if kw and kw.pop('_strict_keywords', True):
1858 [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
1859 if kw:
1860 raise pyxb.UnprocessedKeywordContentError(self, kw)
1861 if 0 < len(args):
1862 if did_set_kw_elt:
1863 raise pyxb.UsageError('Cannot mix keyword and positional args for element initialization')
1864 self.extend(args, _from_xml=from_xml, _location=location)
1865 elif self._CT_SIMPLE == self._ContentTypeTag:
1866 value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _location=location, _nil=self._isNil(), _apply_attributes=False, *args)
1867 if value._constructedWithValue():
1868 self.append(value)
1869 elif dom_node is not None:
1870 self.extend(dom_node.childNodes[:], fallback_namespace)
1871 else:
1872 do_finalize_content_model = False
1873 if do_finalize_content_model:
1874 self._finalizeContentModel()
1875
1876
1877 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
1878 'xsdConstraintsOK', 'content', 'append', 'extend', 'value', 'reset' ]))
1879
1880
1881
1882 _Automaton = None
1883
1884 @classmethod
1886 """Method used by generated code to associate the element binding with a use in this type.
1887
1888 This is necessary because all complex type classes appear in the
1889 module prior to any of the element instances (which reference type
1890 classes), so the association must be formed after the element
1891 instances are available."""
1892 return cls._UseForTag(element.name())._setElementBinding(element)
1893
1894 @classmethod
1896 """Return the ElementDeclaration object corresponding to the element name.
1897
1898 @param tag: The L{ExpandedName} of an element in the class."""
1899 try:
1900 rv = cls._ElementMap[tag]
1901 except KeyError:
1902 if raise_if_fail:
1903 raise
1904 rv = None
1905 return rv
1906
1908 """Generate a list of children in the order in which they should be
1909 added to the parent when creating a DOM representation of this
1910 object.
1911
1912 @note: This is only used when L{pyxb.RequireValidWhenGenerating} has
1913 disabled validation. Consequently, it may not generate valid XML.
1914 """
1915 order = []
1916 for eu in self._ElementMap.values():
1917 value = eu.value(self)
1918 if value is None:
1919 continue
1920 if isinstance(value, list) and eu.isPlural():
1921 order.extend([ (eu, _v) for _v in value ])
1922 continue
1923 order.append( (eu, value) )
1924 return order
1925
1927 """Provide the child elements and non-element content in an order
1928 consistent with the content model.
1929
1930 Returns a sequence of tuples representing a valid path through the
1931 content model where each transition corresponds to one of the member
1932 element instances within this instance. The tuple is a pair
1933 comprising the L{content.ElementDeclaration} instance and the value for the
1934 transition.
1935
1936 If the content of the instance does not validate against the content
1937 model, C{None} is returned.
1938
1939 @return: C{None} or a list as described above.
1940 """
1941 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1942 return []
1943 self._resetAutomaton()
1944 return self.__automatonConfiguration.sequencedChildren()
1945
1947 """Return a map from L{content.ElementDeclaration} instances to a list of
1948 values associated with that use.
1949
1950 This is used as the set of symbols available for transitions when
1951 validating content against a model. Note that the original
1952 L{content.ElementUse} that may have validated the assignment of the
1953 symbol to the content is no longer available, which may result in a
1954 different order being generated by the content model. Preservation of
1955 the original order mitigates this risk.
1956
1957 The value C{None} is used to provide the wildcard members, if any.
1958
1959 If an element use has no associated values, it must not appear in the
1960 returned map.
1961
1962 @raise pyxb.SimpleTypeValueError: when unable tconverting element
1963 content the binding declaration type.
1964 """
1965 rv = { }
1966 for eu in self._ElementMap.values():
1967 value = eu.value(self)
1968 if value is None:
1969 continue
1970 converter = eu.elementBinding().compatibleValue
1971 if eu.isPlural():
1972 if 0 < len(value):
1973 rv[eu] = [ converter(_v) for _v in value ]
1974 else:
1975 rv[eu] = [ converter(value)]
1976 wce = self.__wildcardElements
1977 if (wce is not None) and (0 < len(wce)):
1978 rv[None] = wce[:]
1979 return rv
1980
1984
2000
2010
2028
2029
2030
2031
2032 __content = None
2033
2034 - def content (self):
2035 """Return the content of the element.
2036
2037 This must be a complex type with complex content. The return value is
2038 a list of the element and non-element content in the order in which it
2039 was added.
2040 @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
2041 """
2042 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
2043 raise pyxb.NotComplexContentError(self)
2044 return self.__content
2045
2047 """Return the value of the element.
2048
2049 This must be a complex type with simple content. The returned value
2050 is expected to be an instance of some L{simpleTypeDefinition} class.
2051
2052 @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
2053 """
2054 if self._CT_SIMPLE != self._ContentTypeTag:
2055 raise pyxb.NotSimpleContentError(self)
2056 return self.__content
2057
2058 - def _resetContent (self):
2059 if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
2060 self.__setContent([])
2061 else:
2062 self.__setContent(None)
2063
2064 __automatonConfiguration = None
2072
2076
2078 """Reset the instance.
2079
2080 This resets all element and attribute fields, and discards any
2081 recorded content. It resets the content model automaton to its
2082 initial state.
2083 """
2084
2085 self._resetContent()
2086 for au in self._AttributeMap.values():
2087 au.reset(self)
2088 for eu in self._ElementMap.values():
2089 eu.reset(self)
2090 self._resetAutomaton()
2091 return self
2092
2093 @classmethod
2095 """Determine what the given name means as an element in this type.
2096
2097 Normally, C{element_name} identifies an element definition within this
2098 type. If so, the returned C{element_decl} identifies that definition,
2099 and the C{element_binding} is extracted from that use.
2100
2101 It may also be that the C{element_name} does not appear as an element
2102 definition, but that it identifies a global element. In that case,
2103 the returned C{element_binding} identifies the global element. If,
2104 further, that element is a member of a substitution group which does
2105 have an element definition in this class, then the returned
2106 C{element_decl} identifies that definition.
2107
2108 If a non-C{None} C{element_decl} is returned, there will be an
2109 associated C{element_binding}. However, it is possible to return a
2110 non-C{None} C{element_binding}, but C{None} as the C{element_decl}. In
2111 that case, the C{element_binding} can be used to create a binding
2112 instance, but the content model will have to treat it as a wildcard.
2113
2114 @param element_name: The name of the element in this type, either an
2115 expanded name or a local name if the element has an absent namespace.
2116
2117 @return: C{( element_binding, element_decl )}
2118 """
2119 element_decl = cls._ElementMap.get(element_name)
2120 element_binding = None
2121 if element_decl is None:
2122 try:
2123 element_binding = element_name.elementBinding()
2124 except pyxb.NamespaceError:
2125 pass
2126 if element_binding is not None:
2127 element_decl = element_binding.findSubstituendDecl(cls)
2128 else:
2129 element_binding = element_decl.elementBinding()
2130 return (element_binding, element_decl)
2131
2132 - def append (self, value, **kw):
2133 """Add the value to the instance.
2134
2135 The value should be a DOM node or other value that is or can be
2136 converted to a binding instance. If the instance has a DFA state, the
2137 value must be permitted by the content model.
2138
2139 @raise pyxb.ContentValidationError: the value is not permitted at the current
2140 state of the content model.
2141 """
2142
2143
2144
2145 element_decl = kw.get('_element_decl', None)
2146 maybe_element = kw.get('_maybe_element', True)
2147 location = kw.get('_location', None)
2148 if self._isNil():
2149 raise pyxb.ContentInNilInstanceError(self, value, location)
2150 fallback_namespace = kw.get('_fallback_namespace', None)
2151 require_validation = kw.get('_require_validation', 'True')
2152 from_xml = kw.get('_from_xml', False)
2153 element_binding = None
2154 if element_decl is not None:
2155 from pyxb.binding import content
2156 assert isinstance(element_decl, content.ElementDeclaration)
2157 element_binding = element_decl.elementBinding()
2158 assert element_binding is not None
2159
2160 if isinstance(value, xml.dom.Node):
2161 from_xml = True
2162 assert maybe_element
2163 assert element_binding is None
2164 node = value
2165 require_validation = pyxb._ParsingRequiresValid
2166 if xml.dom.Node.COMMENT_NODE == node.nodeType:
2167
2168
2169 return self
2170 if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
2171 value = node.data
2172 maybe_element = False
2173 else:
2174
2175 assert xml.dom.Node.ELEMENT_NODE == node.nodeType
2176 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
2177 (element_binding, element_decl) = self._ElementBindingDeclForName(expanded_name)
2178 if element_binding is not None:
2179
2180
2181 value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=fallback_namespace)
2182 else:
2183
2184
2185 try:
2186 value = element.CreateDOMBinding(node, None, _fallback_namespace=fallback_namespace)
2187 except:
2188 _log.warning('Unable to convert DOM node %s at %s to binding', expanded_name, getattr(node, 'location', '[UNAVAILABLE]'))
2189 if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
2190 if (0 == len(value.strip())) and not self._isNil():
2191 return self
2192 if maybe_element and (self.__automatonConfiguration is not None):
2193
2194 if not require_validation:
2195 if element_decl is not None:
2196 element_decl.setOrAppend(self, value)
2197 return self
2198 if self.__wildcardElements is not None:
2199 self._appendWildcardElement(value)
2200 return self
2201 raise pyxb.StructuralBadDocumentError('Validation is required when no element_decl can be found')
2202
2203 num_cand = self.__automatonConfiguration.step(value, element_decl)
2204 if 1 <= num_cand:
2205
2206 return self
2207
2208
2209
2210 if (element_binding is not None) or isinstance(value, (xml.dom.Node, complexTypeDefinition)):
2211 raise pyxb.UnrecognizedContentError(self, self.__automatonConfiguration, value, location)
2212
2213
2214
2215 if self._IsSimpleTypeContent():
2216 if self.__content is not None:
2217 raise pyxb.ExtraSimpleContentError(self, value)
2218 if not self._isNil():
2219 if not isinstance(value, self._TypeDefinition):
2220 value = self._TypeDefinition.Factory(value, _from_xml=from_xml)
2221 self.__setContent(value)
2222 if require_validation:
2223
2224
2225
2226 self.xsdConstraintsOK(location)
2227 return self
2228
2229
2230 if not self._IsMixed():
2231 raise pyxb.MixedContentError(self, value, location)
2232
2233
2234 self._addContent(unicode(value), None)
2235 return self
2236
2239
2240 - def extend (self, value_list, _fallback_namespace=None, _from_xml=False, _location=None):
2241 """Invoke L{append} for each value in the list, in turn."""
2242 [ self.append(_v, _fallback_namespace=_fallback_namespace, _from_xml=_from_xml, _location=_location) for _v in value_list ]
2243 return self
2244
2245 - def __setContent (self, value):
2247
2248 - def _addContent (self, child, element_binding):
2249
2250
2251
2252 assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
2253 if isinstance(child, _TypeBinding_mixin) and (child._element() is None):
2254 child._setElement(element_binding)
2255 self.__content.append(child)
2256
2257 @classmethod
2260
2265
2266 - def _postDOMValidate (self):
2267
2268 self._finalizeContentModel()
2269 if self._PerformValidation():
2270
2271 if (not self._isNil()) and (self.__automatonConfiguration is not None):
2272 if not self.__automatonConfiguration.isAccepting():
2273 raise pyxb.SimpleContentAbsentError(self, self._location())
2274 self._validateAttributes()
2275 return self
2276
2284
2286 """Create a DOM element with the given tag holding the content of this instance."""
2287 element = parent
2288 self._setDOMFromAttributes(dom_support, element)
2289 if self._isNil():
2290 pass
2291 elif self._CT_EMPTY == self._ContentTypeTag:
2292 pass
2293 elif self._CT_SIMPLE == self._ContentTypeTag:
2294 assert self.value() is not None, '%s has no value' % (self,)
2295 element.appendChild(dom_support.document().createTextNode(self.value().xsdLiteral()))
2296 else:
2297 if pyxb._GenerationRequiresValid:
2298 order = self._validatedChildren()
2299 else:
2300 order = self.__childrenForDOM()
2301 for (eu, v) in order:
2302 assert v != self
2303 if eu is None:
2304 if isinstance(v, xml.dom.Node):
2305 dom_support.appendChild(v, element)
2306 else:
2307 v.toDOM(dom_support, parent)
2308 else:
2309 eu.toDOM(dom_support, parent, v)
2310 mixed_content = self.content()
2311 for mc in mixed_content:
2312 pass
2313 return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
2314
2315 @classmethod
2317 """CTDs with simple content are simple; other CTDs are not."""
2318 return cls._CT_SIMPLE == cls._ContentTypeTag
2319
2320 @classmethod
2321 - def _description (cls, name_only=False, user_documentation=True):
2347
2348
2349
2350
2351