1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Helper classes that maintain the content model of XMLSchema in the binding
17 classes.
18
19 L{AttributeUse} and L{ElementDeclaration} record information associated with a binding
20 class, for example the types of values, the original XML QName or NCName, and
21 the Python field in which the values are stored. They also provide the
22 low-level interface to set and get the corresponding values in a binding
23 instance.
24
25 L{Wildcard} holds content-related information used in the content model.
26 """
27
28 import pyxb
29 import pyxb.namespace
30 import pyxb.utils.fac
31 from pyxb.binding import basis
32
33 import xml.dom
34 import logging
35
36 _log = logging.getLogger(__name__)
37
39 """A helper class that encapsulates everything we need to know
40 about the way an attribute is used within a binding class.
41
42 Attributes are stored internally as pairs C{(provided, value)}, where
43 C{provided} is a boolean indicating whether a value for the attribute was
44 provided externally, and C{value} is an instance of the attribute
45 datatype. The C{provided} flag is used to determine whether an XML
46 attribute should be added to a created DOM node when generating the XML
47 corresponding to a binding instance.
48 """
49
50 __name = None
51 """ExpandedName of the attribute"""
52
53 __id = None
54 """Identifier used for this attribute within the owning class"""
55
56 __key = None
57 """Private Python attribute used in instances to hold the attribute value"""
58
59 __dataType = None
60 """The L{pyxb.binding.basis.simpleTypeDefinition} for values of the attribute"""
61
62 __unicodeDefault = None
63 """The default attribute value as a unicode string, or C{None}"""
64
65 __defaultValue = None
66 """The default value as an instance of L{__dataType}, or C{None}"""
67
68 __fixed = False
69 """C{True} if the attribute value cannot be changed"""
70
71 __required = False
72 """C{True} if the attribute must appear in every instance of the type"""
73
74 __prohibited = False
75 """C{True} if the attribute must not appear in any instance of the type"""
76
77 - def __init__ (self, name, id, key, data_type, unicode_default=None, fixed=False, required=False, prohibited=False):
78 """Create an AttributeUse instance.
79
80 @param name: The name by which the attribute is referenced in the XML
81 @type name: L{pyxb.namespace.ExpandedName}
82
83 @param id: The Python identifier for the attribute within the
84 containing L{pyxb.basis.binding.complexTypeDefinition}. This is a
85 public identifier, derived from the local part of the attribute name
86 and modified to be unique, and is usually used as the name of the
87 attribute's inspector method.
88 @type id: C{str}
89
90 @param key: The string used to store the attribute
91 value in the dictionary of the containing
92 L{pyxb.basis.binding.complexTypeDefinition}. This is mangled so
93 that it is unique among and is treated as a Python private member.
94 @type key: C{str}
95
96 @param data_type: The class reference to the subclass of
97 L{pyxb.binding.basis.simpleTypeDefinition} of which the attribute
98 values must be instances.
99 @type data_type: C{type}
100
101 @keyword unicode_default: The default value of the attribute as
102 specified in the schema, or None if there is no default attribute
103 value. The default value (of the keyword) is C{None}.
104 @type unicode_default: C{unicode}
105
106 @keyword fixed: If C{True}, indicates that the attribute, if present,
107 must have the value that was given via C{unicode_default}. The
108 default value is C{False}.
109 @type fixed: C{bool}
110
111 @keyword required: If C{True}, indicates that the attribute must appear
112 in the DOM node used to create an instance of the corresponding
113 L{pyxb.binding.basis.complexTypeDefinition}. The default value is
114 C{False}. No more that one of L{required} and L{prohibited} should be
115 assigned C{True}.
116 @type required: C{bool}
117
118 @keyword prohibited: If C{True}, indicates that the attribute must
119 B{not} appear in the DOM node used to create an instance of the
120 corresponding L{pyxb.binding.basis.complexTypeDefinition}. The
121 default value is C{False}. No more that one of L{required} and
122 L{prohibited} should be assigned C{True}.
123 @type prohibited: C{bool}
124
125 @raise pyxb.SimpleTypeValueError: the L{unicode_default} cannot be used
126 to initialize an instance of L{data_type}
127 """
128
129 self.__name = name
130 self.__id = id
131 self.__key = key
132 self.__dataType = data_type
133 self.__unicodeDefault = unicode_default
134 if self.__unicodeDefault is not None:
135 self.__defaultValue = self.__dataType.Factory(self.__unicodeDefault, _from_xml=True)
136 self.__fixed = fixed
137 self.__required = required
138 self.__prohibited = prohibited
139 super(AttributeUse, self).__init__()
140
142 """The expanded name of the element.
143
144 @rtype: L{pyxb.namespace.ExpandedName}
145 """
146 return self.__name
147
149 """The default value of the attribute."""
150 return self.__defaultValue
151
153 """C{True} iff the value of the attribute cannot be changed."""
154 return self.__fixed
155
157 """C{True} iff the attribute must be assigned a value."""
158 return self.__required
159
161 """C{True} iff the attribute must not be assigned a value."""
162 return self.__prohibited
163
165 """C{True} iff the given instance has been explicitly given a value
166 for the attribute.
167
168 This is used for things like only generating an XML attribute
169 assignment when a value was originally given (even if that value
170 happens to be the default).
171 """
172 return self.__getProvided(ctd_instance)
173
175 """Tag used within Python code for the attribute.
176
177 This is not used directly in the default code generation template."""
178 return self.__id
179
181 """String used as key within object dictionary when storing attribute value."""
182 return self.__key
183
185 """The subclass of L{pyxb.binding.basis.simpleTypeDefinition} of which any attribute value must be an instance."""
186 return self.__dataType
187
189 """Retrieve the value information for this attribute in a binding instance.
190
191 @param ctd_instance: The instance object from which the attribute is to be retrieved.
192 @type ctd_instance: subclass of L{pyxb.binding.basis.complexTypeDefinition}
193 @return: C{(provided, value)} where C{provided} is a C{bool} and
194 C{value} is C{None} or an instance of the attribute's datatype.
195
196 """
197 return getattr(ctd_instance, self.__key, (False, None))
198
201
202 - def value (self, ctd_instance):
207
208 - def __setValue (self, ctd_instance, new_value, provided):
209 return setattr(ctd_instance, self.__key, (provided, new_value))
210
211 - def reset (self, ctd_instance):
212 """Set the value of the attribute in the given instance to be its
213 default value, and mark that it has not been provided."""
214 self.__setValue(ctd_instance, self.__defaultValue, False)
215
223
251
252 - def set (self, ctd_instance, new_value):
253 """Set the value of the attribute.
254
255 This validates the value against the data type, creating a new instance if necessary.
256
257 @param ctd_instance: The binding instance for which the attribute
258 value is to be set
259 @type ctd_instance: subclass of L{pyxb.binding.basis.complexTypeDefinition}
260 @param new_value: The value for the attribute
261 @type new_value: Any value that is permitted as the input parameter to
262 the C{Factory} method of the attribute's datatype.
263 """
264 provided = True
265 from_xml = False
266 assert not isinstance(new_value, xml.dom.Node)
267 if new_value is None:
268 if self.__required:
269 raise pyxb.MissingAttributeError(type(ctd_instance), self.__name, ctd_instance)
270 provided = False
271 if self.__prohibited:
272 raise pyxb.ProhibitedAttributeError(type(ctd_instance), self.__name, ctd_instance)
273 if (new_value is not None) and (not isinstance(new_value, self.__dataType)):
274 new_value = self.__dataType.Factory(new_value, _from_xml=from_xml)
275 if self.__fixed and (new_value != self.__defaultValue):
276 raise pyxb.AttributeChangeError(type(ctd_instance), self.__name, ctd_instance)
277 self.__setValue(ctd_instance, new_value, provided)
278 return new_value
279
280 - def _description (self, name_only=False, user_documentation=True):
281 if name_only:
282 return unicode(self.__name)
283 assert issubclass(self.__dataType, basis._TypeBinding_mixin)
284 desc = [ unicode(self.__id), ': ', unicode(self.__name), ' (', self.__dataType._description(name_only=True, user_documentation=False), '), ' ]
285 if self.__required:
286 desc.append('required')
287 elif self.__prohibited:
288 desc.append('prohibited')
289 else:
290 desc.append('optional')
291 if self.__defaultValue is not None:
292 desc.append(', ')
293 if self.__fixed:
294 desc.append('fixed')
295 else:
296 desc.append('default')
297 desc.extend(['=', self.__unicodeDefault ])
298 return ''.join(desc)
299
301 """State for a L{pyxb.utils.fac.Automaton} monitoring content for an
302 incrementally constructed complex type binding instance.
303
304 @warning: This is not an implementation of
305 L{pyxb.utils.fac.Configuration_ABC} because we need the L{step} function
306 to return a different type of value."""
307
308
309 __instance = None
310
311
312
313
314
315
316 __cfg = None
317
318
319
320
321
322
323
324 __multi = None
325
328
330 """Reset the automaton to its initial state.
331
332 Subsequent transitions are expected based on candidate content to be
333 supplied through the L{step} method."""
334 self.__cfg = self.__instance._Automaton.newConfiguration()
335 self.__multi = None
336
338 """Return the number of pending configurations.
339
340 The automaton is deterministic if exactly one configuration is
341 available."""
342 if self.__cfg is not None:
343 assert self.__multi is None
344 return 1
345 return len(self.__multi)
346
347 - def step (self, value, element_decl):
348 """Attempt a transition from the current state.
349
350 @param value: the content to be supplied. For success the value must
351 be consistent with the recorded symbol (element or wildcard
352 declaration) for a transition from the current automaton state.
353
354 @param element_decl: optional
355 L{pyxb.binding.content.ElementDeclaration} that is the preferred
356 symbol for the transition.
357
358 @return: the cardinal number of successful transitions from the
359 current configuration based on the parameters."""
360
361 sym = (value, element_decl)
362
363
364
365 new_multi = []
366 if self.__multi is None:
367 multi = [ (self.__cfg, ()) ]
368 else:
369 multi = self.__multi[:]
370
371
372 for (cfg, pending) in multi:
373 cand = cfg.candidateTransitions(sym)
374 for transition in cand:
375 clone_map = {}
376 ccfg = cfg.clone(clone_map)
377 new_multi.append( (transition.apply(ccfg, clone_map), pending+(transition.consumedSymbol().consumingClosure(sym),)) )
378 rv = len(new_multi)
379 if 0 == rv:
380
381 return 0
382 if 1 == rv:
383
384
385 self.__multi = None
386 (self.__cfg, actions) = new_multi[0]
387 for fn in actions:
388 fn(self.__instance)
389 else:
390
391 self.__cfg = None
392 self.__multi = new_multi
393 return rv
394
396 """Resolve any non-determinism in the automaton state.
397
398 If the automaton has reached a single configuration (was
399 deterministic), this does nothing.
400
401 If multiple candidate configurations are available, the best one is
402 selected and applied, updating the binding instance with the pending
403 content.
404
405 "Best" in this case is determined by optionally eliminating
406 configurations that are not accepting, then selecting the path where
407 the initial transition sorts highest using the binding sort key (based
408 on position in the original schema).
409
410 @keyword prefer_accepting: eliminate non-accepting paths if any
411 accepting path is present."""
412 if self.__multi is None:
413 return
414 assert self.__cfg is None
415 multi = self.__multi
416 if prefer_accepting:
417 multi = filter(lambda _ts: _ts[0].isAccepting(), self.__multi)
418 if 0 == len(multi):
419 multi = self.__multi
420
421
422
423 assert 0 < len(multi)
424 if 1 < len(multi):
425 desc = self.__instance._ExpandedName
426 if desc is None:
427 desc = type(self.__instance)
428 _log.warning('Multiple accepting paths for %s', desc)
429 '''
430 for (cfg, actions) in multi:
431 foo = type(self.__instance)()
432 for fn in actions:
433 fn(foo)
434 print '1: %s ; 2 : %s ; wc: %s' % (foo.first, foo.second, foo.wildcardElements())
435 '''
436 (self.__cfg, actions) = multi[0]
437 self.__multi = None
438 for fn in actions:
439 fn(self.__instance)
440
442 """Return the sequence of acceptable symbols at this state.
443
444 The list comprises the L{pyxb.binding.content.ElementUse} and
445 L{pyxb.binding.content.WildcardUse} instances that are used to
446 validate proposed symbols, in preferred order."""
447 rv = []
448 seen = set()
449 multi = self.__multi
450 if multi is None:
451 multi = [ self.__cfg]
452 for cfg in multi:
453 for u in cfg.acceptableSymbols():
454 if not (u in seen):
455 rv.append(u)
456 seen.add(u)
457 return rv
458
469
470 - def _diagnoseIncompleteContent (self, symbols, symbol_set):
471 """Check for incomplete content.
472
473 @raises pyxb.IncompleteElementContentError: if a non-accepting state is found
474 @return: the topmost configuration (if accepting)
475 """
476
477
478 cfg = self.__cfg
479 while cfg.isAccepting() and (cfg.superConfiguration is not None):
480 cfg = cfg.superConfiguration
481 if not cfg.isAccepting():
482 _log.warning('Incomplete content, expect %s' % (' or '.join(map(str, cfg.acceptableSymbols()))))
483 raise pyxb.IncompleteElementContentError(self.__instance, cfg, symbols, symbol_set)
484 return cfg
485
487 """Generate the exception explaining why the content is incomplete."""
488 return self._diagnoseIncompleteContent(None, None)
489
490 __preferredSequenceIndex = 0
491 __preferredPendingSymbol = None
492 __pendingNonElementContent = None
493
505
516
548
550 """Implement L{pyxb.binding.basis.complexTypeDefinition._validatedChildren}.
551
552 Go there for the interface.
553 """
554
555
556
557 self.reset()
558 cfg = self.__cfg
559
560
561 symbols = []
562
563
564 instance = self.__instance
565 vc = instance._validationConfig
566
567
568
569
570 symbol_set = instance._symbolSet()
571
572
573 preferred_sequence = self.__resetPreferredSequence(instance)
574
575
576
577
578
579 nec = self.__pendingNonElementContent
580
581 psym = None
582 while symbol_set:
583
584
585 selected_xit = None
586 psym = None
587 if preferred_sequence is not None:
588 (preferred_sequence, psym) = self.__processPreferredSequence(preferred_sequence, symbol_set, vc)
589 candidates = cfg.candidateTransitions(psym)
590 for xit in candidates:
591 csym = xit.consumedSymbol()
592 if isinstance(csym, ElementUse):
593 ed = csym.elementDeclaration()
594 elif isinstance(csym, WildcardUse):
595 ed = None
596 else:
597 assert False
598
599 matches = symbol_set.get(ed)
600 if matches is None:
601 continue
602 if not csym.match((matches[0], ed)):
603 continue
604
605
606
607 value = matches.pop(0)
608 if (psym is not None) and (nec is not None):
609 symbols.extend(nec)
610 nec[:] = []
611 symbols.append(basis.ElementContent(csym.matchValue( (value, ed) ), ed))
612 selected_xit = xit
613 if 0 == len(matches):
614 del symbol_set[ed]
615 break
616 if selected_xit is None:
617 if psym is not None:
618
619 _log.info('invalid %s in content', psym)
620 if vc.IGNORE_ONCE == vc.invalidElementInContent:
621 continue
622 if vc.GIVE_UP == vc.invalidElementInContent:
623 preferred_sequence = self.__discardPreferredSequence(preferred_sequence)
624 continue
625 raise pyxb.InvalidPreferredElementContentError(self.__instance, cfg, symbols, symbol_set, psym)
626 break
627 cfg = selected_xit.apply(cfg)
628 psym_wait = False
629 cfg = self._diagnoseIncompleteContent(symbols, symbol_set)
630 if symbol_set:
631 raise pyxb.UnprocessedElementContentError(self.__instance, cfg, symbols, symbol_set)
632
633
634
635 while preferred_sequence is not None:
636 (preferred_sequence, psym) = self.__processPreferredSequence(preferred_sequence, symbol_set, vc)
637 if psym is not None:
638 if not (vc.orphanElementInContent in ( vc.IGNORE_ONCE, vc.GIVE_UP )):
639 raise pyxb.OrphanElementContentError(self.__instance, pxym.value)
640 if nec is not None:
641 symbols.extend(nec)
642 return symbols
643
644 -class _FACSymbol (pyxb.utils.fac.SymbolMatch_mixin):
645 """Base class for L{pyxb.utils.fac.Symbol} instances associated with PyXB content models.
646
647 This holds the location in the schema of the L{ElementUse} or
648 L{WildcardUse} and documents the methods expected of its children."""
649
650 __xsdLocation = None
651
654
656 """Return the value accepted by L{match} for this symbol.
657
658 A match for an element declaration might have resulted in a type
659 change for the value (converting it to an acceptable type). There is
660 no safe place to cache the compatible value calculated in the match
661 while other candidates are being considered, so we need to
662 re-calculate it if the transition is taken.
663
664 If the match could not have changed the value, the value from the
665 symbol may be returned immediately."""
666 raise NotImplementedError('%s._matchValue' % (type(self).__name__,))
667
669 """Create a closure that will apply the value from C{sym} to a to-be-supplied instance.
670
671 This is necessary for non-deterministic automata, where we can't store
672 the value into the instance field until we know that the transition
673 will be taken:
674
675 @return: A closure that takes a L{complexTypeDefinition} instance and
676 stores the value from invoking L{matchValue} on C{sym} into the
677 appropriate slot."""
678 raise NotImplementedError('%s._consumingClosure' % (type(self).__name__,))
679
681 """@param xsd_location: the L{location<pyxb.utils.utility.Location>} of the element use or wildcard declaration."""
682 self.__xsdLocation = xsd_location
683 super(_FACSymbol, self).__init__()
684
686 """Information about a schema element declaration reference.
687
688 This is used by the FAC content model to identify the location
689 within a schema at which an element use appears. The L{ElementDeclaration}
690 is not sufficient since multiple uses in various schema, possibly in
691 different namespaces, may refer to the same declaration but be independent
692 uses.
693 """
694
695 __elementDeclaration = None
696
698 """Return the L{element declaration<pyxb.binding.content.ElementDeclaration>} associated with the use."""
699 return self.__elementDeclaration
700
702 """Return the L{element binding<pyxb.binding.content.ElementDeclaration.elementBinding>} associated with the use.
703
704 Equivalent to L{elementDeclaration}().L{elementBinding()<pyxb.binding.content.ElementDeclaration.elementBinding>}."""
705 return self.__elementDeclaration.elementBinding()
706
708 """Return the element type.
709
710 Equivalent to L{elementDeclaration}().L{elementBinding()<pyxb.binding.content.ElementDeclaration.elementBinding>}.L{typeDefinition()<pyxb.binding.basis.element.typeDefinition>}."""
711 return self.__elementDeclaration.elementBinding().typeDefinition()
712
713 - def __init__ (self, element_declaration, xsd_location):
716
722
727
728 - def match (self, symbol):
729 """Satisfy L{pyxb.utils.fac.SymbolMatch_mixin}.
730
731 Determine whether the proposed content encapsulated in C{symbol} is
732 compatible with the element declaration. If so, the accepted value is
733 cached internally and return C{True}; otherwise return C{False}.
734
735 @param symbol: a pair C{(value, element_decl)}.
736 L{pyxb.binding.content.ElementDeclaration._matches} is used to
737 determine whether the proposed content is compatible with this element
738 declaration."""
739 (value, element_decl) = symbol
740
741
742
743 (rv, value) = self.__elementDeclaration._matches(value, element_decl)
744 return rv
745
748
750 """Information about a schema wildcard element.
751
752 This is functionally parallel to L{ElementUse}, but references a
753 L{Wildcard} that is unique to this instance. That L{Wildcard} is not
754 incorporated into this class is an artifact of the evolution of PyXB."""
755
756 __wildcardDeclaration = None
757
760
764
766 """Create a closure that will apply the value accepted by L{match} to a to-be-supplied instance."""
767 return lambda _inst,_av=self.matchValue(sym): _inst._appendWildcardElement(_av)
768
769 - def match (self, symbol):
770 """Satisfy L{pyxb.utils.fac.SymbolMatch_mixin}.
771
772 Determine whether the proposed content encapsulated in C{symbol} is
773 compatible with the wildcard declaration. If so, the accepted value
774 is cached internally and return C{True}; otherwise return C{False}.
775
776 @param symbol: a pair C{(value, element_decl)}.
777 L{pyxb.binding.content.Wildcard.matches} is used to determine whether
778 the proposed content is compatible with this wildcard.
779 """
780 (value, element_decl) = symbol
781 return self.__wildcardDeclaration.matches(None, value)
782
783 - def __init__ (self, wildcard_declaration, xsd_location):
786
789
790 import collections
791
792
793
794
795
796
798 """Helper for element content that supports multiple occurences.
799
800 This is an adapter for Python list. Any operation that can mutate an item
801 in the list ensures the stored value is compatible with the element for
802 which the list holds values."""
803
804 __list = None
805 __elementBinding = None
806
808 element_binding = kw.pop('element_binding', None)
809 if not isinstance(element_binding, basis.element):
810 raise ValueError()
811 self.__elementBinding = element_binding
812 self.__list = []
813 self.extend(args)
814
817
820
823
829
832
835
838
841
842
845
848
851
852 - def index (self, x, i=0, j=-1):
854
857
858 - def pop (self, i=-1):
860
863
866
867 - def sort (self, cmp=None, key=None, reverse=False):
869
872
878 return not (other == self)
879
885 return (other <= self)
886
892 return (other < self)
893
895 """Aggregate the information relevant to an element of a complex type.
896
897 This includes the L{original tag name<name>}, the spelling of L{the
898 corresponding object in Python <id>}, an L{indicator<isPlural>} of whether
899 multiple instances might be associated with the field, and other relevant
900 information.
901 """
902
904 """The L{location<pyxb.utils.utility.Location>} in the schema where the
905 element was declared.
906
907 Note that this is not necessarily the same location as its use."""
908 return self.__xsdLocation
909 __xsdLocation = None
910
912 """The expanded name of the element.
913
914 @rtype: L{pyxb.namespace.ExpandedName}
915 """
916 return self.__name
917 __name = None
918
920 """The string name of the binding class field used to hold the element
921 values.
922
923 This is the user-visible name, and excepting disambiguation will be
924 equal to the local name of the element."""
925 return self.__id
926 __id = None
927
928
929
930
931 __key = None
932
934 """The L{basis.element} instance identifying the information
935 associated with the element declaration.
936 """
937 return self.__elementBinding
944 __elementBinding = None
945
947 """True iff the content model indicates that more than one element
948 can legitimately belong to this use.
949
950 This includes elements in particles with maxOccurs greater than one,
951 and when multiple elements with the same NCName are declared in the
952 same type.
953 """
954 return self.__isPlural
955 __isPlural = False
956
957 - def __init__ (self, name, id, key, is_plural, location, element_binding=None):
958 """Create an ElementDeclaration instance.
959
960 @param name: The name by which the element is referenced in the XML
961 @type name: L{pyxb.namespace.ExpandedName}
962
963 @param id: The Python name for the element within the containing
964 L{pyxb.basis.binding.complexTypeDefinition}. This is a public
965 identifier, albeit modified to be unique, and is usually used as the
966 name of the element's inspector method or property.
967 @type id: C{str}
968
969 @param key: The string used to store the element
970 value in the dictionary of the containing
971 L{pyxb.basis.binding.complexTypeDefinition}. This is mangled so
972 that it is unique among and is treated as a Python private member.
973 @type key: C{str}
974
975 @param is_plural: If C{True}, documents for the corresponding type may
976 have multiple instances of this element. As a consequence, the value
977 of the element will be a list. If C{False}, the value will be C{None}
978 if the element is absent, and a reference to an instance of the type
979 identified by L{pyxb.binding.basis.element.typeDefinition} if present.
980 @type is_plural: C{bool}
981
982 @param element_binding: Reference to the class that serves as the
983 binding for the element.
984 """
985 self.__name = name
986 self.__id = id
987 self.__key = key
988 self.__isPlural = is_plural
989 self.__elementBinding = element_binding
990 super(ElementDeclaration, self).__init__()
991
993 """Return the default value for this element.
994
995 For plural values, this is an empty collection. For non-plural
996 values, it is C{None} unless the element has a default value, in which
997 case it is that value.
998 """
999 if self.isPlural():
1000 return _PluralBinding(element_binding=self.__elementBinding)
1001 return self.__elementBinding.defaultValue()
1002
1003 - def value (self, ctd_instance):
1004 """Return the value for this use within the given instance."""
1005 return getattr(ctd_instance, self.__key, self.defaultValue())
1006
1007 - def reset (self, ctd_instance):
1008 """Set the value for this use in the given element to its default."""
1009 setattr(ctd_instance, self.__key, self.defaultValue())
1010 return self
1011
1012 - def set (self, ctd_instance, value):
1024
1026 """Invoke either L{set} or L{append}, depending on whether the element
1027 use is plural."""
1028 if self.isPlural():
1029 return self.append(ctd_instance, value)
1030 return self.set(ctd_instance, value)
1031
1032 - def append (self, ctd_instance, value):
1046
1047 - def toDOM (self, dom_support, parent, value):
1048 """Convert the given value to DOM as an instance of this element.
1049
1050 @param dom_support: Helper for managing DOM properties
1051 @type dom_support: L{pyxb.utils.domutils.BindingDOMSupport}
1052 @param parent: The DOM node within which this element should be generated.
1053 @type parent: C{xml.dom.Element}
1054 @param value: The content for this element. May be text (if the
1055 element allows mixed content), or an instance of
1056 L{basis._TypeBinding_mixin}.
1057
1058 @raise pyxb.AbstractElementError: the binding to be used is abstract
1059 """
1060 if isinstance(value, basis._TypeBinding_mixin):
1061 element_binding = self.__elementBinding
1062 if value._substitutesFor(element_binding):
1063 element_binding = value._element()
1064 assert element_binding is not None
1065 if element_binding.abstract():
1066 raise pyxb.AbstractElementError(self, value)
1067 element = dom_support.createChildElement(element_binding.name(), parent)
1068 elt_type = element_binding.typeDefinition()
1069 val_type = type(value)
1070 if isinstance(value, basis.complexTypeDefinition):
1071 assert isinstance(value, elt_type)
1072 else:
1073 if isinstance(value, basis.STD_union) and isinstance(value, elt_type._MemberTypes):
1074 val_type = elt_type
1075 if dom_support.requireXSIType() or elt_type._RequireXSIType(val_type):
1076 val_type_qname = value._ExpandedName.localName()
1077 tns_prefix = dom_support.namespacePrefix(value._ExpandedName.namespace())
1078 if tns_prefix is not None:
1079 val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
1080 dom_support.addAttribute(element, pyxb.namespace.XMLSchema_instance.createExpandedName('type'), val_type_qname)
1081 value._toDOM_csc(dom_support, element)
1082 elif isinstance(value, (str, unicode)):
1083 element = dom_support.createChildElement(self.name(), parent)
1084 element.appendChild(dom_support.document().createTextNode(value))
1085 else:
1086 raise pyxb.LogicError('toDOM with unrecognized value type %s: %s' % (type(value), value))
1087
1088 - def _description (self, name_only=False, user_documentation=True):
1096
1097 - def _matches (self, value, element_decl):
1120
1122 return 'ED.%s@%x' % (self.__name, id(self))
1123
1124
1126 """Placeholder for wildcard objects."""
1127
1128 NC_any = '##any'
1129 NC_not = '##other'
1130 NC_targetNamespace = '##targetNamespace'
1131 NC_local = '##local'
1132
1133 __namespaceConstraint = None
1135 """A constraint on the namespace for the wildcard.
1136
1137 Valid values are:
1138
1139 - L{Wildcard.NC_any}
1140 - A tuple ( L{Wildcard.NC_not}, a L{namespace<pyxb.namespace.Namespace>} instance )
1141 - set(of L{namespace<pyxb.namespace.Namespace>} instances)
1142
1143 Namespaces are represented by their URIs. Absence is
1144 represented by C{None}, both in the "not" pair and in the set.
1145 """
1146 return self.__namespaceConstraint
1147
1148 PC_skip = 'skip'
1149 """No namespace constraint is applied to the wildcard."""
1150
1151 PC_lax = 'lax'
1152 """Validate against available uniquely determined declaration."""
1153
1154 PC_strict = 'strict'
1155 """Validate against declaration or xsi:type, which must be available."""
1156
1157 __processContents = None
1158 """One of L{PC_skip}, L{PC_lax}, L{PC_strict}."""
1159 - def processContents (self):
1160 """Indicate how this wildcard's contents should be processed."""
1161 return self.__processContents
1162
1164 if nsv is None:
1165 return None
1166 if isinstance(nsv, basestring):
1167 nsv = pyxb.namespace.NamespaceForURI(nsv, create_if_missing=True)
1168 assert isinstance(nsv, pyxb.namespace.Namespace), 'unexpected non-namespace %s' % (nsv,)
1169 return nsv
1170
1185
1186 - def matches (self, instance, value):
1218
1219
1220
1221
1222