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', '_apply_whitespace_facet', '_validate_constraints', '_require_value', '_nil', '_element', '_convert_string_values' )
67 """Keywords that are interpreted by __new__ or __init__ in one or more
68 classes in the PyXB type hierarchy. All these keywords must be removed
69 before invoking base Python __init__ or __new__."""
70
71
72
73
74 _Abstract = False
75
77 """Return a L{namespace context <pyxb.binding.NamespaceContext>}
78 associated with the binding instance.
79
80 This will return C{None} unless something has provided a context to
81 the instance. Context is provided when instances are generated by the
82 DOM and SAX-based translators."""
83 return self.__namespaceContext
84 - def _setNamespaceContext (self, namespace_context):
85 """Associate a L{namespace context <pyxb.binding.NamespaceContext>}
86 with the binding instance."""
87 self.__namespaceContext = namespace_context
88 return self
89 __namespaceContext = None
90
92 """Associate a L{pyxb.binding.basis.element} with the instance."""
93 self.__element = element
94 return self
96 """Return a L{pyxb.binding.basis.element} associated with the binding
97 instance.
98
99 This will return C{None} unless an element has been associated.
100 Constructing a binding instance using the element instance will add
101 this association.
102 """
103 return self.__element
104 __element = None
105
106 __xsiNil = None
108 """Indicate whether this instance is U{nil
109 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
110
111 The value is set by the DOM and SAX parsers when building an instance
112 from a DOM element with U{xsi:nil
113 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set to C{true}.
114
115 @return: C{None} if the element used to create the instance is not
116 U{nillable<http://www.w3.org/TR/xmlschema-1/#nillable>}.
117 If it is nillable, returns C{True} or C{False} depending on
118 whether the instance itself is U{nil<http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
119 """
120 return self.__xsiNil
122 """Set the xsi:nil property of the instance.
123
124 @raise pyxb.NoNillableSupportError: the instance is not associated
125 with an element that is L{nillable
126 <pyxb.binding.basis.element.nillable>}.
127 """
128 if self.__xsiNil is None:
129 raise pyxb.NoNillableSupportError(type(self))
130 self.__xsiNil = True
131 self._resetContent()
132
133 - def _resetContent (self):
135
136 __constructedWithValue = False
150
151
152
153
154 __WarnedUnassociatedElement = False
155
166
167 @classmethod
169 """Method invoked upon entry to the Factory method.
170
171 This method is entitled to modify the keywords array. It can also
172 return a state value which is passed to _postFactory_vx."""
173 return None
174
175 - def _postFactory_vx (cls, state):
176 """Method invoked prior to leaving the Factory method.
177
178 This is an instance method, and is given the state that was returned
179 by _PreFactory_vx."""
180 return None
181
182 @classmethod
184 """Provide a common mechanism to create new instances of this type.
185
186 The class constructor won't do, because you can't create
187 instances of union types.
188
189 This method may be overridden in subclasses (like STD_union). Pre-
190 and post-creation actions can be customized on a per-class instance by
191 overriding the L{_PreFactory_vx} and L{_postFactory_vx} methods.
192
193 @keyword _dom_node: If provided, the value must be a DOM node, the
194 content of which will be used to set the value of the instance.
195
196 @keyword _apply_whitespace_facet: If C{True} and this is a
197 simpleTypeDefinition with a whiteSpace facet, the first argument will
198 be normalized in accordance with that facet prior to invoking the
199 parent constructor.
200
201 @keyword _validate_constraints: If C{True}, any constructed value is
202 checked against constraints applied to the union as well as the member
203 type.
204
205 @keyword _require_value: If C{False} (default), it is permitted to
206 create a value without an initial value. If C{True} and no initial
207 value was provided, causes L{pyxb.MissingContentError} to be raised.
208 Only applies to simpleTypeDefinition instances; this is used when
209 creating values from DOM nodes.
210 """
211
212
213 dom_node = kw.get('_dom_node')
214 used_cls = cls._SupersedingClass()
215 state = used_cls._PreFactory_vx(args, kw)
216 rv = cls._DynamicCreate(*args, **kw)
217 rv._postFactory_vx(state)
218 if isinstance(dom_node, utility.Locatable_mixin):
219 rv._setLocation(dom_node.location)
220 return rv
221
226
227 @classmethod
230
231 @classmethod
233 """Return a variant of the value that is compatible with this type.
234
235 Compatibility is defined relative to the type definition associated
236 with the element. The value C{None} is always compatible. If
237 C{value} has a Python type (e.g., C{int}) that is a superclass of the
238 required L{_TypeBinding_mixin} class (e.g., C{xs:byte}), C{value} is
239 used as a constructor parameter to return a new instance of the
240 required type. Note that constraining facets are applied here if
241 necessary (e.g., although a Python C{int} with value C{500} is
242 type-compatible with C{xs:byte}, it is outside the value space, and
243 compatibility will fail.
244
245 @keyword _convert_string_values: If C{True} (default) and the incoming value is
246 a string, an attempt will be made to form a compatible value by using
247 the string as a constructor argument to the this class. This flag is
248 set to C{False} when testing automaton transitions.
249
250 @raise pyxb.BadTypeValueError: if the value is not both
251 type-consistent and value-consistent with the element's type.
252 """
253 convert_string_values = kw.get('_convert_string_values', True)
254
255 if value is None:
256 return None
257
258 if isinstance(value, cls):
259
260
261 return value
262 value_type = type(value)
263
264 if str == value_type:
265 value_type = unicode
266
267
268
269 if issubclass(cls, value_type):
270 return cls(value)
271
272
273
274 if isinstance(value, int) and issubclass(cls, long):
275 return cls(value)
276
277
278 if isinstance(value, bool) and issubclass(cls, pyxb.binding.datatypes.boolean):
279 return cls(value)
280
281
282
283 if convert_string_values and (unicode == value_type):
284 return cls(value)
285
286
287 if issubclass(cls, STD_union):
288 for mt in cls._MemberTypes:
289 try:
290 return mt._CompatibleValue(value, **kw)
291 except:
292 pass
293
294
295 if (pyxb.binding.datatypes.anySimpleType == cls) and issubclass(value_type, simpleTypeDefinition):
296 return value
297 if (pyxb.binding.datatypes.anyType == cls) and issubclass(value_type, complexTypeDefinition):
298 return value
299
300
301
302 if isinstance(value, pyxb.BIND):
303 return value.createInstance(cls.Factory, **kw)
304
305
306
307
308
309
310 raise pyxb.BadTypeValueError('No conversion from %s to %s' % (value_type, cls))
311
312 @classmethod
314 """Return True iff the content of this binding object is a simple type.
315
316 This is true only for descendents of simpleTypeDefinition and instances
317 of complexTypeDefinition that have simple type content."""
318 raise pyxb.LogicError('Failed to override _TypeBinding_mixin._IsSimpleTypeContent')
319
320 - def toDOM (self, bds=None, parent=None, element_name=None):
321 """Convert this instance to a DOM node.
322
323 The name of the top-level element is either the name of the L{element}
324 instance associated with this instance, or the XML name of the type of
325 this instance.
326
327 @param bds: Support for customizing the generated document
328 @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
329 @param parent: If C{None}, a standalone document is created;
330 otherwise, the created element is a child of the given element.
331 @type parent: C{xml.dom.Element} or C{None}
332 @rtype: C{xml.dom.Document}
333 """
334
335 if bds is None:
336 bds = domutils.BindingDOMSupport()
337 need_xsi_type = bds.requireXSIType()
338 if isinstance(element_name, (str, unicode)):
339 element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
340 if (element_name is None) and (self._element() is not None):
341 element_binding = self._element()
342 element_name = element_binding.name()
343 need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
344 if element_name is None:
345 element_name = self._ExpandedName
346 element = bds.createChildElement(element_name, parent)
347 if need_xsi_type:
348 val_type_qname = self._ExpandedName.localName()
349 tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
350 if tns_prefix is not None:
351 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
352 bds.addAttribute(element, XSI.type, val_type_qname)
353 self._toDOM_csc(bds, element)
354 bds.finalize()
355 return bds.document()
356
357 - def toxml (self, bds=None, root_only=False):
358 """Shorthand to get the object as an XML document.
359
360 If you want to set the default namespace, pass in a pre-configured
361 C{bds}.
362
363 @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
364 to use for creation. If not provided (default), a new generic one is
365 created.
366 """
367 dom = self.toDOM(bds)
368 if root_only:
369 dom = dom.documentElement
370 return dom.toxml()
371
377
379 """Override in subclasses for type-specific validation of instance
380 content.
381
382 @return: C{True} if the instance validates
383 @raise pyxb.BindingValidationError: complex content does not match model
384 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
385 """
386 raise pyxb.IncompleteImplementationError('%s did not override _validateBinding_vx' % (type(self),))
387
389 """Check whether the binding content matches its content model.
390
391 @return: C{True} if validation succeeds.
392 @raise pyxb.BindingValidationError: complex content does not match model
393 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
394 """
395 if self._PerformValidation():
396 self._validateBinding_vx()
397 return True
398
399 - def _postDOMValidate (self):
400 self.validateBinding()
401 return self
402
403 @classmethod
410
412 """Helper to allow overriding the implementation class.
413
414 Generally we'll want to augment the generated bindings by subclassing
415 them, and adding functionality to the subclass. This mix-in provides a
416 way to communicate the existence of the superseding subclass back to the
417 binding infrastructure, so that when it creates an instance it uses the
418 subclass rather than the unaugmented binding class.
419
420 When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
421 invoked on the raw class passing in the superseding subclass. E.g.::
422
423 class mywsdl (raw.wsdl):
424 pass
425 raw.wsdl._SetSupersedingClass(mywsdl)
426
427 """
428
429 @classmethod
431 return '_%s__SupersedingClass' % (cls.__name__,)
432
433 @classmethod
435 return '_%s__AlternativeConstructor' % (cls.__name__,)
436
437 @classmethod
441
442 @classmethod
444 """Return the class stored in the class reference attribute."""
445 rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
446 if isinstance(rv, tuple):
447 rv = rv[0]
448 return rv
449
450 @classmethod
452 """Set the class reference attribute.
453
454 @param superseding: A Python class that is a subclass of this class.
455 """
456 assert (superseding is None) or issubclass(superseding, cls)
457 if superseding is None:
458 cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
459 else:
460 setattr(cls, cls.__SupersedingClassAttribute(), superseding)
461 return superseding
462
463 @classmethod
465 attr = cls.__AlternativeConstructorAttribute()
466 if alternative_constructor is None:
467 cls.__dict__.pop(attr, None)
468 else:
469
470
471
472 setattr(cls, attr, (alternative_constructor,))
473 assert cls._AlternativeConstructor() == alternative_constructor
474 return alternative_constructor
475
476 @classmethod
486
487 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
488 """L{simpleTypeDefinition} is a base class that is part of the
489 hierarchy of any class that represents the Python datatype for a
490 L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
491
492 @note: This class, or a descendent of it, must be the first class
493 in the method resolution order when a subclass has multiple
494 parents. Otherwise, constructor keyword arguments may not be
495 removed before passing them on to Python classes that do not
496 accept them.
497 """
498
499
500
501
502 __FacetMap = {}
503
504 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
505 'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
506 'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
507 'PythonLiteral', 'pythonLiteral',
508 'SimpleTypeDefinition' ]))
509 """Symbols that remain the responsibility of this class. Any
510 public symbols in generated binding subclasses are deconflicted
511 by providing an alternative name in the subclass. (There
512 currently are no public symbols in generated SimpleTypeDefinion
513 bindings."""
514
515
516 @classmethod
524
525
526
527
528 __FacetMapAttributeNameMap = { }
529 @classmethod
531 """ """
532 '''
533 if cls == simpleTypeDefinition:
534 return '_%s__FacetMap' % (cls.__name__.strip('_'),)
535
536 # It is not uncommon for a class in one namespace to extend a class of
537 # the same name in a different namespace, so encode the namespace URI
538 # in the attribute name (if it is part of a namespace).
539 ns_uri = ''
540 try:
541 ns_uri = cls._ExpandedName.namespaceURI()
542 except Exception, e:
543 pass
544 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
545 '''
546 nm = cls.__FacetMapAttributeNameMap.get(cls)
547 if nm is None:
548 nm = cls.__name__
549 if nm.endswith('_'):
550 nm += '1'
551 if cls == simpleTypeDefinition:
552 nm = '_%s__FacetMap' % (nm,)
553 else:
554
555
556
557 ns_uri = ''
558 try:
559 ns_uri = cls._ExpandedName.namespaceURI()
560 except Exception, e:
561 pass
562 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
563 cls.__FacetMapAttributeNameMap[cls] = nm
564 return nm
565
566 @classmethod
568 """Return a reference to the facet map for this datatype.
569
570 The facet map is a map from leaf facet classes to instances of those
571 classes that constrain or otherwise apply to the lexical or value
572 space of the datatype. Classes may inherit their facet map from their
573 superclass, or may create a new class instance if the class adds a new
574 constraint type.
575
576 :raise AttributeError: if the facet map has not been defined"""
577 return getattr(cls, cls.__FacetMapAttributeName())
578
579 @classmethod
581 """Initialize the facet map for this datatype.
582
583 This must be called exactly once, after all facets belonging to the
584 datatype have been created.
585
586 :raise pyxb.LogicError: if called multiple times (on the same class)
587 :raise pyxb.LogicError: if called when a parent class facet map has not been initialized
588 :return: the facet map"""
589 fm = None
590 try:
591 fm = cls._FacetMap()
592 except AttributeError:
593 pass
594 if fm is not None:
595 raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
596
597
598
599
600
601 source_class = cls
602 while fm is None:
603
604
605 for super_class in source_class.mro():
606
607 assert super_class is not None
608 if (super_class == simpleTypeDefinition):
609 break
610 if issubclass(super_class, simpleTypeDefinition):
611 try:
612 fm = super_class._FacetMap()
613
614 break
615 except AttributeError:
616 pass
617 if fm is None:
618 try:
619 source_class = source_class.XsdSuperType()
620 except AttributeError:
621 source_class = None
622
623 if source_class is None:
624 fm = { }
625
626 if fm is None:
627 raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
628 fm = fm.copy()
629
630 for facet in args:
631 fm[type(facet)] = facet
632
633
634 setattr(cls, cls.__FacetMapAttributeName(), fm)
635 return fm
636
637 @classmethod
640
641 @classmethod
643 """Pre-process the arguments.
644
645 This is used before invoking the parent constructor. One application
646 is to apply the whitespace facet processing; if such a request is in
647 the keywords, it is removed so it does not propagate to the
648 superclass. Another application is to convert the arguments from a
649 string to a list. Binding-specific applications are performed in the
650 overloaded L{_ConvertArguments_vx} method."""
651 dom_node = kw.pop('_dom_node', None)
652 if dom_node is not None:
653 text_content = domutils.ExtractTextContent(dom_node)
654 if text_content is not None:
655 args = (domutils.ExtractTextContent(dom_node),) + args
656 kw['_apply_whitespace_facet'] = True
657 apply_whitespace_facet = kw.pop('_apply_whitespace_facet', True)
658 if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
659 cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
660 if cf_whitespace is not None:
661
662 norm_str = unicode(cf_whitespace.normalizeString(args[0]))
663 args = (norm_str,) + args[1:]
664 return cls._ConvertArguments_vx(args, kw)
665
666
667
668
669
670
671
672
673
674
675
677
678 kw.pop('_validate_constraints', None)
679 kw.pop('_require_value', None)
680 kw.pop('_element', None)
681 kw.pop('_fallback_namespace', None)
682 kw.pop('_nil', None)
683
684 args = cls._ConvertArguments(args, kw)
685 assert issubclass(cls, _TypeBinding_mixin)
686 try:
687 rv = super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
688 return rv
689 except ValueError, e:
690 raise pyxb.BadTypeValueError(e)
691 except OverflowError, e:
692 raise pyxb.BadTypeValueError(e)
693
694
695
697 """Initialize a newly created STD instance.
698
699 Usually there is one positional argument, which is a value that can be
700 converted to the underlying Python type.
701
702 @keyword _validate_constraints: If True (default), the newly
703 constructed value is checked against its constraining facets.
704 @type _validate_constraints: C{bool}
705 """
706
707 validate_constraints = kw.pop('_validate_constraints', self._PerformValidation())
708 require_value = kw.pop('_require_value', False)
709
710
711 args = self._ConvertArguments(args, kw)
712 try:
713 super(simpleTypeDefinition, self).__init__(*args, **kw)
714 except OverflowError, e:
715 raise pyxb.BadTypeValueError(e)
716 if require_value and (not self._constructedWithValue()):
717 raise pyxb.MissingContentError('missing value')
718
719 if validate_constraints:
720 self.xsdConstraintsOK()
721
722
723
724
725
726
727
728 @classmethod
730 return '_%s__SimpleTypeDefinition' % (cls.__name__,)
731
732 @classmethod
734 """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
735 associated with this binding."""
736 attr_name = cls.__STDAttrName()
737 if hasattr(cls, attr_name):
738 old_value = getattr(cls, attr_name)
739 if old_value != std:
740 raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
741 setattr(cls, attr_name, std)
742
743 @classmethod
745 """Return the SimpleTypeDefinition instance for the given
746 class.
747
748 This should only be invoked when generating bindings.
749
750 @raise pyxb.IncompleteImplementationError: no STD instance has been
751 associated with the class.
752
753 """
754 attr_name = cls.__STDAttrName()
755 if hasattr(cls, attr_name):
756 return getattr(cls, attr_name)
757 raise pyxb.IncompleteImplementationError('%s: No STD available' % (cls,))
758
759 @classmethod
761 """Convert from a python value to a string usable in an XML
762 document.
763
764 This should be implemented in the subclass."""
765 raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
766
768 """Return text suitable for representing the value of this
769 instance in an XML document.
770
771 The base class implementation delegates to the object class's
772 XsdLiteral method."""
773 if self._isNil():
774 return ''
775 return self.XsdLiteral(self)
776
777 @classmethod
779 """Find the nearest parent class in the PST hierarchy.
780
781 The value for anySimpleType is None; for all others, it's a
782 primitive or derived PST descendent (including anySimpleType)."""
783 for sc in cls.mro():
784 if sc == cls:
785 continue
786 if simpleTypeDefinition == sc:
787
788
789
790 return cls._XsdBaseType
791 if issubclass(sc, simpleTypeDefinition):
792 return sc
793 raise pyxb.LogicError('No supertype found for %s' % (cls,))
794
795 @classmethod
797 """Pre-extended class method to verify other things before
798 checking constraints.
799
800 This is used for list types, to verify that the values in the
801 list are acceptable, and for token descendents, to check the
802 lexical/value space conformance of the input.
803 """
804 super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
805 return super_fn(value)
806
807
808
809 __ClassFacetSequence = { }
810
811 @classmethod
813 """Validate the given value against the constraints on this class.
814
815 @raise pyxb.BadTypeValueError: if any constraint is violated.
816 """
817
818 value = cls._XsdConstraintsPreCheck_vb(value)
819
820 facet_values = cls.__ClassFacetSequence.get(cls)
821 if facet_values is None:
822
823
824 classes = [ _x for _x in cls.mro() if issubclass(_x, simpleTypeDefinition) ]
825 classes.reverse()
826 cache_result = True
827 facet_values = []
828 for clazz in classes:
829
830
831
832
833
834
835 try:
836 clazz_facets = clazz._FacetMap().values()
837 except AttributeError, e:
838 cache_result = False
839 clazz_facets = []
840 for v in clazz_facets:
841 if not (v in facet_values):
842 facet_values.append(v)
843 if cache_result:
844 cls.__ClassFacetSequence[cls] = facet_values
845 for f in facet_values:
846 if not f.validateConstraint(value):
847 raise pyxb.BadTypeValueError('%s violation for %s in %s' % (f.Name(), value, cls.__name__))
848
849 return value
850
852 """Validate the value of this instance against its constraints."""
853 return self.XsdConstraintsOK(self)
854
859
860 @classmethod
862 """Return the length of the given value.
863
864 The length is calculated by a subclass implementation of
865 _XsdValueLength_vx in accordance with
866 http://www.w3.org/TR/xmlschema-2/#rf-length.
867
868 The return value is a non-negative integer, or C{None} if length
869 constraints should be considered trivially satisfied (as with
870 QName and NOTATION).
871
872 :raise pyxb.LogicError: the provided value is not an instance of cls.
873 :raise pyxb.LogicError: an attempt is made to calculate a length for
874 an instance of a type that does not support length calculations.
875 """
876 assert isinstance(value, cls)
877 if not hasattr(cls, '_XsdValueLength_vx'):
878 raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
879 return cls._XsdValueLength_vx(value)
880
882 """Return the length of this instance within its value space.
883
884 See XsdValueLength."""
885 return self.XsdValueLength(self)
886
887 @classmethod
889 """Return a string which can be embedded into Python source to
890 represent the given value as an instance of this class."""
891 class_name = cls.__name__
892 return '%s(%s)' % (class_name, repr(value))
893
895 """Return a string which can be embedded into Python source to
896 represent the value of this instance."""
897 return self.PythonLiteral(self)
898
903
904 @classmethod
906 """STDs have simple type content."""
907 return True
908
909 @classmethod
917
918 @classmethod
920
921 """NB: Invoking this on a value that is a list will, if necessary,
922 replace the members of the list with new values that are of the
923 correct item type. This is permitted because only with lists is it
924 possible to bypass the normal content validation (by invoking
925 append/extend on the list instance)."""
926 if value is None:
927 raise pyxb.BadTypeValueError('None is not a valid instance of %s' % (cls,))
928
929 value_class = cls
930 if issubclass(cls, STD_list):
931
932 try:
933 iter(value)
934 except TypeError, e:
935 raise pyxb.BadTypeValueError('%s cannot have non-iterable value type %s' % (cls, type(value)))
936 for v in value:
937 if not cls._ItemType._IsValidValue(v):
938 raise pyxb.BadTypeValueError('%s cannot have member of type %s (want %s)' % (cls, type(v), cls._ItemType))
939 else:
940 if issubclass(cls, STD_union):
941
942 value_class = None
943 for mt in cls._MemberTypes:
944 if mt._IsValidValue(value):
945 value_class = mt
946 break
947 if value_class is None:
948 raise pyxb.BadTypeValueError('%s cannot have value type %s' % (cls, type(value)))
949
950 if not isinstance(value, value_class):
951 raise pyxb.BadTypeValueError('Value type %s is not valid for %s' % (type(value), cls))
952 value_class.XsdConstraintsOK(value)
953
956
959
960 @classmethod
961 - def _description (cls, name_only=False, user_documentation=True):
962 name = cls._Name()
963 if name_only:
964 return name
965 desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
966 if user_documentation and (cls._Documentation is not None):
967 desc.extend(["\n", cls._Documentation])
968 return ''.join(desc)
969
971 """Base class for union datatypes.
972
973 This class descends only from simpleTypeDefinition. A pyxb.LogicError is
974 raised if an attempt is made to construct an instance of a subclass of
975 STD_union. Values consistent with the member types are constructed using
976 the Factory class method. Values are validated using the _ValidatedMember
977 class method.
978
979 Subclasses must provide a class variable _MemberTypes which is a
980 tuple of legal members of the union."""
981
982 _MemberTypes = None
983 """A list of classes which are permitted as values of the union."""
984
985
986
987
988 __FacetMap = {}
989
990 @classmethod
992 """Given a value, attempt to create an instance of some member of this
993 union. The first instance which can be legally created is returned.
994
995 @keyword _validate_constraints: If True (default), any constructed
996 value is checked against constraints applied to the union as well as
997 the member type.
998
999 @raise pyxb.BadTypeValueError: no member type will permit creation of
1000 an instance from the parameters in C{args} and C{kw}.
1001 """
1002
1003 used_cls = cls._SupersedingClass()
1004 state = used_cls._PreFactory_vx(args, kw)
1005
1006 rv = None
1007
1008 validate_constraints = kw.get('_validate_constraints', cls._PerformValidation())
1009 assert isinstance(validate_constraints, bool)
1010 if 0 < len(args):
1011 arg = args[0]
1012 try:
1013 rv = cls._ValidatedMember(arg)
1014 except pyxb.BadTypeValueError, e:
1015 pass
1016 if rv is None:
1017 kw['_validate_constraints'] = True
1018 for mt in cls._MemberTypes:
1019 try:
1020 rv = mt.Factory(*args, **kw)
1021 break
1022 except pyxb.BadTypeValueError:
1023 pass
1024 except ValueError:
1025 pass
1026 except:
1027 pass
1028 if rv is not None:
1029 if validate_constraints:
1030 cls.XsdConstraintsOK(rv)
1031 rv._postFactory_vx(state)
1032 return rv
1033 raise pyxb.BadTypeValueError('%s cannot construct union member from args %s' % (cls.__name__, args))
1034
1035 @classmethod
1037 """Validate the given value as a potential union member.
1038
1039 @raise pyxb.BadTypeValueError: the value is not an instance of a
1040 member type."""
1041 if not isinstance(value, cls._MemberTypes):
1042 for mt in cls._MemberTypes:
1043 try:
1044
1045
1046 value = mt.Factory(value, _validate_constraints=True)
1047 return value
1048 except (TypeError, pyxb.BadTypeValueError):
1049 pass
1050 raise pyxb.BadTypeValueError('%s cannot hold a member of type %s' % (cls.__name__, value.__class__.__name__))
1051 return value
1052
1054 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1055
1056 @classmethod
1057 - def _description (cls, name_only=False, user_documentation=True):
1064
1065 @classmethod
1069
1070
1071 -class STD_list (simpleTypeDefinition, types.ListType):
1072 """Base class for collection datatypes.
1073
1074 This class descends from the Python list type, and incorporates
1075 simpleTypeDefinition. Subclasses must define a class variable _ItemType
1076 which is a reference to the class of which members must be instances."""
1077
1078 _ItemType = None
1079 """A reference to the binding class for items within this list."""
1080
1081
1082
1083 __FacetMap = {}
1084
1085 @classmethod
1103
1104 @classmethod
1106
1107
1108 if 0 < len(args):
1109 arg1 = args[0]
1110 if isinstance(arg1, types.StringTypes):
1111 args = (arg1.split(),) + args[1:]
1112 arg1 = args[0]
1113 is_iterable = False
1114 try:
1115 iter(arg1)
1116 is_iterable = True
1117 except TypeError:
1118 pass
1119 if is_iterable:
1120 new_arg1 = []
1121 for i in range(len(arg1)):
1122 new_arg1.append(cls._ValidatedItem(arg1[i]))
1123 args = (new_arg1,) + args[1:]
1124 super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
1125 return super_fn(args, kw)
1126
1127 @classmethod
1130
1131 @classmethod
1133 """Convert from a binding value to a string usable in an XML document."""
1134 return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
1135
1136 @classmethod
1137 - def _description (cls, name_only=False, user_documentation=True):
1143
1144
1145 @classmethod
1148
1149
1152
1158
1161
1164
1165
1166
1169
1172
1175
1176 - def index (self, x, *args):
1178
1181
1184
1185 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1186 """Class that represents a schema element.
1187
1188 Global and local elements are represented by instances of this class.
1189 """
1190
1192 """The expanded name of the element within its scope."""
1193 return self.__name
1194 __name = None
1195
1199 __typeDefinition = None
1200
1202 """The scope of the element. This is either C{None}, representing a
1203 top-level element, or an instance of C{complexTypeDefinition} for
1204 local elements."""
1205 return self.__scope
1206 __scope = None
1207
1209 """Indicate whether values matching this element can have U{nil
1210 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
1211 return self.__nillable
1212 __nillable = False
1213
1215 """Indicate whether this element is abstract (must use substitution
1216 group members for matches)."""
1217 return self.__abstract
1218 __abstract = False
1219
1221 """Contents of any documentation annotation in the definition."""
1222 return self.__documentation
1223 __documentation = None
1224
1227 __defaultValue = None
1228
1230 """The L{element} instance to whose substitution group this element
1231 belongs. C{None} if this element is not part of a substitution
1232 group."""
1233 return self.__substitutionGroup
1239 __substitutionGroup = None
1240
1248
1250 """Determine whether an instance of this element can substitute for the other element.
1251
1252 See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>)}.
1253
1254 @todo: Do something about blocking constraints. This ignores them, as
1255 does everything leading to this point.
1256 """
1257 if self.substitutionGroup() is None:
1258 return False
1259 if other is None:
1260 return False
1261 assert isinstance(other, element)
1262
1263
1264 if other.scope() is not None:
1265 other = other.name().elementBinding()
1266 if other is None:
1267 return False
1268 assert other.scope() is None
1269
1270 if self.name().elementBinding() == other:
1271 return True
1272 return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
1273
1275 """Stub replaced by _real_substitutesFor when element supports substitution groups."""
1276 return False
1277
1279 """Return a reference to the element instance used for the given name
1280 within this element.
1281
1282 The type for this element must be a complex type definition."""
1283 return self.typeDefinition()._UseForTag(name).elementBinding()
1284
1285 - def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, default_value=None, substitution_group=None, documentation=None):
1297
1299 """Invoke the Factory method on the type associated with this element.
1300
1301 @keyword _dom_node: If set, specifies a DOM node that should be used
1302 for initialization. In that case, the L{createFromDOM} method is
1303 invoked instead of the type definition Factory method.
1304
1305 @raise pyxb.AbstractElementError: This element is abstract and no DOM
1306 node was provided.
1307 """
1308 dom_node = kw.pop('_dom_node', None)
1309 assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
1310 if '_element' in kw:
1311 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1312 kw['_element'] = self
1313
1314 if self.abstract():
1315 raise pyxb.AbstractElementError(self)
1316 return self.typeDefinition().Factory(*args, **kw)
1317
1340
1341
1342 @classmethod
1354
1356 """Return the element that should be used if this element binding is
1357 permitted and an element with the given name is encountered.
1358
1359 Normally, the incoming name matches the name of this binding, and
1360 C{self} is returned. If the incoming name is different, it is
1361 expected to be the name of a global element which is within this
1362 element's substitution group. In that case, the binding corresponding
1363 to the named element is return.
1364
1365 @return: An instance of L{element}, or C{None} if no element with the
1366 given name can be found.
1367 """
1368
1369
1370 if self.name() == name:
1371 return self
1372
1373
1374 top_elt = self.name().elementBinding()
1375 if top_elt is None:
1376 return None
1377
1378
1379
1380
1381 elt_en = top_elt.name().adoptName(name)
1382 assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
1383 named_elt = elt_en.elementBinding()
1384 if (named_elt is None) or (named_elt == top_elt):
1385 return None
1386 if named_elt.substitutesFor(top_elt):
1387 return named_elt
1388 return None
1389
1390 - def createFromDOM (self, node, expanded_name=None, fallback_namespace=None, **kw):
1391 """Create a binding instance from the given DOM node.
1392
1393 @keyword expanded_name: Optional name for the DOM node. If not
1394 present, is inferred from C{node}.
1395
1396 @keyword fallback_namespace: Optional namespace to use when resolving
1397 unqualified names.
1398 """
1399 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1400 node = node.documentElement
1401 if expanded_name is None:
1402 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1403 return self._createFromDOM(node, expanded_name, **kw)
1404
1406 """Create a binding instance from the given DOM node, using the
1407 provided name to identify the correct binding.
1408
1409 The context and information associated with this element is used to
1410 identify the actual element binding to use. By default, C{self} is
1411 used. If this element represents a term in a content model, the name
1412 and namespace of the incoming node may identify a different element.
1413 If that element is a member of this element's substitution group, the
1414 binding associated with the node's name will be used instead.
1415
1416 The type of object returned is determined by the type definition
1417 associated with the element binding and the value of any U{xsi:type
1418 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in the
1419 node, modulated by the configuration of L{XSI.ProcessTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance.ProcessTypeAttribute>}.
1420
1421 Keyword parameters are passed to the factory method of the type
1422 associated with the selected element binding. See
1423 L{_TypeBinding_mixin} and any specializations of it.
1424
1425 @param expanded_name: The expanded name of the node. If the value is
1426 C{None}, defaults to the name of this element. (In the case of
1427 substitution groups, the default is wrong, but correct inference
1428 depends on context not available here.)
1429
1430 @keyword _fallback_namespace: Optional namespace to use when resolving
1431 unqualified type names.
1432
1433 @param node: The DOM node specifying the element content. If this is
1434 a (top-level) Document node, its element node is used.
1435 @type node: C{xml.dom.Node}
1436 @return: An instance of L{_TypeBinding_mixin}
1437 @raise pyxb.StructuralBadDocumentError: The node's name does identify an element binding.
1438 @raise pyxb.AbstractElementError: The element binding associated with the node is abstract.
1439 @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
1440 @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.
1441 """
1442
1443
1444
1445 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1446 node = node.documentElement
1447
1448
1449
1450
1451
1452 fallback_namespace = kw.pop('_fallback_namespace', None)
1453 element_binding = self.elementForName(expanded_name)
1454 if element_binding is None:
1455 raise pyxb.StructuralBadDocumentError('Element %s cannot create from node %s' % (self.name(), expanded_name))
1456
1457
1458
1459
1460 if element_binding.abstract():
1461 raise pyxb.AbstractElementError(element_binding)
1462
1463
1464
1465 if '_element' in kw:
1466 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1467 kw['_element'] = element_binding
1468
1469
1470
1471 type_class = element_binding.typeDefinition()
1472 elt_ns = element_binding.name().namespace()
1473
1474
1475
1476
1477
1478 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
1479 (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
1480
1481
1482
1483
1484 is_nil = XSI.nil.getAttribute(node)
1485 if is_nil is not None:
1486 kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1487
1488 rv = type_class.Factory(_dom_node=node, _fallback_namespace=fallback_namespace, **kw)
1489 assert rv._element() == element_binding
1490 rv._setNamespaceContext(ns_ctx)
1491 return rv._postDOMValidate()
1492
1494 return 'Element %s' % (self.name(),)
1495
1496 - def _description (self, name_only=False, user_documentation=True):
1510
1512 """Marker in case we need to know that a PST has an enumeration constraint facet."""
1513 pass
1514
1515 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1516 """Base for any Python class that serves as the binding for an
1517 XMLSchema complexType.
1518
1519 Subclasses should define a class-level _AttributeMap variable which maps
1520 from the unicode tag of an attribute to the AttributeUse instance that
1521 defines it. Similarly, subclasses should define an _ElementMap variable.
1522 """
1523
1524 _CT_EMPTY = 'EMPTY'
1525 _CT_SIMPLE = 'SIMPLE'
1526 _CT_MIXED = 'MIXED'
1527 _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1528
1529 _ContentTypeTag = None
1530
1531 _TypeDefinition = None
1532 """Subclass of simpleTypeDefinition that corresponds to the type content.
1533 Only valid if _ContentTypeTag is _CT_SIMPLE"""
1534
1535
1536
1537
1538 _AttributeWildcard = None
1539
1540 _AttributeMap = { }
1541 """Map from expanded names to AttributeUse instances."""
1542
1543
1544
1545 _HasWildcardElement = False
1546
1547
1548 _ElementMap = { }
1549 """Map from expanded names to ElementUse instances."""
1550
1551
1552
1553 __wildcardAttributeMap = None
1554
1556 """Obtain access to wildcard attributes.
1557
1558 The return value is C{None} if this type does not support wildcard
1559 attributes. If wildcard attributes are allowed, the return value is a
1560 map from QNames to the unicode string value of the corresponding
1561 attribute.
1562
1563 @todo: The map keys should be namespace extended names rather than
1564 QNames, as the in-scope namespace may not be readily available to the
1565 user.
1566 """
1567 return self.__wildcardAttributeMap
1568
1569
1570
1571 __wildcardElements = None
1572
1574 """Obtain access to wildcard elements.
1575
1576 The return value is C{None} if the content model for this type does not
1577 support wildcard elements. If wildcard elements are allowed, the
1578 return value is a list of values corresponding to conformant
1579 unrecognized elements, in the order in which they were encountered.
1580 If the containing binding was created from an XML document and enough
1581 information was present to determine the binding of the member
1582 element, the value is a binding instance. Otherwise, the value is the
1583 original DOM Element node.
1584 """
1585 return self.__wildcardElements
1586
1587 @classmethod
1595
1597 """Create a new instance of this binding.
1598
1599 Arguments are used as transition values along the content model.
1600 Keywords are passed to the constructor of any simple content, or used
1601 to initialize attribute and element values whose L{id
1602 <content.ElementUse.id>} (not L{name <content.ElementUse.name>})
1603 matches the keyword.
1604
1605 @keyword _dom_node: The node to use as the source of binding content.
1606 @type _dom_node: C{xml.dom.Element}
1607
1608 """
1609
1610 fallback_namespace = kw.pop('_fallback_namespace', None)
1611 is_nil = False
1612 dom_node = kw.pop('_dom_node', None)
1613 if dom_node is not None:
1614 if isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
1615 self._setLocation(dom_node.location)
1616 if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
1617 dom_node = dom_node.documentElement
1618
1619 is_nil = XSI.nil.getAttribute(dom_node)
1620 if is_nil is not None:
1621 is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1622 if self._AttributeWildcard is not None:
1623 self.__wildcardAttributeMap = { }
1624 if self._HasWildcardElement:
1625 self.__wildcardElements = []
1626 if self._Abstract:
1627 raise pyxb.AbstractInstantiationError(type(self))
1628 super(complexTypeDefinition, self).__init__(**kw)
1629 self.reset()
1630
1631 attribute_settings = { }
1632 if dom_node is not None:
1633 attribute_settings.update(self.__AttributesFromDOM(dom_node))
1634 for fu in self._AttributeMap.values():
1635 iv = kw.pop(fu.id(), None)
1636 if iv is not None:
1637 attribute_settings[fu.name()] = iv
1638 for (attr_en, value) in attribute_settings.items():
1639 au = self._setAttribute(attr_en, value)
1640 for fu in self._ElementMap.values():
1641 iv = kw.pop(fu.id(), None)
1642 if iv is not None:
1643 fu.set(self, iv)
1644 if kw and kw.pop('_strict_keywords', True):
1645 [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
1646 if kw:
1647 raise pyxb.ExtraContentError(kw)
1648 if dom_node is not None:
1649 if self._CT_SIMPLE == self._ContentTypeTag:
1650 self.__initializeSimpleContent(args, dom_node)
1651 else:
1652 self._setContentFromDOM(dom_node, fallback_namespace)
1653 elif 0 < len(args):
1654 self.extend(args)
1655 else:
1656 if self._CT_SIMPLE == self._ContentTypeTag:
1657 self.__initializeSimpleContent(args, dom_node)
1658
1659 - def __initializeSimpleContent (self, args, dom_node=None):
1660
1661
1662
1663
1664 value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _nil=self._isNil(), *args)
1665 if value._constructedWithValue():
1666 if self._isNil():
1667 raise pyxb.ContentInNilElementError(value)
1668 else:
1669 self.append(value)
1670
1671
1672 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
1673 'xsdConstraintsOK', 'content', 'append', 'extend', 'value', 'reset' ]))
1674
1675
1676
1677 _ContentModel = None
1678
1679 @classmethod
1681 """Method used by generated code to associate the element binding with a use in this type.
1682
1683 This is necessary because all complex type classes appear in the
1684 module prior to any of the element instances (which reference type
1685 classes), so the association must be formed after the element
1686 instances are available."""
1687 return cls._UseForTag(element.name())._setElementBinding(element)
1688
1689 @classmethod
1691 """Return the ElementUse object corresponding to the element name.
1692
1693 @param tag: The L{ExpandedName} of an element in the class."""
1694 rv = cls._ElementMap.get(tag)
1695 if (rv is None) and raise_if_fail:
1696 raise pyxb.NotAnElementError(tag, cls)
1697 return rv
1698
1700 """Generate a list of children in the order in which they should be
1701 added to the parent when creating a DOM representation of this
1702 object.
1703
1704 @note: This is not currently used; it is retained as an example of one
1705 way to override L{_validatedChildren} in cases where content model
1706 validation is not required.
1707 """
1708 order = []
1709 for eu in self._ElementMap.values():
1710 value = eu.value(self)
1711 if value is None:
1712 continue
1713 if isinstance(value, list):
1714 order.extend([ (eu, _v) for _v in value ])
1715 continue
1716 order.append( (eu, value) )
1717 return order
1718
1720 """Provide the child elements and non-element content in an order
1721 consistent with the content model.
1722
1723 Returns a sequence of tuples representing a valid path through the
1724 content model where each transition corresponds to one of the member
1725 element instances within this instance. The tuple is a pair
1726 comprising the L{content.ElementUse} instance and the value for the
1727 transition.
1728
1729 If the content of the instance does not validate against the content
1730 model, C{None} is returned.
1731
1732 The base class implementation uses the
1733 L{content.ParticleModel.validate} method. Subclasses may desire to
1734 override this in cases where the desired order is not maintained by
1735 model interpretation (for example, when an "all" model is used and the
1736 original element order is desired). See L{__childrenForDOM} as an
1737 example of an alternative approach.
1738
1739 @return: C{None} or a list as described above.
1740 """
1741 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1742 return []
1743
1744 if self._ContentModel is None:
1745 raise pyxb.NoContentModel(self)
1746 path = self._ContentModel.validate(self._symbolSet())
1747 if path is not None:
1748 ( symbols, sequence ) = path
1749 if 0 == len(symbols):
1750 return sequence
1751 raise pyxb.BindingValidationError('Ungenerated symbols: %s' % (symbols,) )
1752 return None
1753
1755 """Return a map from L{content.ElementUse} instances to a list of
1756 values associated with that use.
1757
1758 This is used as the set of symbols available for transitions when
1759 validating content against a model. Note that the order of values
1760 within a use is likely to be significant, although the model cannot
1761 detect this.
1762
1763 The value C{None} should be used to provide a list of wildcard
1764 members.
1765
1766 If an element use has no associated values, it must not appear in the
1767 returned map.
1768 """
1769 rv = { }
1770 for eu in self._ElementMap.values():
1771 value = eu.value(self)
1772 if value is None:
1773 continue
1774 res = None
1775 converter = eu.elementBinding().compatibleValue
1776 if eu.isPlural():
1777 if 0 < len(value):
1778 rv[eu] = [ converter(_v) for _v in value ]
1779 else:
1780 rv[eu] = [ converter(value)]
1781 wce = self.wildcardElements()
1782 if (wce is not None) and (0 < len(wce)):
1783 rv[None] = wce[:]
1784 return rv
1785
1789
1810
1811 @classmethod
1831
1841
1843 """Initialize the attributes of this element from those of the DOM node.
1844
1845 @raise pyxb.UnrecognizedAttributeError: if the DOM node has attributes
1846 that are not allowed in this type
1847 @raise pyxb.ProhibitedAttributeError: a prohibited attribute was encountered
1848 @raise pyxb.MissingAttributeError: a required attribute could not be found
1849 """
1850
1851
1852 attrs_available = set(self._AttributeMap.values())
1853 for (attr_en, value) in attribute_settings.items():
1854 au = self._setAttribute(attr_en, value)
1855 if au is not None:
1856 attrs_available.remove(au)
1857
1858 return self
1859
1861 """Validate the content against the simple type.
1862
1863 @return: C{True} if the content validates against its type.
1864 @raise pyxb.NotSimpleContentError: this type does not have simple content.
1865 @raise pyxb.MissingContentError: the content of this type has not been set
1866 """
1867
1868 if self._CT_SIMPLE != self._ContentTypeTag:
1869 raise pyxb.NotSimpleContentError(self)
1870 if self._isNil():
1871 return True
1872 if self.value() is None:
1873 raise pyxb.MissingContentError(self)
1874 return self.value().xsdConstraintsOK()
1875
1876 __content = None
1877 - def content (self):
1878 """Return the content of the element.
1879
1880 This must be a complex type with complex content. The return value is
1881 a list of the element and non-element content in the order in which it
1882 was added.
1883 @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
1884 """
1885 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1886 raise pyxb.NotComplexContentError(str(self._ExpandedName))
1887 return self.__content
1888
1890 """Return the value of the element.
1891
1892 This must be a complex type with simple content. The returned value
1893 is expected to be an instance of some L{simpleTypeDefinition} class.
1894
1895 @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
1896 """
1897 if self._CT_SIMPLE != self._ContentTypeTag:
1898 raise pyxb.NotSimpleContentError('%s (%s)' % (str(self._ExpandedName), type(self)))
1899 return self.__content
1900
1901 - def _resetContent (self):
1902 if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
1903 self.__setContent([])
1904 else:
1905 self.__setContent(None)
1906
1907 __modelState = None
1924
1925 @classmethod
1927 """Determine what the given name means as an element in this type.
1928
1929 Normally, C{element_name} identifies an element definition within this
1930 type. If so, the returned C{element_use} identifies that definition,
1931 and the C{element_binding} is extracted from that use.
1932
1933 It may also be that the C{element_name} does not appear as an element
1934 definition, but that it identifies a global element. In that case,
1935 the returned C{element_binding} identifies the global element. If,
1936 further, that element is a member of a substitution group which does
1937 have an element definition in this class, then the returned
1938 C{element_use} identifies that definition.
1939
1940 If a non-C{None} C{element_use} is returned, there will be an
1941 associated C{element_binding}. However, it is possible to return a
1942 non-C{None} C{element_binding}, but C{None} as the C{element_use}. In
1943 that case, the C{element_binding} can be used to create a binding
1944 instance, but the content model will have to treat it as a wildcard.
1945
1946 @param element_name: The name of the element in this type, either an
1947 expanded name or a local name if the element has an absent namespace.
1948
1949 @return: C{( element_binding, element_use )}
1950 """
1951 element_use = cls._ElementMap.get(element_name)
1952 element_binding = None
1953 if element_use is None:
1954 try:
1955 element_binding = element_name.elementBinding()
1956 except pyxb.NamespaceError:
1957 pass
1958 if element_binding is not None:
1959 element_use = element_binding.findSubstituendUse(cls)
1960 else:
1961 element_binding = element_use.elementBinding()
1962 return (element_binding, element_use)
1963
1964 - def append (self, value, element_use=None, maybe_element=True, _fallback_namespace=None, require_validation=True):
1965 """Add the value to the instance.
1966
1967 The value should be a DOM node or other value that is or can be
1968 converted to a binding instance. If the instance has a DFA state, the
1969 value must be permitted by the content model.
1970
1971 @raise pyxb.ExtraContentError: the value is not permitted at the
1972 current state of the content model.
1973 """
1974
1975
1976
1977 element_binding = None
1978 if element_use is not None:
1979 import content
1980 assert isinstance(element_use, content.ElementUse)
1981 element_binding = element_use.elementBinding()
1982 assert element_binding is not None
1983
1984 if isinstance(value, xml.dom.Node):
1985 assert maybe_element
1986 assert element_binding is None
1987 node = value
1988 require_validation = pyxb._ParsingRequiresValid
1989 if xml.dom.Node.COMMENT_NODE == node.nodeType:
1990
1991
1992 return self
1993 if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
1994 value = node.data
1995 maybe_element = False
1996 else:
1997
1998 assert xml.dom.Node.ELEMENT_NODE == node.nodeType
1999 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=_fallback_namespace)
2000 (element_binding, element_use) = self._ElementBindingUseForName(expanded_name)
2001 if element_binding is not None:
2002 value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=_fallback_namespace)
2003 else:
2004
2005
2006
2007 try:
2008 ns = expanded_name.namespace()
2009 if ns is not None:
2010 for mr in ns.moduleRecords():
2011 try:
2012 if (mr.module() is None) and (mr.modulePath() is not None):
2013 print 'Importing %s to get binding for wildcard %s' % (mr.modulePath(), expanded_name)
2014 mod = __import__(mr.modulePath())
2015 for c in mr.modulePath().split('.')[1:]:
2016 mod = getattr(mod, c)
2017 mr._setModule(mod)
2018 value = mr.module().CreateFromDOM(node)
2019 break
2020 except pyxb.PyXBException, e:
2021 print 'Ignoring error when creating binding for wildcard %s: %s' % (expanded_name, e)
2022 except AttributeError, e:
2023
2024
2025
2026
2027 if mr.namespace() != pyxb.namespace.XMLSchema:
2028 raise
2029 except Exception, e:
2030 print 'WARNING: Unable to convert DOM node %s to Python instance: %s' % (expanded_name, e)
2031 if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
2032 if (0 == len(value.strip())) and not self._isNil():
2033 return self
2034 if self._isNil() and not self._IsSimpleTypeContent():
2035 raise pyxb.ExtraContentError('%s: Content %s present in element with xsi:nil' % (type(self), value))
2036 if maybe_element and (self.__modelState is not None):
2037
2038 if not require_validation:
2039 if element_use is not None:
2040 element_use.setOrAppend(self, value)
2041 return self
2042 raise pyxb.StructuralBadDocumentError('Validation is required when no element_use can be found')
2043 if self.wildcardElements() is not None:
2044 self._appendWildcardElement(value)
2045 return self
2046 else:
2047
2048 ( consumed, underflow_exc ) = self.__modelState.step(self, value, element_use)
2049 if consumed:
2050 return self
2051
2052
2053
2054 if (element_binding is not None) or isinstance(value, xml.dom.Node):
2055 raise pyxb.ExtraContentError('%s: Extra content %s starting with %s' % (self._ExpandedName, element_binding, value,))
2056
2057
2058
2059 if self._IsSimpleTypeContent():
2060 if self.__content is not None:
2061 raise pyxb.ExtraContentError('Extra content starting with %s (already have %s)' % (value, self.__content))
2062 if not self._isNil():
2063 if not isinstance(value, self._TypeDefinition):
2064 value = self._TypeDefinition.Factory(value)
2065 self.__setContent(value)
2066 if require_validation:
2067
2068
2069
2070 self.xsdConstraintsOK()
2071 return self
2072
2073
2074 if not self._IsMixed():
2075 raise pyxb.UnexpectedNonElementContentError(value)
2076 if isinstance(value, _TypeBinding_mixin):
2077 raise pyxb.ExtraContentError('Extra content starting with %s' % (value,))
2078
2079 self._addContent(value, element_binding)
2080 return self
2081
2087
2088 - def extend (self, value_list, _fallback_namespace=None):
2089 """Invoke L{append} for each value in the list, in turn."""
2090 [ self.append(_v, _fallback_namespace=_fallback_namespace) for _v in value_list ]
2091 return self
2092
2093 - def __setContent (self, value):
2095
2096 - def _addContent (self, child, element_binding):
2097
2098
2099
2100 assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
2101 if isinstance(child, _TypeBinding_mixin) and (child._element() is None):
2102 child._setElement(element_binding)
2103 self.__content.append(child)
2104
2105 @classmethod
2108
2109 - def _postDOMValidate (self):
2110 if self._PerformValidation() and (not self._isNil()) and (self.__modelState is not None):
2111 self.__modelState.verifyComplete()
2112 self._validateAttributes()
2113 return self
2114
2115 - def _setContentFromDOM (self, node, _fallback_namespace):
2116 """Initialize the content of this element from the content of the DOM node."""
2117
2118 self.extend(node.childNodes[:], _fallback_namespace)
2119 return self._postDOMValidate()
2120
2126
2128 """Create a DOM element with the given tag holding the content of this instance."""
2129 element = parent
2130 self._setDOMFromAttributes(dom_support, element)
2131 if self._isNil():
2132 pass
2133 elif self._CT_EMPTY == self._ContentTypeTag:
2134 pass
2135 elif self._CT_SIMPLE == self._ContentTypeTag:
2136 assert self.value() is not None, '%s has no value' % (self,)
2137 element.appendChild(dom_support.document().createTextNode(self.value().xsdLiteral()))
2138 else:
2139 if pyxb._GenerationRequiresValid:
2140 order = self._validatedChildren()
2141 else:
2142 order = self.__childrenForDOM()
2143 if order is None:
2144 raise pyxb.DOMGenerationError('Binding value inconsistent with content model')
2145 for (eu, v) in order:
2146 assert v != self
2147 if eu is None:
2148 if isinstance(v, xml.dom.Node):
2149 element.appendChild(v)
2150 else:
2151 v.toDOM(dom_support, parent)
2152 else:
2153 eu.toDOM(dom_support, parent, v)
2154 mixed_content = self.content()
2155 for mc in mixed_content:
2156 pass
2157 return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
2158
2159 @classmethod
2161 """CTDs with simple content are simple; other CTDs are not."""
2162 return cls._CT_SIMPLE == cls._ContentTypeTag
2163
2164 @classmethod
2165 - def _description (cls, name_only=False, user_documentation=True):
2191
2192 ConfigureBindingStyle(DEFAULT_BINDING_STYLE)
2193
2194
2195
2196
2197