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