1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """This module contains support classes from which schema-specific bindings
16 inherit, and that describe the content models of those schema."""
17
18 import pyxb
19 import xml.dom
20 import pyxb.utils.domutils as domutils
21 import pyxb.utils.utility as utility
22 import types
23 import pyxb.namespace
24 from pyxb.namespace.builtin import XMLSchema_instance as XSI
25
26 BINDING_STYLE_ACCESSOR = 'accessor'
27 BINDING_STYLE_PROPERTY = 'property'
28
29 BINDING_STYLES = (BINDING_STYLE_ACCESSOR, BINDING_STYLE_PROPERTY)
30 DEFAULT_BINDING_STYLE = BINDING_STYLE_PROPERTY
31 CURRENT_BINDING_STYLE = None
38
40
41 @classmethod
52
53 _ExpandedName = None
54 """The expanded name of the component."""
55
56 _ReservedSymbols = set([ 'validateBinding', 'toDOM', 'toxml', 'Factory', 'property' ])
57
58 if pyxb._CorruptionDetectionEnabled:
63
64
65
66 _PyXBFactoryKeywords = ( '_dom_node', '_fallback_namespace', '_from_xml',
67 '_apply_whitespace_facet', '_validate_constraints',
68 '_require_value', '_nil', '_element',
69 '_convert_string_values' )
70 """Keywords that are interpreted by __new__ or __init__ in one or more
71 classes in the PyXB type hierarchy. All these keywords must be removed
72 before invoking base Python __init__ or __new__."""
73
74
75
76
77 _Abstract = False
78
80 """Return a L{namespace context <pyxb.binding.NamespaceContext>}
81 associated with the binding instance.
82
83 This will return C{None} unless something has provided a context to
84 the instance. Context is provided when instances are generated by the
85 DOM and SAX-based translators."""
86 return self.__namespaceContext
87 - def _setNamespaceContext (self, namespace_context):
88 """Associate a L{namespace context <pyxb.binding.NamespaceContext>}
89 with the binding instance."""
90 self.__namespaceContext = namespace_context
91 return self
92 __namespaceContext = None
93
95 """Associate a L{pyxb.binding.basis.element} with the instance."""
96 self.__element = element
97 return self
99 """Return a L{pyxb.binding.basis.element} associated with the binding
100 instance.
101
102 This will return C{None} unless an element has been associated.
103 Constructing a binding instance using the element instance will add
104 this association.
105 """
106 return self.__element
107 __element = None
108
109 __xsiNil = None
111 """Indicate whether this instance is U{nil
112 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
113
114 The value is set by the DOM and SAX parsers when building an instance
115 from a DOM element with U{xsi:nil
116 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set to C{true}.
117
118 @return: C{None} if the element used to create the instance is not
119 U{nillable<http://www.w3.org/TR/xmlschema-1/#nillable>}.
120 If it is nillable, returns C{True} or C{False} depending on
121 whether the instance itself is U{nil<http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
122 """
123 return self.__xsiNil
125 """Set the xsi:nil property of the instance.
126
127 @raise pyxb.NoNillableSupportError: the instance is not associated
128 with an element that is L{nillable
129 <pyxb.binding.basis.element.nillable>}.
130 """
131 if self.__xsiNil is None:
132 raise pyxb.NoNillableSupportError(type(self))
133 self.__xsiNil = True
134 self._resetContent()
135
136 - def _resetContent (self):
138
139 __constructedWithValue = False
153
154
155
156
157 __WarnedUnassociatedElement = False
158
169
170 @classmethod
172 """Method invoked upon entry to the Factory method.
173
174 This method is entitled to modify the keywords array. It can also
175 return a state value which is passed to _postFactory_vx."""
176 return None
177
178 - def _postFactory_vx (cls, state):
179 """Method invoked prior to leaving the Factory method.
180
181 This is an instance method, and is given the state that was returned
182 by _PreFactory_vx."""
183 return None
184
185 @classmethod
187 """Provide a common mechanism to create new instances of this type.
188
189 The class constructor won't do, because you can't create
190 instances of union types.
191
192 This method may be overridden in subclasses (like STD_union). Pre-
193 and post-creation actions can be customized on a per-class instance by
194 overriding the L{_PreFactory_vx} and L{_postFactory_vx} methods.
195
196 @keyword _dom_node: If provided, the value must be a DOM node, the
197 content of which will be used to set the value of the instance.
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.
210
211 @keyword _validate_constraints: If C{True}, any constructed value is
212 checked against constraints applied to the union as well as the member
213 type.
214
215 @keyword _require_value: If C{False} (default), it is permitted to
216 create a value without an initial value. If C{True} and no initial
217 value was provided, causes L{pyxb.MissingContentError} to be raised.
218 Only applies to simpleTypeDefinition instances; this is used when
219 creating values from DOM nodes.
220 """
221
222
223 dom_node = kw.get('_dom_node')
224 kw.setdefault('_from_xml', dom_node is not None)
225 used_cls = cls._SupersedingClass()
226 state = used_cls._PreFactory_vx(args, kw)
227 rv = cls._DynamicCreate(*args, **kw)
228 rv._postFactory_vx(state)
229 if isinstance(dom_node, utility.Locatable_mixin):
230 rv._setLocation(dom_node.location)
231 return rv
232
237
238 @classmethod
240 """Return C{True} iff this is the ur-type.
241
242 The only ur-type is {http://www.w3.org/2001/XMLSchema}anyType. The
243 implementation of this method is overridden for
244 L{pyxb.binding.datatypes.anyType}."""
245 return False
246
247 @classmethod
253
254 @classmethod
256 """Return a variant of the value that is compatible with this type.
257
258 Compatibility is defined relative to the type definition associated
259 with the element. The value C{None} is always compatible. If
260 C{value} has a Python type (e.g., C{int}) that is a superclass of the
261 required L{_TypeBinding_mixin} class (e.g., C{xs:byte}), C{value} is
262 used as a constructor parameter to return a new instance of the
263 required type. Note that constraining facets are applied here if
264 necessary (e.g., although a Python C{int} with value C{500} is
265 type-compatible with C{xs:byte}, it is outside the value space, and
266 compatibility will fail.
267
268 @keyword _convert_string_values: If C{True} (default) and the incoming value is
269 a string, an attempt will be made to form a compatible value by using
270 the string as a constructor argument to the this class. This flag is
271 set to C{False} when testing automaton transitions.
272
273 @raise pyxb.BadTypeValueError: if the value is not both
274 type-consistent and value-consistent with the element's type.
275 """
276 convert_string_values = kw.get('_convert_string_values', True)
277
278 if value is None:
279 return None
280
281 if isinstance(value, cls):
282
283
284 return value
285 value_type = type(value)
286
287 if str == value_type:
288 value_type = unicode
289
290
291
292 if issubclass(cls, value_type):
293 return cls(value)
294
295
296
297 if isinstance(value, int) and issubclass(cls, long):
298 return cls(value)
299
300
301 if isinstance(value, bool) and issubclass(cls, pyxb.binding.datatypes.boolean):
302 return cls(value)
303
304
305
306 if convert_string_values and (unicode == value_type):
307 return cls(value)
308
309
310 if issubclass(cls, STD_union):
311 for mt in cls._MemberTypes:
312 try:
313 return mt._CompatibleValue(value, **kw)
314 except:
315 pass
316
317
318 if (pyxb.binding.datatypes.anySimpleType == cls) and issubclass(value_type, simpleTypeDefinition):
319 return value
320 if pyxb.binding.datatypes.anyType == cls:
321 if not isinstance(value, _TypeBinding_mixin):
322 print 'NOTE: Created %s instance from value of type %s' % (cls._ExpandedName, type(value))
323 value = cls(value)
324 return value
325
326
327
328 if isinstance(value, pyxb.BIND):
329 return value.createInstance(cls.Factory, **kw)
330
331
332
333
334
335
336 raise pyxb.BadTypeValueError('No conversion from %s to %s' % (value_type, cls))
337
338 @classmethod
340 """Return True iff the content of this binding object is a simple type.
341
342 This is true only for descendents of simpleTypeDefinition and instances
343 of complexTypeDefinition that have simple type content."""
344 raise pyxb.LogicError('Failed to override _TypeBinding_mixin._IsSimpleTypeContent')
345
346
347
348
349 _AttributeWildcard = None
350
351 _AttributeMap = { }
352 """Map from expanded names to AttributeUse instances. Non-empty only in
353 L{complexTypeDefinition} subclasses."""
354
355 @classmethod
375
377 """Invoke self._setAttribute based on node attributes and keywords.
378
379 Though attributes can only legally appear in complexTypeDefinition
380 instances, delayed conditional validation requires caching them in
381 simpleTypeDefinition.
382
383 @param kw: keywords passed to the constructor. This map is mutated by
384 the call: keywords corresponding to recognized attributes are removed.
385
386 @param dom_node: an xml.dom Node instance, possibly C{None}
387 """
388
389
390 attribute_settings = { }
391 if dom_node is not None:
392 attribute_settings.update(self.__AttributesFromDOM(dom_node))
393 for fu in self._AttributeMap.values():
394 iv = kw.pop(fu.id(), None)
395 if iv is not None:
396 attribute_settings[fu.name()] = iv
397 for (attr_en, value) in attribute_settings.items():
398 au = self._setAttribute(attr_en, value)
399
400 - def toDOM (self, bds=None, parent=None, element_name=None):
401 """Convert this instance to a DOM node.
402
403 The name of the top-level element is either the name of the L{element}
404 instance associated with this instance, or the XML name of the type of
405 this instance.
406
407 @param bds: Support for customizing the generated document
408 @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
409 @param parent: If C{None}, a standalone document is created;
410 otherwise, the created element is a child of the given element.
411 @type parent: C{xml.dom.Element} or C{None}
412 @rtype: C{xml.dom.Document}
413 """
414
415 if bds is None:
416 bds = domutils.BindingDOMSupport()
417 need_xsi_type = bds.requireXSIType()
418 if isinstance(element_name, (str, unicode)):
419 element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
420 if (element_name is None) and (self._element() is not None):
421 element_binding = self._element()
422 element_name = element_binding.name()
423 need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
424 if element_name is None:
425 element_name = self._ExpandedName
426 element = bds.createChildElement(element_name, parent)
427 if need_xsi_type:
428 val_type_qname = self._ExpandedName.localName()
429 tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
430 if tns_prefix is not None:
431 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
432 bds.addAttribute(element, XSI.type, val_type_qname)
433 self._toDOM_csc(bds, element)
434 bds.finalize()
435 return bds.document()
436
437 - def toxml (self, encoding=None, bds=None, root_only=False):
438 """Shorthand to get the object as an XML document.
439
440 If you want to set the default namespace, pass in a pre-configured
441 C{bds}.
442
443 @param encoding: The encoding to be used. See
444 @C{xml.dom.Node.toxml()} for a description of why you should always
445 pass @C{'utf-8'} here. Because this method follows the contract of
446 the corresponding C{xml.dom.Node} method, it does not automatically
447 get the default PyXB output encoding.
448
449 @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
450 to use for creation. If not provided (default), a new generic one is
451 created.
452 """
453 dom = self.toDOM(bds)
454 if root_only:
455 dom = dom.documentElement
456 return dom.toxml(encoding)
457
463
465 """Override in subclasses for type-specific validation of instance
466 content.
467
468 @return: C{True} if the instance validates
469 @raise pyxb.BindingValidationError: complex content does not match model
470 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
471 """
472 raise pyxb.IncompleteImplementationError('%s did not override _validateBinding_vx' % (type(self),))
473
475 """Check whether the binding content matches its content model.
476
477 @return: C{True} if validation succeeds.
478 @raise pyxb.BindingValidationError: complex content does not match model
479 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
480 """
481 if self._PerformValidation():
482 self._validateBinding_vx()
483 return True
484
485 - def _postDOMValidate (self):
486 self.validateBinding()
487 return self
488
489 @classmethod
496
498 """Helper to allow overriding the implementation class.
499
500 Generally we'll want to augment the generated bindings by subclassing
501 them, and adding functionality to the subclass. This mix-in provides a
502 way to communicate the existence of the superseding subclass back to the
503 binding infrastructure, so that when it creates an instance it uses the
504 subclass rather than the unaugmented binding class.
505
506 When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
507 invoked on the raw class passing in the superseding subclass. E.g.::
508
509 class mywsdl (raw.wsdl):
510 pass
511 raw.wsdl._SetSupersedingClass(mywsdl)
512
513 """
514
515 @classmethod
517 return '_%s__SupersedingClass' % (cls.__name__,)
518
519 @classmethod
521 return '_%s__AlternativeConstructor' % (cls.__name__,)
522
523 @classmethod
527
528 @classmethod
530 """Return the class stored in the class reference attribute."""
531 rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
532 if isinstance(rv, tuple):
533 rv = rv[0]
534 return rv
535
536 @classmethod
538 """Set the class reference attribute.
539
540 @param superseding: A Python class that is a subclass of this class.
541 """
542 assert (superseding is None) or issubclass(superseding, cls)
543 if superseding is None:
544 cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
545 else:
546 setattr(cls, cls.__SupersedingClassAttribute(), superseding)
547 return superseding
548
549 @classmethod
551 attr = cls.__AlternativeConstructorAttribute()
552 if alternative_constructor is None:
553 cls.__dict__.pop(attr, None)
554 else:
555
556
557
558 setattr(cls, attr, (alternative_constructor,))
559 assert cls._AlternativeConstructor() == alternative_constructor
560 return alternative_constructor
561
562 @classmethod
574
575 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
576 """L{simpleTypeDefinition} is a base class that is part of the
577 hierarchy of any class that represents the Python datatype for a
578 L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
579
580 @note: This class, or a descendent of it, must be the first class
581 in the method resolution order when a subclass has multiple
582 parents. Otherwise, constructor keyword arguments may not be
583 removed before passing them on to Python classes that do not
584 accept them.
585 """
586
587
588
589
590 __FacetMap = {}
591
592 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
593 'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
594 'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
595 'PythonLiteral', 'pythonLiteral',
596 'SimpleTypeDefinition' ]))
597 """Symbols that remain the responsibility of this class. Any
598 public symbols in generated binding subclasses are deconflicted
599 by providing an alternative name in the subclass. (There
600 currently are no public symbols in generated SimpleTypeDefinion
601 bindings."""
602
603
604 @classmethod
612
613
614
615
616 __FacetMapAttributeNameMap = { }
617 @classmethod
619 """ """
620 '''
621 if cls == simpleTypeDefinition:
622 return '_%s__FacetMap' % (cls.__name__.strip('_'),)
623
624 # It is not uncommon for a class in one namespace to extend a class of
625 # the same name in a different namespace, so encode the namespace URI
626 # in the attribute name (if it is part of a namespace).
627 ns_uri = ''
628 try:
629 ns_uri = cls._ExpandedName.namespaceURI()
630 except Exception, e:
631 pass
632 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
633 '''
634 nm = cls.__FacetMapAttributeNameMap.get(cls)
635 if nm is None:
636 nm = cls.__name__
637 if nm.endswith('_'):
638 nm += '1'
639 if cls == simpleTypeDefinition:
640 nm = '_%s__FacetMap' % (nm,)
641 else:
642
643
644
645 ns_uri = ''
646 try:
647 ns_uri = cls._ExpandedName.namespaceURI()
648 except Exception, e:
649 pass
650 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
651 cls.__FacetMapAttributeNameMap[cls] = nm
652 return nm
653
654 @classmethod
656 """Return a reference to the facet map for this datatype.
657
658 The facet map is a map from leaf facet classes to instances of those
659 classes that constrain or otherwise apply to the lexical or value
660 space of the datatype. Classes may inherit their facet map from their
661 superclass, or may create a new class instance if the class adds a new
662 constraint type.
663
664 :raise AttributeError: if the facet map has not been defined"""
665 return getattr(cls, cls.__FacetMapAttributeName())
666
667 @classmethod
669 """Initialize the facet map for this datatype.
670
671 This must be called exactly once, after all facets belonging to the
672 datatype have been created.
673
674 :raise pyxb.LogicError: if called multiple times (on the same class)
675 :raise pyxb.LogicError: if called when a parent class facet map has not been initialized
676 :return: the facet map"""
677 fm = None
678 try:
679 fm = cls._FacetMap()
680 except AttributeError:
681 pass
682 if fm is not None:
683 raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
684
685
686
687
688
689 source_class = cls
690 while fm is None:
691
692
693 for super_class in source_class.mro():
694
695 assert super_class is not None
696 if (super_class == simpleTypeDefinition):
697 break
698 if issubclass(super_class, simpleTypeDefinition):
699 try:
700 fm = super_class._FacetMap()
701
702 break
703 except AttributeError:
704 pass
705 if fm is None:
706 try:
707 source_class = source_class.XsdSuperType()
708 except AttributeError:
709 source_class = None
710
711 if source_class is None:
712 fm = { }
713
714 if fm is None:
715 raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
716 fm = fm.copy()
717
718 for facet in args:
719 fm[type(facet)] = facet
720
721
722 setattr(cls, cls.__FacetMapAttributeName(), fm)
723 return fm
724
725 @classmethod
728
729 @classmethod
731 """Pre-process the arguments.
732
733 This is used before invoking the parent constructor. One application
734 is to apply the whitespace facet processing; if such a request is in
735 the keywords, it is removed so it does not propagate to the
736 superclass. Another application is to convert the arguments from a
737 string to a list. Binding-specific applications are performed in the
738 overloaded L{_ConvertArguments_vx} method."""
739 dom_node = kw.pop('_dom_node', None)
740 from_xml = kw.get('_from_xml', dom_node is not None)
741 if dom_node is not None:
742 text_content = domutils.ExtractTextContent(dom_node)
743 if text_content is not None:
744 args = (domutils.ExtractTextContent(dom_node),) + args
745 kw['_apply_whitespace_facet'] = True
746 apply_whitespace_facet = kw.pop('_apply_whitespace_facet', from_xml)
747 if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
748 cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
749 if cf_whitespace is not None:
750
751 norm_str = unicode(cf_whitespace.normalizeString(args[0]))
752 args = (norm_str,) + args[1:]
753 kw['_from_xml'] = from_xml
754 return cls._ConvertArguments_vx(args, kw)
755
756
757
758
759
760
761
762
763
764
765
767
768 kw.pop('_validate_constraints', None)
769 kw.pop('_require_value', None)
770 kw.pop('_element', None)
771 kw.pop('_fallback_namespace', None)
772 kw.pop('_nil', None)
773
774 dom_node = kw.get('_dom_node')
775 args = cls._ConvertArguments(args, kw)
776 kw.pop('_from_xml', dom_node is not None)
777 assert issubclass(cls, _TypeBinding_mixin)
778 try:
779 rv = super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
780 rv._setAttributesFromKeywordsAndDOM(kw, dom_node)
781 return rv
782 except ValueError, e:
783 raise pyxb.BadTypeValueError(e)
784 except OverflowError, e:
785 raise pyxb.BadTypeValueError(e)
786
787
788
790 """Initialize a newly created STD instance.
791
792 Usually there is one positional argument, which is a value that can be
793 converted to the underlying Python type.
794
795 @keyword _validate_constraints: If True (default), the newly
796 constructed value is checked against its constraining facets.
797 @type _validate_constraints: C{bool}
798 """
799
800 validate_constraints = kw.pop('_validate_constraints', self._PerformValidation())
801 require_value = kw.pop('_require_value', False)
802
803
804 args = self._ConvertArguments(args, kw)
805 try:
806 super(simpleTypeDefinition, self).__init__(*args, **kw)
807 except OverflowError, e:
808 raise pyxb.BadTypeValueError(e)
809 if require_value and (not self._constructedWithValue()):
810 raise pyxb.MissingContentError('missing value')
811
812 if validate_constraints:
813 self.xsdConstraintsOK()
814
815
816
817
818
819
820
821 @classmethod
823 return '_%s__SimpleTypeDefinition' % (cls.__name__,)
824
825 @classmethod
827 """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
828 associated with this binding."""
829 attr_name = cls.__STDAttrName()
830 if hasattr(cls, attr_name):
831 old_value = getattr(cls, attr_name)
832 if old_value != std:
833 raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
834 setattr(cls, attr_name, std)
835
836 @classmethod
838 """Return the SimpleTypeDefinition instance for the given
839 class.
840
841 This should only be invoked when generating bindings.
842
843 @raise pyxb.IncompleteImplementationError: no STD instance has been
844 associated with the class.
845
846 """
847 attr_name = cls.__STDAttrName()
848 if hasattr(cls, attr_name):
849 return getattr(cls, attr_name)
850 raise pyxb.IncompleteImplementationError('%s: No STD available' % (cls,))
851
852 @classmethod
854 """Convert from a python value to a string usable in an XML
855 document.
856
857 This should be implemented in the subclass."""
858 raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
859
861 """Return text suitable for representing the value of this
862 instance in an XML document.
863
864 The base class implementation delegates to the object class's
865 XsdLiteral method."""
866 if self._isNil():
867 return ''
868 return self.XsdLiteral(self)
869
870 @classmethod
872 """Find the nearest parent class in the PST hierarchy.
873
874 The value for anySimpleType is None; for all others, it's a
875 primitive or derived PST descendent (including anySimpleType)."""
876 for sc in cls.mro():
877 if sc == cls:
878 continue
879 if simpleTypeDefinition == sc:
880
881
882
883 return cls._XsdBaseType
884 if issubclass(sc, simpleTypeDefinition):
885 return sc
886 raise pyxb.LogicError('No supertype found for %s' % (cls,))
887
888 @classmethod
890 """Pre-extended class method to verify other things before
891 checking constraints.
892
893 This is used for list types, to verify that the values in the
894 list are acceptable, and for token descendents, to check the
895 lexical/value space conformance of the input.
896 """
897 super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
898 return super_fn(value)
899
900
901
902 __ClassFacetSequence = { }
903
904 @classmethod
906 """Validate the given value against the constraints on this class.
907
908 @raise pyxb.BadTypeValueError: if any constraint is violated.
909 """
910
911 value = cls._XsdConstraintsPreCheck_vb(value)
912
913 facet_values = cls.__ClassFacetSequence.get(cls)
914 if facet_values is None:
915
916
917 classes = [ _x for _x in cls.mro() if issubclass(_x, simpleTypeDefinition) ]
918 classes.reverse()
919 cache_result = True
920 facet_values = []
921 for clazz in classes:
922
923
924
925
926
927
928 try:
929 clazz_facets = clazz._FacetMap().values()
930 except AttributeError, e:
931 cache_result = False
932 clazz_facets = []
933 for v in clazz_facets:
934 if not (v in facet_values):
935 facet_values.append(v)
936 if cache_result:
937 cls.__ClassFacetSequence[cls] = facet_values
938 for f in facet_values:
939 if not f.validateConstraint(value):
940 raise pyxb.BadTypeValueError('%s violation for %s in %s' % (f.Name(), value, cls.__name__))
941
942 return value
943
945 """Validate the value of this instance against its constraints."""
946 return self.XsdConstraintsOK(self)
947
952
953 @classmethod
955 """Return the length of the given value.
956
957 The length is calculated by a subclass implementation of
958 _XsdValueLength_vx in accordance with
959 http://www.w3.org/TR/xmlschema-2/#rf-length.
960
961 The return value is a non-negative integer, or C{None} if length
962 constraints should be considered trivially satisfied (as with
963 QName and NOTATION).
964
965 :raise pyxb.LogicError: the provided value is not an instance of cls.
966 :raise pyxb.LogicError: an attempt is made to calculate a length for
967 an instance of a type that does not support length calculations.
968 """
969 assert isinstance(value, cls)
970 if not hasattr(cls, '_XsdValueLength_vx'):
971 raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
972 return cls._XsdValueLength_vx(value)
973
975 """Return the length of this instance within its value space.
976
977 See XsdValueLength."""
978 return self.XsdValueLength(self)
979
980 @classmethod
982 """Return a string which can be embedded into Python source to
983 represent the given value as an instance of this class."""
984 class_name = cls.__name__
985 return '%s(%s)' % (class_name, repr(value))
986
988 """Return a string which can be embedded into Python source to
989 represent the value of this instance."""
990 return self.PythonLiteral(self)
991
996
997 @classmethod
999 """STDs have simple type content."""
1000 return True
1001
1002 @classmethod
1010
1011 @classmethod
1013
1014 """NB: Invoking this on a value that is a list will, if necessary,
1015 replace the members of the list with new values that are of the
1016 correct item type. This is permitted because only with lists is it
1017 possible to bypass the normal content validation (by invoking
1018 append/extend on the list instance)."""
1019 if value is None:
1020 raise pyxb.BadTypeValueError('None is not a valid instance of %s' % (cls,))
1021
1022 value_class = cls
1023 if issubclass(cls, STD_list):
1024
1025 try:
1026 iter(value)
1027 except TypeError, e:
1028 raise pyxb.BadTypeValueError('%s cannot have non-iterable value type %s' % (cls, type(value)))
1029 for v in value:
1030 if not cls._ItemType._IsValidValue(v):
1031 raise pyxb.BadTypeValueError('%s cannot have member of type %s (want %s)' % (cls, type(v), cls._ItemType))
1032 else:
1033 if issubclass(cls, STD_union):
1034
1035 value_class = None
1036 for mt in cls._MemberTypes:
1037 if mt._IsValidValue(value):
1038 value_class = mt
1039 break
1040 if value_class is None:
1041 raise pyxb.BadTypeValueError('%s cannot have value type %s' % (cls, type(value)))
1042
1043 if not isinstance(value, value_class):
1044 raise pyxb.BadTypeValueError('Value type %s is not valid for %s' % (type(value), cls))
1045 value_class.XsdConstraintsOK(value)
1046
1049
1052
1055
1056 @classmethod
1057 - def _description (cls, name_only=False, user_documentation=True):
1058 name = cls._Name()
1059 if name_only:
1060 return name
1061 desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
1062 if user_documentation and (cls._Documentation is not None):
1063 desc.extend(["\n", cls._Documentation])
1064 return ''.join(desc)
1065
1067 """Base class for union datatypes.
1068
1069 This class descends only from simpleTypeDefinition. A pyxb.LogicError is
1070 raised if an attempt is made to construct an instance of a subclass of
1071 STD_union. Values consistent with the member types are constructed using
1072 the Factory class method. Values are validated using the _ValidatedMember
1073 class method.
1074
1075 Subclasses must provide a class variable _MemberTypes which is a
1076 tuple of legal members of the union."""
1077
1078 _MemberTypes = None
1079 """A list of classes which are permitted as values of the union."""
1080
1081
1082
1083
1084 __FacetMap = {}
1085
1086 @classmethod
1088 """Given a value, attempt to create an instance of some member of this
1089 union. The first instance which can be legally created is returned.
1090
1091 @keyword _validate_constraints: If True (default), any constructed
1092 value is checked against constraints applied to the union as well as
1093 the member type.
1094
1095 @raise pyxb.BadTypeValueError: no member type will permit creation of
1096 an instance from the parameters in C{args} and C{kw}.
1097 """
1098
1099 used_cls = cls._SupersedingClass()
1100 state = used_cls._PreFactory_vx(args, kw)
1101
1102 rv = None
1103
1104 validate_constraints = kw.get('_validate_constraints', cls._PerformValidation())
1105 assert isinstance(validate_constraints, bool)
1106 if 0 < len(args):
1107 arg = args[0]
1108 try:
1109 rv = cls._ValidatedMember(arg)
1110 except pyxb.BadTypeValueError, e:
1111 pass
1112 if rv is None:
1113 kw['_validate_constraints'] = True
1114 for mt in cls._MemberTypes:
1115 try:
1116 rv = mt.Factory(*args, **kw)
1117 break
1118 except pyxb.BadTypeValueError:
1119 pass
1120 except ValueError:
1121 pass
1122 except:
1123 pass
1124 if rv is not None:
1125 if validate_constraints:
1126 cls.XsdConstraintsOK(rv)
1127 rv._postFactory_vx(state)
1128 return rv
1129 raise pyxb.BadTypeValueError('%s cannot construct union member from args %s' % (cls.__name__, args))
1130
1131 @classmethod
1133 """Validate the given value as a potential union member.
1134
1135 @raise pyxb.BadTypeValueError: the value is not an instance of a
1136 member type."""
1137 if not isinstance(value, cls._MemberTypes):
1138 for mt in cls._MemberTypes:
1139 try:
1140
1141
1142 value = mt.Factory(value, _validate_constraints=True)
1143 return value
1144 except (TypeError, pyxb.BadTypeValueError):
1145 pass
1146 raise pyxb.BadTypeValueError('%s cannot hold a member of type %s' % (cls.__name__, value.__class__.__name__))
1147 return value
1148
1150 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1151
1152 @classmethod
1153 - def _description (cls, name_only=False, user_documentation=True):
1160
1161 @classmethod
1165
1166
1167 -class STD_list (simpleTypeDefinition, types.ListType):
1168 """Base class for collection datatypes.
1169
1170 This class descends from the Python list type, and incorporates
1171 simpleTypeDefinition. Subclasses must define a class variable _ItemType
1172 which is a reference to the class of which members must be instances."""
1173
1174 _ItemType = None
1175 """A reference to the binding class for items within this list."""
1176
1177
1178
1179 __FacetMap = {}
1180
1181 @classmethod
1199
1200 @classmethod
1202
1203
1204 if 0 < len(args):
1205 arg1 = args[0]
1206 if isinstance(arg1, types.StringTypes):
1207 args = (arg1.split(),) + args[1:]
1208 arg1 = args[0]
1209 is_iterable = False
1210 try:
1211 iter(arg1)
1212 is_iterable = True
1213 except TypeError:
1214 pass
1215 if is_iterable:
1216 new_arg1 = []
1217 for i in range(len(arg1)):
1218 new_arg1.append(cls._ValidatedItem(arg1[i]))
1219 args = (new_arg1,) + args[1:]
1220 super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
1221 return super_fn(args, kw)
1222
1223 @classmethod
1226
1227 @classmethod
1229 """Convert from a binding value to a string usable in an XML document."""
1230 return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
1231
1232 @classmethod
1233 - def _description (cls, name_only=False, user_documentation=True):
1239
1240
1241 @classmethod
1244
1245
1248
1254
1257
1260
1261
1262
1265
1266 - def extend (self, x, _from_xml=False):
1268
1271
1272 - def index (self, x, *args):
1274
1277
1280
1281 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1282 """Class that represents a schema element.
1283
1284 Global and local elements are represented by instances of this class.
1285 """
1286
1288 """The expanded name of the element within its scope."""
1289 return self.__name
1290 __name = None
1291
1295 __typeDefinition = None
1296
1298 """The scope of the element. This is either C{None}, representing a
1299 top-level element, or an instance of C{complexTypeDefinition} for
1300 local elements."""
1301 return self.__scope
1302 __scope = None
1303
1305 """Indicate whether values matching this element can have U{nil
1306 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
1307 return self.__nillable
1308 __nillable = False
1309
1311 """Indicate whether this element is abstract (must use substitution
1312 group members for matches)."""
1313 return self.__abstract
1314 __abstract = False
1315
1317 """Contents of any documentation annotation in the definition."""
1318 return self.__documentation
1319 __documentation = None
1320
1323 __defaultValue = None
1324
1326 """The L{element} instance to whose substitution group this element
1327 belongs. C{None} if this element is not part of a substitution
1328 group."""
1329 return self.__substitutionGroup
1335 __substitutionGroup = None
1336
1344
1346 """Determine whether an instance of this element can substitute for the other element.
1347
1348 See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>)}.
1349
1350 @todo: Do something about blocking constraints. This ignores them, as
1351 does everything leading to this point.
1352 """
1353 if self.substitutionGroup() is None:
1354 return False
1355 if other is None:
1356 return False
1357 assert isinstance(other, element)
1358
1359
1360 if other.scope() is not None:
1361 other = other.name().elementBinding()
1362 if other is None:
1363 return False
1364 assert other.scope() is None
1365
1366 if self.name().elementBinding() == other:
1367 return True
1368 return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
1369
1371 """Stub replaced by _real_substitutesFor when element supports substitution groups."""
1372 return False
1373
1375 """Return a reference to the element instance used for the given name
1376 within this element.
1377
1378 The type for this element must be a complex type definition."""
1379 return self.typeDefinition()._UseForTag(name).elementBinding()
1380
1381 - def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, default_value=None, substitution_group=None, documentation=None):
1393
1395 """Invoke the Factory method on the type associated with this element.
1396
1397 @keyword _dom_node: If set, specifies a DOM node that should be used
1398 for initialization. In that case, the L{createFromDOM} method is
1399 invoked instead of the type definition Factory method.
1400
1401 @note: Other keywords are passed to L{_TypeBinding_mixin.Factory}.
1402
1403 @raise pyxb.AbstractElementError: This element is abstract and no DOM
1404 node was provided.
1405 """
1406 dom_node = kw.pop('_dom_node', None)
1407 assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
1408 if '_element' in kw:
1409 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1410 kw['_element'] = self
1411
1412 if self.abstract():
1413 raise pyxb.AbstractElementError(self)
1414 return self.typeDefinition().Factory(*args, **kw)
1415
1438
1439
1440 @classmethod
1452
1454 """Return the element that should be used if this element binding is
1455 permitted and an element with the given name is encountered.
1456
1457 Normally, the incoming name matches the name of this binding, and
1458 C{self} is returned. If the incoming name is different, it is
1459 expected to be the name of a global element which is within this
1460 element's substitution group. In that case, the binding corresponding
1461 to the named element is return.
1462
1463 @return: An instance of L{element}, or C{None} if no element with the
1464 given name can be found.
1465 """
1466
1467
1468 if self.name() == name:
1469 return self
1470
1471
1472 top_elt = self.name().elementBinding()
1473 if top_elt is None:
1474 return None
1475
1476
1477
1478
1479 elt_en = top_elt.name().adoptName(name)
1480 assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
1481 named_elt = elt_en.elementBinding()
1482 if (named_elt is None) or (named_elt == top_elt):
1483 return None
1484 if named_elt.substitutesFor(top_elt):
1485 return named_elt
1486 return None
1487
1488 - def createFromDOM (self, node, expanded_name=None, fallback_namespace=None, **kw):
1489 """Create a binding instance from the given DOM node.
1490
1491 @keyword expanded_name: Optional name for the DOM node. If not
1492 present, is inferred from C{node}.
1493
1494 @keyword fallback_namespace: Optional namespace to use when resolving
1495 unqualified names.
1496 """
1497 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1498 node = node.documentElement
1499 if expanded_name is None:
1500 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1501 return self._createFromDOM(node, expanded_name, **kw)
1502
1504 """Create a binding instance from the given DOM node, using the
1505 provided name to identify the correct binding.
1506
1507 The context and information associated with this element is used to
1508 identify the actual element binding to use. By default, C{self} is
1509 used. If this element represents a term in a content model, the name
1510 and namespace of the incoming node may identify a different element.
1511 If that element is a member of this element's substitution group, the
1512 binding associated with the node's name will be used instead.
1513
1514 The type of object returned is determined by the type definition
1515 associated with the element binding and the value of any U{xsi:type
1516 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in the
1517 node, modulated by the configuration of L{XSI.ProcessTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance.ProcessTypeAttribute>}.
1518
1519 Keyword parameters are passed to the factory method of the type
1520 associated with the selected element binding. See
1521 L{_TypeBinding_mixin} and any specializations of it.
1522
1523 @param expanded_name: The expanded name of the node. If the value is
1524 C{None}, defaults to the name of this element. (In the case of
1525 substitution groups, the default is wrong, but correct inference
1526 depends on context not available here.)
1527
1528 @keyword _fallback_namespace: Optional namespace to use when resolving
1529 unqualified type names.
1530
1531 @param node: The DOM node specifying the element content. If this is
1532 a (top-level) Document node, its element node is used.
1533 @type node: C{xml.dom.Node}
1534 @return: An instance of L{_TypeBinding_mixin}
1535 @raise pyxb.StructuralBadDocumentError: The node's name does identify an element binding.
1536 @raise pyxb.AbstractElementError: The element binding associated with the node is abstract.
1537 @raise pyxb.BadDocumentError: An U{xsi:type <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute in the node fails to resolve to a recognized type
1538 @raise pyxb.BadDocumentError: An U{xsi:type <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute in the node resolves to a type that is not a subclass of the type of the element binding.
1539 """
1540
1541
1542
1543 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1544 node = node.documentElement
1545
1546
1547
1548
1549
1550 fallback_namespace = kw.pop('_fallback_namespace', None)
1551 element_binding = self.elementForName(expanded_name)
1552 if element_binding is None:
1553 raise pyxb.StructuralBadDocumentError('Element %s cannot create from node %s' % (self.name(), expanded_name))
1554
1555
1556
1557
1558 if element_binding.abstract():
1559 raise pyxb.AbstractElementError(element_binding)
1560
1561
1562
1563 if '_element' in kw:
1564 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1565 kw['_element'] = element_binding
1566
1567
1568
1569 type_class = element_binding.typeDefinition()
1570 elt_ns = element_binding.name().namespace()
1571
1572
1573
1574
1575
1576 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
1577 (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
1578
1579
1580
1581
1582 is_nil = XSI.nil.getAttribute(node)
1583 if is_nil is not None:
1584 kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1585
1586 rv = type_class.Factory(_dom_node=node, _fallback_namespace=fallback_namespace, **kw)
1587 assert rv._element() == element_binding
1588 rv._setNamespaceContext(ns_ctx)
1589 return rv._postDOMValidate()
1590
1592 return 'Element %s' % (self.name(),)
1593
1594 - def _description (self, name_only=False, user_documentation=True):
1608
1610 """Marker in case we need to know that a PST has an enumeration constraint facet."""
1611
1612 @classmethod
1614 """Return a list of values that the enumeration can take."""
1615 return cls._CF_enumeration.values()
1616
1617 @classmethod
1621
1622 @classmethod
1624 """Return the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1625 return cls._CF_enumeration.items()
1626
1627 @classmethod
1629 """Generate the associated L{pyxb.binding.facet._EnumerationElement} instances."""
1630 return cls._CF_enumeration.iteritems()
1631
1632 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1633 """Base for any Python class that serves as the binding for an
1634 XMLSchema complexType.
1635
1636 Subclasses should define a class-level _AttributeMap variable which maps
1637 from the unicode tag of an attribute to the AttributeUse instance that
1638 defines it. Similarly, subclasses should define an _ElementMap variable.
1639 """
1640
1641 _CT_EMPTY = 'EMPTY'
1642 _CT_SIMPLE = 'SIMPLE'
1643 _CT_MIXED = 'MIXED'
1644 _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1645
1646 _ContentTypeTag = None
1647
1648 _TypeDefinition = None
1649 """Subclass of simpleTypeDefinition that corresponds to the type content.
1650 Only valid if _ContentTypeTag is _CT_SIMPLE"""
1651
1652
1653
1654 _HasWildcardElement = False
1655
1656
1657 _ElementMap = { }
1658 """Map from expanded names to ElementUse instances."""
1659
1660
1661
1662 __wildcardAttributeMap = None
1663
1665 """Obtain access to wildcard attributes.
1666
1667 The return value is C{None} if this type does not support wildcard
1668 attributes. If wildcard attributes are allowed, the return value is a
1669 map from QNames to the unicode string value of the corresponding
1670 attribute.
1671
1672 @todo: The map keys should be namespace extended names rather than
1673 QNames, as the in-scope namespace may not be readily available to the
1674 user.
1675 """
1676 return self.__wildcardAttributeMap
1677
1678
1679
1680 __wildcardElements = None
1681
1683 """Obtain access to wildcard elements.
1684
1685 The return value is C{None} if the content model for this type does not
1686 support wildcard elements. If wildcard elements are allowed, the
1687 return value is a list of values corresponding to conformant
1688 unrecognized elements, in the order in which they were encountered.
1689 If the containing binding was created from an XML document and enough
1690 information was present to determine the binding of the member
1691 element, the value is a binding instance. Otherwise, the value is the
1692 original DOM Element node.
1693 """
1694 return self.__wildcardElements
1695
1696 @classmethod
1704
1706 """Create a new instance of this binding.
1707
1708 Arguments are used as transition values along the content model.
1709 Keywords are passed to the constructor of any simple content, or used
1710 to initialize attribute and element values whose L{id
1711 <content.ElementUse.id>} (not L{name <content.ElementUse.name>})
1712 matches the keyword.
1713
1714 @keyword _dom_node: The node to use as the source of binding content.
1715 @type _dom_node: C{xml.dom.Element}
1716
1717 @keyword _from_xml: See L{_TypeBinding_mixin.Factory}
1718
1719 """
1720
1721 fallback_namespace = kw.pop('_fallback_namespace', None)
1722 is_nil = False
1723 dom_node = kw.pop('_dom_node', None)
1724 from_xml = kw.pop('_from_xml', dom_node is not None)
1725 if dom_node is not None:
1726 if isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
1727 self._setLocation(dom_node.location)
1728 if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
1729 dom_node = dom_node.documentElement
1730
1731 is_nil = XSI.nil.getAttribute(dom_node)
1732 if is_nil is not None:
1733 is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1734 if self._AttributeWildcard is not None:
1735 self.__wildcardAttributeMap = { }
1736 if self._HasWildcardElement:
1737 self.__wildcardElements = []
1738 if self._Abstract:
1739 raise pyxb.AbstractInstantiationError(type(self))
1740 super(complexTypeDefinition, self).__init__(**kw)
1741 self.reset()
1742 self._setAttributesFromKeywordsAndDOM(kw, dom_node)
1743 for fu in self._ElementMap.values():
1744 iv = kw.pop(fu.id(), None)
1745 if iv is not None:
1746 fu.set(self, iv)
1747 if kw and kw.pop('_strict_keywords', True):
1748 [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
1749 if kw:
1750 raise pyxb.ExtraContentError(kw)
1751 if dom_node is not None:
1752 if self._CT_SIMPLE == self._ContentTypeTag:
1753 self.__initializeSimpleContent(args, dom_node)
1754 else:
1755 self._setContentFromDOM(dom_node, fallback_namespace)
1756 elif 0 < len(args):
1757 self.extend(args, _from_xml=from_xml)
1758 else:
1759 if self._CT_SIMPLE == self._ContentTypeTag:
1760 self.__initializeSimpleContent(args, dom_node)
1761
1762 - def __initializeSimpleContent (self, args, dom_node=None):
1763
1764
1765
1766
1767 value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _nil=self._isNil(), *args)
1768 if value._constructedWithValue():
1769 if self._isNil():
1770 raise pyxb.ContentInNilElementError(value)
1771 else:
1772 self.append(value)
1773
1774
1775 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
1776 'xsdConstraintsOK', 'content', 'append', 'extend', 'value', 'reset' ]))
1777
1778
1779
1780 _ContentModel = None
1781
1782 @classmethod
1784 """Method used by generated code to associate the element binding with a use in this type.
1785
1786 This is necessary because all complex type classes appear in the
1787 module prior to any of the element instances (which reference type
1788 classes), so the association must be formed after the element
1789 instances are available."""
1790 return cls._UseForTag(element.name())._setElementBinding(element)
1791
1792 @classmethod
1794 """Return the ElementUse object corresponding to the element name.
1795
1796 @param tag: The L{ExpandedName} of an element in the class."""
1797 rv = cls._ElementMap.get(tag)
1798 if (rv is None) and raise_if_fail:
1799 raise pyxb.NotAnElementError(tag, cls)
1800 return rv
1801
1803 """Generate a list of children in the order in which they should be
1804 added to the parent when creating a DOM representation of this
1805 object.
1806
1807 @note: This is only used when L{pyxb.RequireValidWhenGenerating} has
1808 disabled validation. Consequently, it may not generate valid XML.
1809 """
1810 order = []
1811 for eu in self._ElementMap.values():
1812 value = eu.value(self)
1813 if value is None:
1814 continue
1815 if isinstance(value, list) and eu.isPlural():
1816 order.extend([ (eu, _v) for _v in value ])
1817 continue
1818 order.append( (eu, value) )
1819 return order
1820
1822 """Provide the child elements and non-element content in an order
1823 consistent with the content model.
1824
1825 Returns a sequence of tuples representing a valid path through the
1826 content model where each transition corresponds to one of the member
1827 element instances within this instance. The tuple is a pair
1828 comprising the L{content.ElementUse} instance and the value for the
1829 transition.
1830
1831 If the content of the instance does not validate against the content
1832 model, C{None} is returned.
1833
1834 The base class implementation uses the
1835 L{content.ParticleModel.validate} method. Subclasses may desire to
1836 override this in cases where the desired order is not maintained by
1837 model interpretation (for example, when an "all" model is used and the
1838 original element order is desired). See L{__childrenForDOM} as an
1839 example of an alternative approach.
1840
1841 @return: C{None} or a list as described above.
1842 """
1843 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1844 return []
1845
1846 if self._ContentModel is None:
1847 raise pyxb.NoContentModel(self)
1848 path = self._ContentModel.validate(self._symbolSet())
1849 if path is not None:
1850 ( symbols, sequence ) = path
1851 if 0 == len(symbols):
1852 return sequence
1853 raise pyxb.BindingValidationError('Ungenerated symbols: %s' % (symbols,) )
1854 return None
1855
1857 """Return a map from L{content.ElementUse} instances to a list of
1858 values associated with that use.
1859
1860 This is used as the set of symbols available for transitions when
1861 validating content against a model. Note that the order of values
1862 within a use is likely to be significant, although the model cannot
1863 detect this.
1864
1865 The value C{None} should be used to provide a list of wildcard
1866 members.
1867
1868 If an element use has no associated values, it must not appear in the
1869 returned map.
1870 """
1871 rv = { }
1872 for eu in self._ElementMap.values():
1873 value = eu.value(self)
1874 if value is None:
1875 continue
1876 res = None
1877 converter = eu.elementBinding().compatibleValue
1878 if eu.isPlural():
1879 if 0 < len(value):
1880 rv[eu] = [ converter(_v) for _v in value ]
1881 else:
1882 rv[eu] = [ converter(value)]
1883 wce = self.wildcardElements()
1884 if (wce is not None) and (0 < len(wce)):
1885 rv[None] = wce[:]
1886 return rv
1887
1891
1912
1922
1924 """Validate the content against the simple type.
1925
1926 @return: C{True} if the content validates against its type.
1927 @raise pyxb.NotSimpleContentError: this type does not have simple content.
1928 @raise pyxb.MissingContentError: the content of this type has not been set
1929 """
1930
1931 if self._CT_SIMPLE != self._ContentTypeTag:
1932 raise pyxb.NotSimpleContentError(self)
1933 if self._isNil():
1934 return True
1935 if self.value() is None:
1936 raise pyxb.MissingContentError(self)
1937 return self.value().xsdConstraintsOK()
1938
1939 __content = None
1940 - def content (self):
1941 """Return the content of the element.
1942
1943 This must be a complex type with complex content. The return value is
1944 a list of the element and non-element content in the order in which it
1945 was added.
1946 @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
1947 """
1948 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1949 raise pyxb.NotComplexContentError(str(self._ExpandedName))
1950 return self.__content
1951
1953 """Return the value of the element.
1954
1955 This must be a complex type with simple content. The returned value
1956 is expected to be an instance of some L{simpleTypeDefinition} class.
1957
1958 @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
1959 """
1960 if self._CT_SIMPLE != self._ContentTypeTag:
1961 raise pyxb.NotSimpleContentError('%s (%s)' % (str(self._ExpandedName), type(self)))
1962 return self.__content
1963
1964 - def _resetContent (self):
1965 if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
1966 self.__setContent([])
1967 else:
1968 self.__setContent(None)
1969
1970 __modelState = None
1987
1988 @classmethod
1990 """Determine what the given name means as an element in this type.
1991
1992 Normally, C{element_name} identifies an element definition within this
1993 type. If so, the returned C{element_use} identifies that definition,
1994 and the C{element_binding} is extracted from that use.
1995
1996 It may also be that the C{element_name} does not appear as an element
1997 definition, but that it identifies a global element. In that case,
1998 the returned C{element_binding} identifies the global element. If,
1999 further, that element is a member of a substitution group which does
2000 have an element definition in this class, then the returned
2001 C{element_use} identifies that definition.
2002
2003 If a non-C{None} C{element_use} is returned, there will be an
2004 associated C{element_binding}. However, it is possible to return a
2005 non-C{None} C{element_binding}, but C{None} as the C{element_use}. In
2006 that case, the C{element_binding} can be used to create a binding
2007 instance, but the content model will have to treat it as a wildcard.
2008
2009 @param element_name: The name of the element in this type, either an
2010 expanded name or a local name if the element has an absent namespace.
2011
2012 @return: C{( element_binding, element_use )}
2013 """
2014 element_use = cls._ElementMap.get(element_name)
2015 element_binding = None
2016 if element_use is None:
2017 try:
2018 element_binding = element_name.elementBinding()
2019 except pyxb.NamespaceError:
2020 pass
2021 if element_binding is not None:
2022 element_use = element_binding.findSubstituendUse(cls)
2023 else:
2024 element_binding = element_use.elementBinding()
2025 return (element_binding, element_use)
2026
2027 - def append (self, value, element_use=None, maybe_element=True, _fallback_namespace=None, require_validation=True, _from_xml=False):
2028 """Add the value to the instance.
2029
2030 The value should be a DOM node or other value that is or can be
2031 converted to a binding instance. If the instance has a DFA state, the
2032 value must be permitted by the content model.
2033
2034 @raise pyxb.ExtraContentError: the value is not permitted at the
2035 current state of the content model.
2036 """
2037
2038
2039
2040 element_binding = None
2041 if element_use is not None:
2042 import content
2043 assert isinstance(element_use, content.ElementUse)
2044 element_binding = element_use.elementBinding()
2045 assert element_binding is not None
2046
2047 if isinstance(value, xml.dom.Node):
2048 _from_xml = True
2049 assert maybe_element
2050 assert element_binding is None
2051 node = value
2052 require_validation = pyxb._ParsingRequiresValid
2053 if xml.dom.Node.COMMENT_NODE == node.nodeType:
2054
2055
2056 return self
2057 if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
2058 value = node.data
2059 maybe_element = False
2060 else:
2061
2062 assert xml.dom.Node.ELEMENT_NODE == node.nodeType
2063 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=_fallback_namespace)
2064 (element_binding, element_use) = self._ElementBindingUseForName(expanded_name)
2065 if element_binding is not None:
2066 value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=_fallback_namespace)
2067 else:
2068
2069
2070
2071 try:
2072 ns = expanded_name.namespace()
2073 if ns is not None:
2074 for mr in ns.moduleRecords():
2075 try:
2076 if (mr.module() is None) and (mr.modulePath() is not None):
2077 print 'Importing %s to get binding for wildcard %s' % (mr.modulePath(), expanded_name)
2078 mod = __import__(mr.modulePath())
2079 for c in mr.modulePath().split('.')[1:]:
2080 mod = getattr(mod, c)
2081 mr._setModule(mod)
2082 value = mr.module().CreateFromDOM(node)
2083 break
2084 except pyxb.PyXBException, e:
2085 print 'Ignoring error when creating binding for wildcard %s: %s' % (expanded_name, e)
2086 except AttributeError, e:
2087
2088
2089
2090
2091 if mr.namespace() != pyxb.namespace.XMLSchema:
2092 raise
2093 except Exception, e:
2094 print 'WARNING: Unable to convert DOM node %s to Python instance: %s' % (expanded_name, e)
2095 if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
2096 if (0 == len(value.strip())) and not self._isNil():
2097 return self
2098 if self._isNil() and not self._IsSimpleTypeContent():
2099 raise pyxb.ExtraContentError('%s: Content %s present in element with xsi:nil' % (type(self), value))
2100 if maybe_element and (self.__modelState is not None):
2101
2102 if not require_validation:
2103 if element_use is not None:
2104 element_use.setOrAppend(self, value)
2105 return self
2106 if self.wildcardElements() is not None:
2107 self._appendWildcardElement(value)
2108 return self
2109 raise pyxb.StructuralBadDocumentError('Validation is required when no element_use can be found')
2110 else:
2111
2112 ( consumed, underflow_exc ) = self.__modelState.step(self, value, element_use)
2113 if consumed:
2114 return self
2115
2116
2117
2118 if (element_binding is not None) or isinstance(value, xml.dom.Node):
2119 raise pyxb.ExtraContentError('%s: Extra content %s starting with %s' % (self._ExpandedName, element_binding, value,))
2120
2121
2122
2123 if self._IsSimpleTypeContent():
2124 if self.__content is not None:
2125 raise pyxb.ExtraContentError('Extra content starting with %s (already have %s)' % (value, self.__content))
2126 if not self._isNil():
2127 if not isinstance(value, self._TypeDefinition):
2128 value = self._TypeDefinition.Factory(value, _from_xml=_from_xml)
2129 self.__setContent(value)
2130 if require_validation:
2131
2132
2133
2134 self.xsdConstraintsOK()
2135 return self
2136
2137
2138 if not self._IsMixed():
2139 raise pyxb.UnexpectedNonElementContentError(value)
2140 if isinstance(value, _TypeBinding_mixin):
2141 raise pyxb.ExtraContentError('Extra content starting with %s' % (value,))
2142
2143 self._addContent(value, element_binding)
2144 return self
2145
2151
2152 - def extend (self, value_list, _fallback_namespace=None, _from_xml=False):
2153 """Invoke L{append} for each value in the list, in turn."""
2154 [ self.append(_v, _fallback_namespace=_fallback_namespace, _from_xml=_from_xml) for _v in value_list ]
2155 return self
2156
2157 - def __setContent (self, value):
2159
2160 - def _addContent (self, child, element_binding):
2161
2162
2163
2164 assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
2165 if isinstance(child, _TypeBinding_mixin) and (child._element() is None):
2166 child._setElement(element_binding)
2167 self.__content.append(child)
2168
2169 @classmethod
2172
2173 - def _postDOMValidate (self):
2174 if self._PerformValidation() and (not self._isNil()) and (self.__modelState is not None):
2175 self.__modelState.verifyComplete()
2176 self._validateAttributes()
2177 return self
2178
2179 - def _setContentFromDOM (self, node, _fallback_namespace):
2180 """Initialize the content of this element from the content of the DOM node."""
2181
2182 self.extend(node.childNodes[:], _fallback_namespace)
2183 return self._postDOMValidate()
2184
2192
2194 """Create a DOM element with the given tag holding the content of this instance."""
2195 element = parent
2196 self._setDOMFromAttributes(dom_support, element)
2197 if self._isNil():
2198 pass
2199 elif self._CT_EMPTY == self._ContentTypeTag:
2200 pass
2201 elif self._CT_SIMPLE == self._ContentTypeTag:
2202 assert self.value() is not None, '%s has no value' % (self,)
2203 element.appendChild(dom_support.document().createTextNode(self.value().xsdLiteral()))
2204 else:
2205 if pyxb._GenerationRequiresValid:
2206 order = self._validatedChildren()
2207 else:
2208 order = self.__childrenForDOM()
2209 if order is None:
2210 raise pyxb.DOMGenerationError('Binding value inconsistent with content model')
2211 for (eu, v) in order:
2212 assert v != self
2213 if eu is None:
2214 if isinstance(v, xml.dom.Node):
2215 dom_support.appendChild(v, element)
2216 else:
2217 v.toDOM(dom_support, parent)
2218 else:
2219 eu.toDOM(dom_support, parent, v)
2220 mixed_content = self.content()
2221 for mc in mixed_content:
2222 pass
2223 return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
2224
2225 @classmethod
2227 """CTDs with simple content are simple; other CTDs are not."""
2228 return cls._CT_SIMPLE == cls._ContentTypeTag
2229
2230 @classmethod
2231 - def _description (cls, name_only=False, user_documentation=True):
2257
2258 ConfigureBindingStyle(DEFAULT_BINDING_STYLE)
2259
2260
2261
2262
2263