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 - def toDOM (self, bds=None, parent=None, element_name=None):
347 """Convert this instance to a DOM node.
348
349 The name of the top-level element is either the name of the L{element}
350 instance associated with this instance, or the XML name of the type of
351 this instance.
352
353 @param bds: Support for customizing the generated document
354 @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
355 @param parent: If C{None}, a standalone document is created;
356 otherwise, the created element is a child of the given element.
357 @type parent: C{xml.dom.Element} or C{None}
358 @rtype: C{xml.dom.Document}
359 """
360
361 if bds is None:
362 bds = domutils.BindingDOMSupport()
363 need_xsi_type = bds.requireXSIType()
364 if isinstance(element_name, (str, unicode)):
365 element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
366 if (element_name is None) and (self._element() is not None):
367 element_binding = self._element()
368 element_name = element_binding.name()
369 need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
370 if element_name is None:
371 element_name = self._ExpandedName
372 element = bds.createChildElement(element_name, parent)
373 if need_xsi_type:
374 val_type_qname = self._ExpandedName.localName()
375 tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
376 if tns_prefix is not None:
377 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
378 bds.addAttribute(element, XSI.type, val_type_qname)
379 self._toDOM_csc(bds, element)
380 bds.finalize()
381 return bds.document()
382
383 - def toxml (self, bds=None, root_only=False):
384 """Shorthand to get the object as an XML document.
385
386 If you want to set the default namespace, pass in a pre-configured
387 C{bds}.
388
389 @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
390 to use for creation. If not provided (default), a new generic one is
391 created.
392 """
393 dom = self.toDOM(bds)
394 if root_only:
395 dom = dom.documentElement
396 return dom.toxml()
397
403
405 """Override in subclasses for type-specific validation of instance
406 content.
407
408 @return: C{True} if the instance validates
409 @raise pyxb.BindingValidationError: complex content does not match model
410 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
411 """
412 raise pyxb.IncompleteImplementationError('%s did not override _validateBinding_vx' % (type(self),))
413
415 """Check whether the binding content matches its content model.
416
417 @return: C{True} if validation succeeds.
418 @raise pyxb.BindingValidationError: complex content does not match model
419 @raise pyxb.BadTypeValueError: simple content fails to satisfy constraints
420 """
421 if self._PerformValidation():
422 self._validateBinding_vx()
423 return True
424
425 - def _postDOMValidate (self):
426 self.validateBinding()
427 return self
428
429 @classmethod
436
438 """Helper to allow overriding the implementation class.
439
440 Generally we'll want to augment the generated bindings by subclassing
441 them, and adding functionality to the subclass. This mix-in provides a
442 way to communicate the existence of the superseding subclass back to the
443 binding infrastructure, so that when it creates an instance it uses the
444 subclass rather than the unaugmented binding class.
445
446 When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
447 invoked on the raw class passing in the superseding subclass. E.g.::
448
449 class mywsdl (raw.wsdl):
450 pass
451 raw.wsdl._SetSupersedingClass(mywsdl)
452
453 """
454
455 @classmethod
457 return '_%s__SupersedingClass' % (cls.__name__,)
458
459 @classmethod
461 return '_%s__AlternativeConstructor' % (cls.__name__,)
462
463 @classmethod
467
468 @classmethod
470 """Return the class stored in the class reference attribute."""
471 rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
472 if isinstance(rv, tuple):
473 rv = rv[0]
474 return rv
475
476 @classmethod
478 """Set the class reference attribute.
479
480 @param superseding: A Python class that is a subclass of this class.
481 """
482 assert (superseding is None) or issubclass(superseding, cls)
483 if superseding is None:
484 cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
485 else:
486 setattr(cls, cls.__SupersedingClassAttribute(), superseding)
487 return superseding
488
489 @classmethod
491 attr = cls.__AlternativeConstructorAttribute()
492 if alternative_constructor is None:
493 cls.__dict__.pop(attr, None)
494 else:
495
496
497
498 setattr(cls, attr, (alternative_constructor,))
499 assert cls._AlternativeConstructor() == alternative_constructor
500 return alternative_constructor
501
502 @classmethod
514
515 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
516 """L{simpleTypeDefinition} is a base class that is part of the
517 hierarchy of any class that represents the Python datatype for a
518 L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
519
520 @note: This class, or a descendent of it, must be the first class
521 in the method resolution order when a subclass has multiple
522 parents. Otherwise, constructor keyword arguments may not be
523 removed before passing them on to Python classes that do not
524 accept them.
525 """
526
527
528
529
530 __FacetMap = {}
531
532 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
533 'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
534 'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
535 'PythonLiteral', 'pythonLiteral',
536 'SimpleTypeDefinition' ]))
537 """Symbols that remain the responsibility of this class. Any
538 public symbols in generated binding subclasses are deconflicted
539 by providing an alternative name in the subclass. (There
540 currently are no public symbols in generated SimpleTypeDefinion
541 bindings."""
542
543
544 @classmethod
552
553
554
555
556 __FacetMapAttributeNameMap = { }
557 @classmethod
559 """ """
560 '''
561 if cls == simpleTypeDefinition:
562 return '_%s__FacetMap' % (cls.__name__.strip('_'),)
563
564 # It is not uncommon for a class in one namespace to extend a class of
565 # the same name in a different namespace, so encode the namespace URI
566 # in the attribute name (if it is part of a namespace).
567 ns_uri = ''
568 try:
569 ns_uri = cls._ExpandedName.namespaceURI()
570 except Exception, e:
571 pass
572 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
573 '''
574 nm = cls.__FacetMapAttributeNameMap.get(cls)
575 if nm is None:
576 nm = cls.__name__
577 if nm.endswith('_'):
578 nm += '1'
579 if cls == simpleTypeDefinition:
580 nm = '_%s__FacetMap' % (nm,)
581 else:
582
583
584
585 ns_uri = ''
586 try:
587 ns_uri = cls._ExpandedName.namespaceURI()
588 except Exception, e:
589 pass
590 nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
591 cls.__FacetMapAttributeNameMap[cls] = nm
592 return nm
593
594 @classmethod
596 """Return a reference to the facet map for this datatype.
597
598 The facet map is a map from leaf facet classes to instances of those
599 classes that constrain or otherwise apply to the lexical or value
600 space of the datatype. Classes may inherit their facet map from their
601 superclass, or may create a new class instance if the class adds a new
602 constraint type.
603
604 :raise AttributeError: if the facet map has not been defined"""
605 return getattr(cls, cls.__FacetMapAttributeName())
606
607 @classmethod
609 """Initialize the facet map for this datatype.
610
611 This must be called exactly once, after all facets belonging to the
612 datatype have been created.
613
614 :raise pyxb.LogicError: if called multiple times (on the same class)
615 :raise pyxb.LogicError: if called when a parent class facet map has not been initialized
616 :return: the facet map"""
617 fm = None
618 try:
619 fm = cls._FacetMap()
620 except AttributeError:
621 pass
622 if fm is not None:
623 raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
624
625
626
627
628
629 source_class = cls
630 while fm is None:
631
632
633 for super_class in source_class.mro():
634
635 assert super_class is not None
636 if (super_class == simpleTypeDefinition):
637 break
638 if issubclass(super_class, simpleTypeDefinition):
639 try:
640 fm = super_class._FacetMap()
641
642 break
643 except AttributeError:
644 pass
645 if fm is None:
646 try:
647 source_class = source_class.XsdSuperType()
648 except AttributeError:
649 source_class = None
650
651 if source_class is None:
652 fm = { }
653
654 if fm is None:
655 raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
656 fm = fm.copy()
657
658 for facet in args:
659 fm[type(facet)] = facet
660
661
662 setattr(cls, cls.__FacetMapAttributeName(), fm)
663 return fm
664
665 @classmethod
668
669 @classmethod
671 """Pre-process the arguments.
672
673 This is used before invoking the parent constructor. One application
674 is to apply the whitespace facet processing; if such a request is in
675 the keywords, it is removed so it does not propagate to the
676 superclass. Another application is to convert the arguments from a
677 string to a list. Binding-specific applications are performed in the
678 overloaded L{_ConvertArguments_vx} method."""
679 dom_node = kw.pop('_dom_node', None)
680 from_xml = kw.get('_from_xml', dom_node is not None)
681 if dom_node is not None:
682 text_content = domutils.ExtractTextContent(dom_node)
683 if text_content is not None:
684 args = (domutils.ExtractTextContent(dom_node),) + args
685 kw['_apply_whitespace_facet'] = True
686 apply_whitespace_facet = kw.pop('_apply_whitespace_facet', from_xml)
687 if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
688 cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
689 if cf_whitespace is not None:
690
691 norm_str = unicode(cf_whitespace.normalizeString(args[0]))
692 args = (norm_str,) + args[1:]
693 kw['_from_xml'] = from_xml
694 return cls._ConvertArguments_vx(args, kw)
695
696
697
698
699
700
701
702
703
704
705
707
708 kw.pop('_validate_constraints', None)
709 kw.pop('_require_value', None)
710 kw.pop('_element', None)
711 kw.pop('_fallback_namespace', None)
712 kw.pop('_nil', None)
713
714 args = cls._ConvertArguments(args, kw)
715 kw.pop('_from_xml', None)
716 assert issubclass(cls, _TypeBinding_mixin)
717 try:
718 rv = super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
719 return rv
720 except ValueError, e:
721 raise pyxb.BadTypeValueError(e)
722 except OverflowError, e:
723 raise pyxb.BadTypeValueError(e)
724
725
726
728 """Initialize a newly created STD instance.
729
730 Usually there is one positional argument, which is a value that can be
731 converted to the underlying Python type.
732
733 @keyword _validate_constraints: If True (default), the newly
734 constructed value is checked against its constraining facets.
735 @type _validate_constraints: C{bool}
736 """
737
738 validate_constraints = kw.pop('_validate_constraints', self._PerformValidation())
739 require_value = kw.pop('_require_value', False)
740
741
742 args = self._ConvertArguments(args, kw)
743 try:
744 super(simpleTypeDefinition, self).__init__(*args, **kw)
745 except OverflowError, e:
746 raise pyxb.BadTypeValueError(e)
747 if require_value and (not self._constructedWithValue()):
748 raise pyxb.MissingContentError('missing value')
749
750 if validate_constraints:
751 self.xsdConstraintsOK()
752
753
754
755
756
757
758
759 @classmethod
761 return '_%s__SimpleTypeDefinition' % (cls.__name__,)
762
763 @classmethod
765 """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
766 associated with this binding."""
767 attr_name = cls.__STDAttrName()
768 if hasattr(cls, attr_name):
769 old_value = getattr(cls, attr_name)
770 if old_value != std:
771 raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
772 setattr(cls, attr_name, std)
773
774 @classmethod
776 """Return the SimpleTypeDefinition instance for the given
777 class.
778
779 This should only be invoked when generating bindings.
780
781 @raise pyxb.IncompleteImplementationError: no STD instance has been
782 associated with the class.
783
784 """
785 attr_name = cls.__STDAttrName()
786 if hasattr(cls, attr_name):
787 return getattr(cls, attr_name)
788 raise pyxb.IncompleteImplementationError('%s: No STD available' % (cls,))
789
790 @classmethod
792 """Convert from a python value to a string usable in an XML
793 document.
794
795 This should be implemented in the subclass."""
796 raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
797
799 """Return text suitable for representing the value of this
800 instance in an XML document.
801
802 The base class implementation delegates to the object class's
803 XsdLiteral method."""
804 if self._isNil():
805 return ''
806 return self.XsdLiteral(self)
807
808 @classmethod
810 """Find the nearest parent class in the PST hierarchy.
811
812 The value for anySimpleType is None; for all others, it's a
813 primitive or derived PST descendent (including anySimpleType)."""
814 for sc in cls.mro():
815 if sc == cls:
816 continue
817 if simpleTypeDefinition == sc:
818
819
820
821 return cls._XsdBaseType
822 if issubclass(sc, simpleTypeDefinition):
823 return sc
824 raise pyxb.LogicError('No supertype found for %s' % (cls,))
825
826 @classmethod
828 """Pre-extended class method to verify other things before
829 checking constraints.
830
831 This is used for list types, to verify that the values in the
832 list are acceptable, and for token descendents, to check the
833 lexical/value space conformance of the input.
834 """
835 super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
836 return super_fn(value)
837
838
839
840 __ClassFacetSequence = { }
841
842 @classmethod
844 """Validate the given value against the constraints on this class.
845
846 @raise pyxb.BadTypeValueError: if any constraint is violated.
847 """
848
849 value = cls._XsdConstraintsPreCheck_vb(value)
850
851 facet_values = cls.__ClassFacetSequence.get(cls)
852 if facet_values is None:
853
854
855 classes = [ _x for _x in cls.mro() if issubclass(_x, simpleTypeDefinition) ]
856 classes.reverse()
857 cache_result = True
858 facet_values = []
859 for clazz in classes:
860
861
862
863
864
865
866 try:
867 clazz_facets = clazz._FacetMap().values()
868 except AttributeError, e:
869 cache_result = False
870 clazz_facets = []
871 for v in clazz_facets:
872 if not (v in facet_values):
873 facet_values.append(v)
874 if cache_result:
875 cls.__ClassFacetSequence[cls] = facet_values
876 for f in facet_values:
877 if not f.validateConstraint(value):
878 raise pyxb.BadTypeValueError('%s violation for %s in %s' % (f.Name(), value, cls.__name__))
879
880 return value
881
883 """Validate the value of this instance against its constraints."""
884 return self.XsdConstraintsOK(self)
885
890
891 @classmethod
893 """Return the length of the given value.
894
895 The length is calculated by a subclass implementation of
896 _XsdValueLength_vx in accordance with
897 http://www.w3.org/TR/xmlschema-2/#rf-length.
898
899 The return value is a non-negative integer, or C{None} if length
900 constraints should be considered trivially satisfied (as with
901 QName and NOTATION).
902
903 :raise pyxb.LogicError: the provided value is not an instance of cls.
904 :raise pyxb.LogicError: an attempt is made to calculate a length for
905 an instance of a type that does not support length calculations.
906 """
907 assert isinstance(value, cls)
908 if not hasattr(cls, '_XsdValueLength_vx'):
909 raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
910 return cls._XsdValueLength_vx(value)
911
913 """Return the length of this instance within its value space.
914
915 See XsdValueLength."""
916 return self.XsdValueLength(self)
917
918 @classmethod
920 """Return a string which can be embedded into Python source to
921 represent the given value as an instance of this class."""
922 class_name = cls.__name__
923 return '%s(%s)' % (class_name, repr(value))
924
926 """Return a string which can be embedded into Python source to
927 represent the value of this instance."""
928 return self.PythonLiteral(self)
929
934
935 @classmethod
937 """STDs have simple type content."""
938 return True
939
940 @classmethod
948
949 @classmethod
951
952 """NB: Invoking this on a value that is a list will, if necessary,
953 replace the members of the list with new values that are of the
954 correct item type. This is permitted because only with lists is it
955 possible to bypass the normal content validation (by invoking
956 append/extend on the list instance)."""
957 if value is None:
958 raise pyxb.BadTypeValueError('None is not a valid instance of %s' % (cls,))
959
960 value_class = cls
961 if issubclass(cls, STD_list):
962
963 try:
964 iter(value)
965 except TypeError, e:
966 raise pyxb.BadTypeValueError('%s cannot have non-iterable value type %s' % (cls, type(value)))
967 for v in value:
968 if not cls._ItemType._IsValidValue(v):
969 raise pyxb.BadTypeValueError('%s cannot have member of type %s (want %s)' % (cls, type(v), cls._ItemType))
970 else:
971 if issubclass(cls, STD_union):
972
973 value_class = None
974 for mt in cls._MemberTypes:
975 if mt._IsValidValue(value):
976 value_class = mt
977 break
978 if value_class is None:
979 raise pyxb.BadTypeValueError('%s cannot have value type %s' % (cls, type(value)))
980
981 if not isinstance(value, value_class):
982 raise pyxb.BadTypeValueError('Value type %s is not valid for %s' % (type(value), cls))
983 value_class.XsdConstraintsOK(value)
984
987
990
991 @classmethod
992 - def _description (cls, name_only=False, user_documentation=True):
993 name = cls._Name()
994 if name_only:
995 return name
996 desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
997 if user_documentation and (cls._Documentation is not None):
998 desc.extend(["\n", cls._Documentation])
999 return ''.join(desc)
1000
1002 """Base class for union datatypes.
1003
1004 This class descends only from simpleTypeDefinition. A pyxb.LogicError is
1005 raised if an attempt is made to construct an instance of a subclass of
1006 STD_union. Values consistent with the member types are constructed using
1007 the Factory class method. Values are validated using the _ValidatedMember
1008 class method.
1009
1010 Subclasses must provide a class variable _MemberTypes which is a
1011 tuple of legal members of the union."""
1012
1013 _MemberTypes = None
1014 """A list of classes which are permitted as values of the union."""
1015
1016
1017
1018
1019 __FacetMap = {}
1020
1021 @classmethod
1023 """Given a value, attempt to create an instance of some member of this
1024 union. The first instance which can be legally created is returned.
1025
1026 @keyword _validate_constraints: If True (default), any constructed
1027 value is checked against constraints applied to the union as well as
1028 the member type.
1029
1030 @raise pyxb.BadTypeValueError: no member type will permit creation of
1031 an instance from the parameters in C{args} and C{kw}.
1032 """
1033
1034 used_cls = cls._SupersedingClass()
1035 state = used_cls._PreFactory_vx(args, kw)
1036
1037 rv = None
1038
1039 validate_constraints = kw.get('_validate_constraints', cls._PerformValidation())
1040 assert isinstance(validate_constraints, bool)
1041 if 0 < len(args):
1042 arg = args[0]
1043 try:
1044 rv = cls._ValidatedMember(arg)
1045 except pyxb.BadTypeValueError, e:
1046 pass
1047 if rv is None:
1048 kw['_validate_constraints'] = True
1049 for mt in cls._MemberTypes:
1050 try:
1051 rv = mt.Factory(*args, **kw)
1052 break
1053 except pyxb.BadTypeValueError:
1054 pass
1055 except ValueError:
1056 pass
1057 except:
1058 pass
1059 if rv is not None:
1060 if validate_constraints:
1061 cls.XsdConstraintsOK(rv)
1062 rv._postFactory_vx(state)
1063 return rv
1064 raise pyxb.BadTypeValueError('%s cannot construct union member from args %s' % (cls.__name__, args))
1065
1066 @classmethod
1068 """Validate the given value as a potential union member.
1069
1070 @raise pyxb.BadTypeValueError: the value is not an instance of a
1071 member type."""
1072 if not isinstance(value, cls._MemberTypes):
1073 for mt in cls._MemberTypes:
1074 try:
1075
1076
1077 value = mt.Factory(value, _validate_constraints=True)
1078 return value
1079 except (TypeError, pyxb.BadTypeValueError):
1080 pass
1081 raise pyxb.BadTypeValueError('%s cannot hold a member of type %s' % (cls.__name__, value.__class__.__name__))
1082 return value
1083
1085 raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
1086
1087 @classmethod
1088 - def _description (cls, name_only=False, user_documentation=True):
1095
1096 @classmethod
1100
1101
1102 -class STD_list (simpleTypeDefinition, types.ListType):
1103 """Base class for collection datatypes.
1104
1105 This class descends from the Python list type, and incorporates
1106 simpleTypeDefinition. Subclasses must define a class variable _ItemType
1107 which is a reference to the class of which members must be instances."""
1108
1109 _ItemType = None
1110 """A reference to the binding class for items within this list."""
1111
1112
1113
1114 __FacetMap = {}
1115
1116 @classmethod
1134
1135 @classmethod
1137
1138
1139 if 0 < len(args):
1140 arg1 = args[0]
1141 if isinstance(arg1, types.StringTypes):
1142 args = (arg1.split(),) + args[1:]
1143 arg1 = args[0]
1144 is_iterable = False
1145 try:
1146 iter(arg1)
1147 is_iterable = True
1148 except TypeError:
1149 pass
1150 if is_iterable:
1151 new_arg1 = []
1152 for i in range(len(arg1)):
1153 new_arg1.append(cls._ValidatedItem(arg1[i]))
1154 args = (new_arg1,) + args[1:]
1155 super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
1156 return super_fn(args, kw)
1157
1158 @classmethod
1161
1162 @classmethod
1164 """Convert from a binding value to a string usable in an XML document."""
1165 return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
1166
1167 @classmethod
1168 - def _description (cls, name_only=False, user_documentation=True):
1174
1175
1176 @classmethod
1179
1180
1183
1189
1192
1195
1196
1197
1200
1201 - def extend (self, x, _from_xml=False):
1203
1206
1207 - def index (self, x, *args):
1209
1212
1215
1216 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1217 """Class that represents a schema element.
1218
1219 Global and local elements are represented by instances of this class.
1220 """
1221
1223 """The expanded name of the element within its scope."""
1224 return self.__name
1225 __name = None
1226
1230 __typeDefinition = None
1231
1233 """The scope of the element. This is either C{None}, representing a
1234 top-level element, or an instance of C{complexTypeDefinition} for
1235 local elements."""
1236 return self.__scope
1237 __scope = None
1238
1240 """Indicate whether values matching this element can have U{nil
1241 <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
1242 return self.__nillable
1243 __nillable = False
1244
1246 """Indicate whether this element is abstract (must use substitution
1247 group members for matches)."""
1248 return self.__abstract
1249 __abstract = False
1250
1252 """Contents of any documentation annotation in the definition."""
1253 return self.__documentation
1254 __documentation = None
1255
1258 __defaultValue = None
1259
1261 """The L{element} instance to whose substitution group this element
1262 belongs. C{None} if this element is not part of a substitution
1263 group."""
1264 return self.__substitutionGroup
1270 __substitutionGroup = None
1271
1279
1281 """Determine whether an instance of this element can substitute for the other element.
1282
1283 See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>)}.
1284
1285 @todo: Do something about blocking constraints. This ignores them, as
1286 does everything leading to this point.
1287 """
1288 if self.substitutionGroup() is None:
1289 return False
1290 if other is None:
1291 return False
1292 assert isinstance(other, element)
1293
1294
1295 if other.scope() is not None:
1296 other = other.name().elementBinding()
1297 if other is None:
1298 return False
1299 assert other.scope() is None
1300
1301 if self.name().elementBinding() == other:
1302 return True
1303 return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
1304
1306 """Stub replaced by _real_substitutesFor when element supports substitution groups."""
1307 return False
1308
1310 """Return a reference to the element instance used for the given name
1311 within this element.
1312
1313 The type for this element must be a complex type definition."""
1314 return self.typeDefinition()._UseForTag(name).elementBinding()
1315
1316 - def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, default_value=None, substitution_group=None, documentation=None):
1328
1330 """Invoke the Factory method on the type associated with this element.
1331
1332 @keyword _dom_node: If set, specifies a DOM node that should be used
1333 for initialization. In that case, the L{createFromDOM} method is
1334 invoked instead of the type definition Factory method.
1335
1336 @note: Other keywords are passed to L{_TypeBinding_mixin.Factory}.
1337
1338 @raise pyxb.AbstractElementError: This element is abstract and no DOM
1339 node was provided.
1340 """
1341 dom_node = kw.pop('_dom_node', None)
1342 assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
1343 if '_element' in kw:
1344 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1345 kw['_element'] = self
1346
1347 if self.abstract():
1348 raise pyxb.AbstractElementError(self)
1349 return self.typeDefinition().Factory(*args, **kw)
1350
1373
1374
1375 @classmethod
1387
1389 """Return the element that should be used if this element binding is
1390 permitted and an element with the given name is encountered.
1391
1392 Normally, the incoming name matches the name of this binding, and
1393 C{self} is returned. If the incoming name is different, it is
1394 expected to be the name of a global element which is within this
1395 element's substitution group. In that case, the binding corresponding
1396 to the named element is return.
1397
1398 @return: An instance of L{element}, or C{None} if no element with the
1399 given name can be found.
1400 """
1401
1402
1403 if self.name() == name:
1404 return self
1405
1406
1407 top_elt = self.name().elementBinding()
1408 if top_elt is None:
1409 return None
1410
1411
1412
1413
1414 elt_en = top_elt.name().adoptName(name)
1415 assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
1416 named_elt = elt_en.elementBinding()
1417 if (named_elt is None) or (named_elt == top_elt):
1418 return None
1419 if named_elt.substitutesFor(top_elt):
1420 return named_elt
1421 return None
1422
1423 - def createFromDOM (self, node, expanded_name=None, fallback_namespace=None, **kw):
1424 """Create a binding instance from the given DOM node.
1425
1426 @keyword expanded_name: Optional name for the DOM node. If not
1427 present, is inferred from C{node}.
1428
1429 @keyword fallback_namespace: Optional namespace to use when resolving
1430 unqualified names.
1431 """
1432 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1433 node = node.documentElement
1434 if expanded_name is None:
1435 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
1436 return self._createFromDOM(node, expanded_name, **kw)
1437
1439 """Create a binding instance from the given DOM node, using the
1440 provided name to identify the correct binding.
1441
1442 The context and information associated with this element is used to
1443 identify the actual element binding to use. By default, C{self} is
1444 used. If this element represents a term in a content model, the name
1445 and namespace of the incoming node may identify a different element.
1446 If that element is a member of this element's substitution group, the
1447 binding associated with the node's name will be used instead.
1448
1449 The type of object returned is determined by the type definition
1450 associated with the element binding and the value of any U{xsi:type
1451 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in the
1452 node, modulated by the configuration of L{XSI.ProcessTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance.ProcessTypeAttribute>}.
1453
1454 Keyword parameters are passed to the factory method of the type
1455 associated with the selected element binding. See
1456 L{_TypeBinding_mixin} and any specializations of it.
1457
1458 @param expanded_name: The expanded name of the node. If the value is
1459 C{None}, defaults to the name of this element. (In the case of
1460 substitution groups, the default is wrong, but correct inference
1461 depends on context not available here.)
1462
1463 @keyword _fallback_namespace: Optional namespace to use when resolving
1464 unqualified type names.
1465
1466 @param node: The DOM node specifying the element content. If this is
1467 a (top-level) Document node, its element node is used.
1468 @type node: C{xml.dom.Node}
1469 @return: An instance of L{_TypeBinding_mixin}
1470 @raise pyxb.StructuralBadDocumentError: The node's name does identify an element binding.
1471 @raise pyxb.AbstractElementError: The element binding associated with the node is abstract.
1472 @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
1473 @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.
1474 """
1475
1476
1477
1478 if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
1479 node = node.documentElement
1480
1481
1482
1483
1484
1485 fallback_namespace = kw.pop('_fallback_namespace', None)
1486 element_binding = self.elementForName(expanded_name)
1487 if element_binding is None:
1488 raise pyxb.StructuralBadDocumentError('Element %s cannot create from node %s' % (self.name(), expanded_name))
1489
1490
1491
1492
1493 if element_binding.abstract():
1494 raise pyxb.AbstractElementError(element_binding)
1495
1496
1497
1498 if '_element' in kw:
1499 raise pyxb.LogicError('Cannot set _element in element-based instance creation')
1500 kw['_element'] = element_binding
1501
1502
1503
1504 type_class = element_binding.typeDefinition()
1505 elt_ns = element_binding.name().namespace()
1506
1507
1508
1509
1510
1511 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
1512 (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
1513
1514
1515
1516
1517 is_nil = XSI.nil.getAttribute(node)
1518 if is_nil is not None:
1519 kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1520
1521 rv = type_class.Factory(_dom_node=node, _fallback_namespace=fallback_namespace, **kw)
1522 assert rv._element() == element_binding
1523 rv._setNamespaceContext(ns_ctx)
1524 return rv._postDOMValidate()
1525
1527 return 'Element %s' % (self.name(),)
1528
1529 - def _description (self, name_only=False, user_documentation=True):
1543
1545 """Marker in case we need to know that a PST has an enumeration constraint facet."""
1546 pass
1547
1548 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
1549 """Base for any Python class that serves as the binding for an
1550 XMLSchema complexType.
1551
1552 Subclasses should define a class-level _AttributeMap variable which maps
1553 from the unicode tag of an attribute to the AttributeUse instance that
1554 defines it. Similarly, subclasses should define an _ElementMap variable.
1555 """
1556
1557 _CT_EMPTY = 'EMPTY'
1558 _CT_SIMPLE = 'SIMPLE'
1559 _CT_MIXED = 'MIXED'
1560 _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'
1561
1562 _ContentTypeTag = None
1563
1564 _TypeDefinition = None
1565 """Subclass of simpleTypeDefinition that corresponds to the type content.
1566 Only valid if _ContentTypeTag is _CT_SIMPLE"""
1567
1568
1569
1570
1571 _AttributeWildcard = None
1572
1573 _AttributeMap = { }
1574 """Map from expanded names to AttributeUse instances."""
1575
1576
1577
1578 _HasWildcardElement = False
1579
1580
1581 _ElementMap = { }
1582 """Map from expanded names to ElementUse instances."""
1583
1584
1585
1586 __wildcardAttributeMap = None
1587
1589 """Obtain access to wildcard attributes.
1590
1591 The return value is C{None} if this type does not support wildcard
1592 attributes. If wildcard attributes are allowed, the return value is a
1593 map from QNames to the unicode string value of the corresponding
1594 attribute.
1595
1596 @todo: The map keys should be namespace extended names rather than
1597 QNames, as the in-scope namespace may not be readily available to the
1598 user.
1599 """
1600 return self.__wildcardAttributeMap
1601
1602
1603
1604 __wildcardElements = None
1605
1607 """Obtain access to wildcard elements.
1608
1609 The return value is C{None} if the content model for this type does not
1610 support wildcard elements. If wildcard elements are allowed, the
1611 return value is a list of values corresponding to conformant
1612 unrecognized elements, in the order in which they were encountered.
1613 If the containing binding was created from an XML document and enough
1614 information was present to determine the binding of the member
1615 element, the value is a binding instance. Otherwise, the value is the
1616 original DOM Element node.
1617 """
1618 return self.__wildcardElements
1619
1620 @classmethod
1628
1630 """Create a new instance of this binding.
1631
1632 Arguments are used as transition values along the content model.
1633 Keywords are passed to the constructor of any simple content, or used
1634 to initialize attribute and element values whose L{id
1635 <content.ElementUse.id>} (not L{name <content.ElementUse.name>})
1636 matches the keyword.
1637
1638 @keyword _dom_node: The node to use as the source of binding content.
1639 @type _dom_node: C{xml.dom.Element}
1640
1641 @keyword _from_xml: See L{_TypeBinding_mixin.Factory}
1642
1643 """
1644
1645 fallback_namespace = kw.pop('_fallback_namespace', None)
1646 is_nil = False
1647 dom_node = kw.pop('_dom_node', None)
1648 from_xml = kw.pop('_from_xml', dom_node is not None)
1649 if dom_node is not None:
1650 if isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
1651 self._setLocation(dom_node.location)
1652 if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
1653 dom_node = dom_node.documentElement
1654
1655 is_nil = XSI.nil.getAttribute(dom_node)
1656 if is_nil is not None:
1657 is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
1658 if self._AttributeWildcard is not None:
1659 self.__wildcardAttributeMap = { }
1660 if self._HasWildcardElement:
1661 self.__wildcardElements = []
1662 if self._Abstract:
1663 raise pyxb.AbstractInstantiationError(type(self))
1664 super(complexTypeDefinition, self).__init__(**kw)
1665 self.reset()
1666
1667 attribute_settings = { }
1668 if dom_node is not None:
1669 attribute_settings.update(self.__AttributesFromDOM(dom_node))
1670 for fu in self._AttributeMap.values():
1671 iv = kw.pop(fu.id(), None)
1672 if iv is not None:
1673 attribute_settings[fu.name()] = iv
1674 for (attr_en, value) in attribute_settings.items():
1675 au = self._setAttribute(attr_en, value)
1676 for fu in self._ElementMap.values():
1677 iv = kw.pop(fu.id(), None)
1678 if iv is not None:
1679 fu.set(self, iv)
1680 if kw and kw.pop('_strict_keywords', True):
1681 [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
1682 if kw:
1683 raise pyxb.ExtraContentError(kw)
1684 if dom_node is not None:
1685 if self._CT_SIMPLE == self._ContentTypeTag:
1686 self.__initializeSimpleContent(args, dom_node)
1687 else:
1688 self._setContentFromDOM(dom_node, fallback_namespace)
1689 elif 0 < len(args):
1690 self.extend(args, _from_xml=from_xml)
1691 else:
1692 if self._CT_SIMPLE == self._ContentTypeTag:
1693 self.__initializeSimpleContent(args, dom_node)
1694
1695 - def __initializeSimpleContent (self, args, dom_node=None):
1696
1697
1698
1699
1700 value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _nil=self._isNil(), *args)
1701 if value._constructedWithValue():
1702 if self._isNil():
1703 raise pyxb.ContentInNilElementError(value)
1704 else:
1705 self.append(value)
1706
1707
1708 _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
1709 'xsdConstraintsOK', 'content', 'append', 'extend', 'value', 'reset' ]))
1710
1711
1712
1713 _ContentModel = None
1714
1715 @classmethod
1717 """Method used by generated code to associate the element binding with a use in this type.
1718
1719 This is necessary because all complex type classes appear in the
1720 module prior to any of the element instances (which reference type
1721 classes), so the association must be formed after the element
1722 instances are available."""
1723 return cls._UseForTag(element.name())._setElementBinding(element)
1724
1725 @classmethod
1727 """Return the ElementUse object corresponding to the element name.
1728
1729 @param tag: The L{ExpandedName} of an element in the class."""
1730 rv = cls._ElementMap.get(tag)
1731 if (rv is None) and raise_if_fail:
1732 raise pyxb.NotAnElementError(tag, cls)
1733 return rv
1734
1736 """Generate a list of children in the order in which they should be
1737 added to the parent when creating a DOM representation of this
1738 object.
1739
1740 @note: This is not currently used; it is retained as an example of one
1741 way to override L{_validatedChildren} in cases where content model
1742 validation is not required.
1743 """
1744 order = []
1745 for eu in self._ElementMap.values():
1746 value = eu.value(self)
1747 if value is None:
1748 continue
1749 if isinstance(value, list):
1750 order.extend([ (eu, _v) for _v in value ])
1751 continue
1752 order.append( (eu, value) )
1753 return order
1754
1756 """Provide the child elements and non-element content in an order
1757 consistent with the content model.
1758
1759 Returns a sequence of tuples representing a valid path through the
1760 content model where each transition corresponds to one of the member
1761 element instances within this instance. The tuple is a pair
1762 comprising the L{content.ElementUse} instance and the value for the
1763 transition.
1764
1765 If the content of the instance does not validate against the content
1766 model, C{None} is returned.
1767
1768 The base class implementation uses the
1769 L{content.ParticleModel.validate} method. Subclasses may desire to
1770 override this in cases where the desired order is not maintained by
1771 model interpretation (for example, when an "all" model is used and the
1772 original element order is desired). See L{__childrenForDOM} as an
1773 example of an alternative approach.
1774
1775 @return: C{None} or a list as described above.
1776 """
1777 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1778 return []
1779
1780 if self._ContentModel is None:
1781 raise pyxb.NoContentModel(self)
1782 path = self._ContentModel.validate(self._symbolSet())
1783 if path is not None:
1784 ( symbols, sequence ) = path
1785 if 0 == len(symbols):
1786 return sequence
1787 raise pyxb.BindingValidationError('Ungenerated symbols: %s' % (symbols,) )
1788 return None
1789
1791 """Return a map from L{content.ElementUse} instances to a list of
1792 values associated with that use.
1793
1794 This is used as the set of symbols available for transitions when
1795 validating content against a model. Note that the order of values
1796 within a use is likely to be significant, although the model cannot
1797 detect this.
1798
1799 The value C{None} should be used to provide a list of wildcard
1800 members.
1801
1802 If an element use has no associated values, it must not appear in the
1803 returned map.
1804 """
1805 rv = { }
1806 for eu in self._ElementMap.values():
1807 value = eu.value(self)
1808 if value is None:
1809 continue
1810 res = None
1811 converter = eu.elementBinding().compatibleValue
1812 if eu.isPlural():
1813 if 0 < len(value):
1814 rv[eu] = [ converter(_v) for _v in value ]
1815 else:
1816 rv[eu] = [ converter(value)]
1817 wce = self.wildcardElements()
1818 if (wce is not None) and (0 < len(wce)):
1819 rv[None] = wce[:]
1820 return rv
1821
1825
1846
1847 @classmethod
1867
1877
1879 """Initialize the attributes of this element from those of the DOM node.
1880
1881 @raise pyxb.UnrecognizedAttributeError: if the DOM node has attributes
1882 that are not allowed in this type
1883 @raise pyxb.ProhibitedAttributeError: a prohibited attribute was encountered
1884 @raise pyxb.MissingAttributeError: a required attribute could not be found
1885 """
1886
1887
1888 attrs_available = set(self._AttributeMap.values())
1889 for (attr_en, value) in attribute_settings.items():
1890 au = self._setAttribute(attr_en, value)
1891 if au is not None:
1892 attrs_available.remove(au)
1893
1894 return self
1895
1897 """Validate the content against the simple type.
1898
1899 @return: C{True} if the content validates against its type.
1900 @raise pyxb.NotSimpleContentError: this type does not have simple content.
1901 @raise pyxb.MissingContentError: the content of this type has not been set
1902 """
1903
1904 if self._CT_SIMPLE != self._ContentTypeTag:
1905 raise pyxb.NotSimpleContentError(self)
1906 if self._isNil():
1907 return True
1908 if self.value() is None:
1909 raise pyxb.MissingContentError(self)
1910 return self.value().xsdConstraintsOK()
1911
1912 __content = None
1913 - def content (self):
1914 """Return the content of the element.
1915
1916 This must be a complex type with complex content. The return value is
1917 a list of the element and non-element content in the order in which it
1918 was added.
1919 @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
1920 """
1921 if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
1922 raise pyxb.NotComplexContentError(str(self._ExpandedName))
1923 return self.__content
1924
1926 """Return the value of the element.
1927
1928 This must be a complex type with simple content. The returned value
1929 is expected to be an instance of some L{simpleTypeDefinition} class.
1930
1931 @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
1932 """
1933 if self._CT_SIMPLE != self._ContentTypeTag:
1934 raise pyxb.NotSimpleContentError('%s (%s)' % (str(self._ExpandedName), type(self)))
1935 return self.__content
1936
1937 - def _resetContent (self):
1938 if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
1939 self.__setContent([])
1940 else:
1941 self.__setContent(None)
1942
1943 __modelState = None
1960
1961 @classmethod
1963 """Determine what the given name means as an element in this type.
1964
1965 Normally, C{element_name} identifies an element definition within this
1966 type. If so, the returned C{element_use} identifies that definition,
1967 and the C{element_binding} is extracted from that use.
1968
1969 It may also be that the C{element_name} does not appear as an element
1970 definition, but that it identifies a global element. In that case,
1971 the returned C{element_binding} identifies the global element. If,
1972 further, that element is a member of a substitution group which does
1973 have an element definition in this class, then the returned
1974 C{element_use} identifies that definition.
1975
1976 If a non-C{None} C{element_use} is returned, there will be an
1977 associated C{element_binding}. However, it is possible to return a
1978 non-C{None} C{element_binding}, but C{None} as the C{element_use}. In
1979 that case, the C{element_binding} can be used to create a binding
1980 instance, but the content model will have to treat it as a wildcard.
1981
1982 @param element_name: The name of the element in this type, either an
1983 expanded name or a local name if the element has an absent namespace.
1984
1985 @return: C{( element_binding, element_use )}
1986 """
1987 element_use = cls._ElementMap.get(element_name)
1988 element_binding = None
1989 if element_use is None:
1990 try:
1991 element_binding = element_name.elementBinding()
1992 except pyxb.NamespaceError:
1993 pass
1994 if element_binding is not None:
1995 element_use = element_binding.findSubstituendUse(cls)
1996 else:
1997 element_binding = element_use.elementBinding()
1998 return (element_binding, element_use)
1999
2000 - def append (self, value, element_use=None, maybe_element=True, _fallback_namespace=None, require_validation=True, _from_xml=False):
2001 """Add the value to the instance.
2002
2003 The value should be a DOM node or other value that is or can be
2004 converted to a binding instance. If the instance has a DFA state, the
2005 value must be permitted by the content model.
2006
2007 @raise pyxb.ExtraContentError: the value is not permitted at the
2008 current state of the content model.
2009 """
2010
2011
2012
2013 element_binding = None
2014 if element_use is not None:
2015 import content
2016 assert isinstance(element_use, content.ElementUse)
2017 element_binding = element_use.elementBinding()
2018 assert element_binding is not None
2019
2020 if isinstance(value, xml.dom.Node):
2021 _from_xml = True
2022 assert maybe_element
2023 assert element_binding is None
2024 node = value
2025 require_validation = pyxb._ParsingRequiresValid
2026 if xml.dom.Node.COMMENT_NODE == node.nodeType:
2027
2028
2029 return self
2030 if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
2031 value = node.data
2032 maybe_element = False
2033 else:
2034
2035 assert xml.dom.Node.ELEMENT_NODE == node.nodeType
2036 expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=_fallback_namespace)
2037 (element_binding, element_use) = self._ElementBindingUseForName(expanded_name)
2038 if element_binding is not None:
2039 value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=_fallback_namespace)
2040 else:
2041
2042
2043
2044 try:
2045 ns = expanded_name.namespace()
2046 if ns is not None:
2047 for mr in ns.moduleRecords():
2048 try:
2049 if (mr.module() is None) and (mr.modulePath() is not None):
2050 print 'Importing %s to get binding for wildcard %s' % (mr.modulePath(), expanded_name)
2051 mod = __import__(mr.modulePath())
2052 for c in mr.modulePath().split('.')[1:]:
2053 mod = getattr(mod, c)
2054 mr._setModule(mod)
2055 value = mr.module().CreateFromDOM(node)
2056 break
2057 except pyxb.PyXBException, e:
2058 print 'Ignoring error when creating binding for wildcard %s: %s' % (expanded_name, e)
2059 except AttributeError, e:
2060
2061
2062
2063
2064 if mr.namespace() != pyxb.namespace.XMLSchema:
2065 raise
2066 except Exception, e:
2067 print 'WARNING: Unable to convert DOM node %s to Python instance: %s' % (expanded_name, e)
2068 if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
2069 if (0 == len(value.strip())) and not self._isNil():
2070 return self
2071 if self._isNil() and not self._IsSimpleTypeContent():
2072 raise pyxb.ExtraContentError('%s: Content %s present in element with xsi:nil' % (type(self), value))
2073 if maybe_element and (self.__modelState is not None):
2074
2075 if not require_validation:
2076 if element_use is not None:
2077 element_use.setOrAppend(self, value)
2078 return self
2079 raise pyxb.StructuralBadDocumentError('Validation is required when no element_use can be found')
2080 if self.wildcardElements() is not None:
2081 self._appendWildcardElement(value)
2082 return self
2083 else:
2084
2085 ( consumed, underflow_exc ) = self.__modelState.step(self, value, element_use)
2086 if consumed:
2087 return self
2088
2089
2090
2091 if (element_binding is not None) or isinstance(value, xml.dom.Node):
2092 raise pyxb.ExtraContentError('%s: Extra content %s starting with %s' % (self._ExpandedName, element_binding, value,))
2093
2094
2095
2096 if self._IsSimpleTypeContent():
2097 if self.__content is not None:
2098 raise pyxb.ExtraContentError('Extra content starting with %s (already have %s)' % (value, self.__content))
2099 if not self._isNil():
2100 if not isinstance(value, self._TypeDefinition):
2101 value = self._TypeDefinition.Factory(value, _from_xml=_from_xml)
2102 self.__setContent(value)
2103 if require_validation:
2104
2105
2106
2107 self.xsdConstraintsOK()
2108 return self
2109
2110
2111 if not self._IsMixed():
2112 raise pyxb.UnexpectedNonElementContentError(value)
2113 if isinstance(value, _TypeBinding_mixin):
2114 raise pyxb.ExtraContentError('Extra content starting with %s' % (value,))
2115
2116 self._addContent(value, element_binding)
2117 return self
2118
2124
2125 - def extend (self, value_list, _fallback_namespace=None, _from_xml=False):
2126 """Invoke L{append} for each value in the list, in turn."""
2127 [ self.append(_v, _fallback_namespace=_fallback_namespace, _from_xml=_from_xml) for _v in value_list ]
2128 return self
2129
2130 - def __setContent (self, value):
2132
2133 - def _addContent (self, child, element_binding):
2134
2135
2136
2137 assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
2138 if isinstance(child, _TypeBinding_mixin) and (child._element() is None):
2139 child._setElement(element_binding)
2140 self.__content.append(child)
2141
2142 @classmethod
2145
2146 - def _postDOMValidate (self):
2147 if self._PerformValidation() and (not self._isNil()) and (self.__modelState is not None):
2148 self.__modelState.verifyComplete()
2149 self._validateAttributes()
2150 return self
2151
2152 - def _setContentFromDOM (self, node, _fallback_namespace):
2153 """Initialize the content of this element from the content of the DOM node."""
2154
2155 self.extend(node.childNodes[:], _fallback_namespace)
2156 return self._postDOMValidate()
2157
2163
2165 """Create a DOM element with the given tag holding the content of this instance."""
2166 element = parent
2167 self._setDOMFromAttributes(dom_support, element)
2168 if self._isNil():
2169 pass
2170 elif self._CT_EMPTY == self._ContentTypeTag:
2171 pass
2172 elif self._CT_SIMPLE == self._ContentTypeTag:
2173 assert self.value() is not None, '%s has no value' % (self,)
2174 element.appendChild(dom_support.document().createTextNode(self.value().xsdLiteral()))
2175 else:
2176 if pyxb._GenerationRequiresValid:
2177 order = self._validatedChildren()
2178 else:
2179 order = self.__childrenForDOM()
2180 if order is None:
2181 raise pyxb.DOMGenerationError('Binding value inconsistent with content model')
2182 for (eu, v) in order:
2183 assert v != self
2184 if eu is None:
2185 if isinstance(v, xml.dom.Node):
2186 element.appendChild(v)
2187 else:
2188 v.toDOM(dom_support, parent)
2189 else:
2190 eu.toDOM(dom_support, parent, v)
2191 mixed_content = self.content()
2192 for mc in mixed_content:
2193 pass
2194 return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
2195
2196 @classmethod
2198 """CTDs with simple content are simple; other CTDs are not."""
2199 return cls._CT_SIMPLE == cls._ContentTypeTag
2200
2201 @classmethod
2202 - def _description (cls, name_only=False, user_documentation=True):
2228
2229 ConfigureBindingStyle(DEFAULT_BINDING_STYLE)
2230
2231
2232
2233
2234