Package xmlschema_acue ::
Package validators ::
Module simple_types
1
2
3
4
5
6
7
8
9
10
11 """
12 This module contains classes for XML Schema simple data types.
13 """
14 from __future__ import unicode_literals
15 from decimal import DecimalException
16
17 from xmlschema_acue.compat import string_base_type, unicode_type
18 from xmlschema_acue.etree import etree_element
19 from xmlschema_acue.exceptions import XMLSchemaTypeError, XMLSchemaValueError
20 from xmlschema_acue.qnames import (
21 XSD_ANY_TYPE, XSD_SIMPLE_TYPE, XSD_ANY_ATOMIC_TYPE, XSD_ATTRIBUTE, XSD_ATTRIBUTE_GROUP,
22 XSD_ANY_ATTRIBUTE, XSD_PATTERN, XSD_MIN_INCLUSIVE, XSD_MIN_EXCLUSIVE, XSD_MAX_INCLUSIVE,
23 XSD_MAX_EXCLUSIVE, XSD_LENGTH, XSD_MIN_LENGTH, XSD_MAX_LENGTH, XSD_WHITE_SPACE, XSD_LIST,
24 XSD_ANY_SIMPLE_TYPE, XSD_UNION, XSD_RESTRICTION, XSD_ANNOTATION, XSD_ASSERTION, XSD_ID,
25 XSD_FRACTION_DIGITS, XSD_TOTAL_DIGITS
26 )
27 from xmlschema_acue.helpers import get_qname, local_name, get_xsd_derivation_attribute
28
29 from xmlschema_acue.validators.exceptions import XMLSchemaValidationError, XMLSchemaEncodeError, XMLSchemaDecodeError, XMLSchemaParseError
30 from xmlschema_acue.validators.xsdbase import XsdAnnotation, XsdType, ValidationMixin
31 from xmlschema_acue.validators.facets import XsdFacet, XsdWhiteSpaceFacet, XSD_10_FACETS_BUILDERS, XSD_11_FACETS_BUILDERS, XSD_10_FACETS, \
32 XSD_11_FACETS, XSD_10_LIST_FACETS, XSD_11_LIST_FACETS, XSD_10_UNION_FACETS, XSD_11_UNION_FACETS, MULTIPLE_FACETS
36 try:
37 name = get_qname(schema.target_namespace, elem.attrib['name'])
38 except KeyError:
39 name = None
40 else:
41 if name == XSD_ANY_SIMPLE_TYPE:
42 return
43
44 annotation = None
45 try:
46 child = elem[0]
47 except IndexError:
48 return schema.maps.types[XSD_ANY_SIMPLE_TYPE]
49 else:
50 if child.tag == XSD_ANNOTATION:
51 try:
52 child = elem[1]
53 annotation = XsdAnnotation(elem[0], schema, child)
54 except IndexError:
55 return schema.maps.types[XSD_ANY_SIMPLE_TYPE]
56
57 if child.tag == XSD_RESTRICTION:
58 result = schema.BUILDERS.restriction_class(child, schema, parent, name=name)
59 elif child.tag == XSD_LIST:
60 result = XsdList(child, schema, parent, name=name)
61 elif child.tag == XSD_UNION:
62 result = schema.BUILDERS.union_class(child, schema, parent, name=name)
63 else:
64 result = schema.maps.types[XSD_ANY_SIMPLE_TYPE]
65
66 if annotation is not None:
67 result.annotation = annotation
68
69 if 'final' in elem.attrib:
70 try:
71 result._final = get_xsd_derivation_attribute(elem, 'final')
72 except ValueError as err:
73 result.parse_error(err, elem)
74
75 return result
76
79 """
80 Base class for simpleTypes definitions. Generally used only for
81 instances of xs:anySimpleType.
82
83 <simpleType
84 final = (#all | List of (list | union | restriction | extension))
85 id = ID
86 name = NCName
87 {any attributes with non-schema namespace . . .}>
88 Content: (annotation?, (restriction | list | union))
89 </simpleType>
90 """
91 _special_types = {XSD_ANY_TYPE, XSD_ANY_SIMPLE_TYPE}
92 _admitted_tags = {XSD_SIMPLE_TYPE}
93
94 min_length = None
95 max_length = None
96 white_space = None
97 patterns = None
98 validators = ()
99
100 - def __init__(self, elem, schema, parent, name=None, facets=None):
104
133
135 if facets and self.base_type is not None:
136 if self.base_type.is_simple():
137 if self.base_type.name == XSD_ANY_SIMPLE_TYPE:
138 self.parse_error("facets not allowed for a direct derivation of xs:anySimpleType")
139 elif self.base_type.has_simple_content():
140 if self.base_type.content_type.name == XSD_ANY_SIMPLE_TYPE:
141 self.parse_error("facets not allowed for a direct content derivation of xs:anySimpleType")
142
143
144 if any(k not in self.admitted_facets for k in facets if k is not None):
145 reason = "one or more facets are not applicable, admitted set is %r:"
146 self.parse_error(reason % {local_name(e) for e in self.admitted_facets if e})
147
148
149 base_type = {t.base_type for t in facets.values() if isinstance(t, XsdFacet)}
150 if len(base_type) > 1:
151 self.parse_error("facet group must have the same base_type: %r" % base_type)
152 base_type = base_type.pop() if base_type else None
153
154
155 length = getattr(facets.get(XSD_LENGTH), 'value', None)
156 min_length = getattr(facets.get(XSD_MIN_LENGTH), 'value', None)
157 max_length = getattr(facets.get(XSD_MAX_LENGTH), 'value', None)
158 if length is not None:
159 if length < 0:
160 self.parse_error("'length' value must be non negative integer")
161 if min_length is not None:
162 if min_length > length:
163 self.parse_error("'minLength' value must be less or equal to 'length'")
164 min_length_facet = base_type.get_facet(XSD_MIN_LENGTH)
165 length_facet = base_type.get_facet(XSD_LENGTH)
166 if min_length_facet is None or \
167 (length_facet is not None and length_facet.base_type == min_length_facet.base_type):
168 self.parse_error("cannot specify both 'length' and 'minLength'")
169 if max_length is not None:
170 if max_length < length:
171 self.parse_error("'maxLength' value must be greater or equal to 'length'")
172 max_length_facet = base_type.get_facet(XSD_MAX_LENGTH)
173 length_facet = base_type.get_facet(XSD_LENGTH)
174 if max_length_facet is None or \
175 (length_facet is not None and length_facet.base_type == max_length_facet.base_type):
176 self.parse_error("cannot specify both 'length' and 'maxLength'")
177 min_length = max_length = length
178 elif min_length is not None or max_length is not None:
179 min_length_facet = base_type.get_facet(XSD_MIN_LENGTH)
180 max_length_facet = base_type.get_facet(XSD_MAX_LENGTH)
181 if min_length is not None:
182 if min_length < 0:
183 self.parse_error("'minLength' value must be non negative integer")
184 if max_length is not None and max_length < min_length:
185 self.parse_error("'maxLength' value is lesser than 'minLength'")
186 if min_length_facet is not None and min_length_facet.value > min_length:
187 self.parse_error("'minLength' has a lesser value than parent")
188 if max_length_facet is not None and min_length > max_length_facet.value:
189 self.parse_error("'minLength' has a greater value than parent 'maxLength'")
190
191 if max_length is not None:
192 if max_length < 0:
193 self.parse_error("'maxLength' value mu st be non negative integer")
194 if min_length_facet is not None and min_length_facet.value > max_length:
195 self.parse_error("'maxLength' has a lesser value than parent 'minLength'")
196 if max_length_facet is not None and max_length > max_length_facet.value:
197 self.parse_error("'maxLength' has a greater value than parent")
198
199
200 min_inclusive = getattr(facets.get(XSD_MIN_INCLUSIVE), 'value', None)
201 min_exclusive = getattr(facets.get(XSD_MIN_EXCLUSIVE), 'value', None)
202 max_inclusive = getattr(facets.get(XSD_MAX_INCLUSIVE), 'value', None)
203 max_exclusive = getattr(facets.get(XSD_MAX_EXCLUSIVE), 'value', None)
204
205 if min_inclusive is not None:
206 if min_exclusive is not None:
207 self.parse_error("cannot specify both 'minInclusive' and 'minExclusive")
208 if max_inclusive is not None and min_inclusive > max_inclusive:
209 self.parse_error("'minInclusive' must be less or equal to 'maxInclusive'")
210 elif max_exclusive is not None and min_inclusive >= max_exclusive:
211 self.parse_error("'minInclusive' must be lesser than 'maxExclusive'")
212
213 elif min_exclusive is not None:
214 if max_inclusive is not None and min_exclusive >= max_inclusive:
215 self.parse_error("'minExclusive' must be lesser than 'maxInclusive'")
216 elif max_exclusive is not None and min_exclusive > max_exclusive:
217 self.parse_error("'minExclusive' must be less or equal to 'maxExclusive'")
218
219 if max_inclusive is not None and max_exclusive is not None:
220 self.parse_error("cannot specify both 'maxInclusive' and 'maxExclusive")
221
222
223 if XSD_TOTAL_DIGITS in facets:
224 if XSD_FRACTION_DIGITS in facets and facets[XSD_TOTAL_DIGITS].value < facets[XSD_FRACTION_DIGITS].value:
225 self.parse_error("fractionDigits facet value cannot be lesser than the value of totalDigits")
226 total_digits = base_type.get_facet(XSD_TOTAL_DIGITS)
227 if total_digits is not None and total_digits.value < facets[XSD_TOTAL_DIGITS].value:
228 self.parse_error("totalDigits facet value cannot be greater than those on the base type")
229
230 self.min_length = min_length
231 self.max_length = max_length
232
233 @property
235 min_exclusive_facet = self.get_facet(XSD_MIN_EXCLUSIVE)
236 if min_exclusive_facet is None:
237 return getattr(self.get_facet(XSD_MIN_INCLUSIVE), 'value', None)
238
239 min_inclusive_facet = self.get_facet(XSD_MIN_INCLUSIVE)
240 if min_inclusive_facet is None or min_inclusive_facet.value <= min_exclusive_facet.value:
241 return min_exclusive_facet.value
242 else:
243 return min_inclusive_facet.value
244
245 @property
247 max_exclusive_facet = self.get_facet(XSD_MAX_EXCLUSIVE)
248 if max_exclusive_facet is None:
249 return getattr(self.get_facet(XSD_MAX_INCLUSIVE), 'value', None)
250
251 max_inclusive_facet = self.get_facet(XSD_MAX_INCLUSIVE)
252 if max_inclusive_facet is None or max_inclusive_facet.value >= max_exclusive_facet.value:
253 return max_exclusive_facet.value
254 else:
255 return max_inclusive_facet.value
256
257 @property
260
261 @property
264
265 @staticmethod
268
269 @staticmethod
272
275
278
281
284
287
309
311 """
312 Normalize and restrict value-space with pre-lexical and lexical facets.
313 The normalized string is returned. Returns the argument if it isn't a string.
314
315 :param text: text string encoded value.
316 :return: normalized string.
317 """
318 if isinstance(text, bytes):
319 text = text.decode('utf-8')
320 elif not isinstance(text, string_base_type):
321 raise XMLSchemaValueError('argument is not a string: %r' % text)
322
323 if self.white_space == 'replace':
324 return self._REGEX_SPACE.sub(' ', text)
325 elif self.white_space == 'collapse':
326 return self._REGEX_SPACES.sub(' ', text).strip()
327 else:
328 return text
329
330 - def iter_decode(self, obj, validation='lax', **kwargs):
331 if isinstance(obj, (string_base_type, bytes)):
332 obj = self.normalize(obj)
333
334 if validation != 'skip':
335 if self.patterns is not None:
336 for error in self.patterns(obj):
337 if validation == 'strict':
338 raise error
339 yield error
340
341 for validator in self.validators:
342 for error in validator(obj):
343 if validation == 'strict':
344 raise error
345 yield error
346 yield obj
347
348 - def iter_encode(self, obj, validation='lax', **kwargs):
349 if isinstance(obj, (string_base_type, bytes)):
350 obj = self.normalize(obj)
351 elif validation != 'skip':
352 yield self.encode_error(validation, obj, unicode_type)
353
354 if validation != 'skip':
355 if self.patterns is not None:
356 for error in self.patterns(obj):
357 if validation == 'strict':
358 raise error
359 yield error
360
361 for validator in self.validators:
362 for error in validator(obj):
363 if validation == 'strict':
364 raise error
365 yield error
366
367 yield obj
368
371
458
461 """
462 Class for defining XML Schema built-in simpleType atomic datatypes. An instance
463 contains a Python's type transformation and a list of validator functions. The
464 'base_type' is not used for validation, but only for reference to the XML Schema
465 restriction hierarchy.
466
467 Type conversion methods:
468 - to_python(value): Decoding from XML
469 - from_python(value): Encoding to XML
470 """
471 - def __init__(self, elem, schema, name, python_type, base_type=None, admitted_facets=None, facets=None,
472 to_python=None, from_python=None):
473 """
474 :param name: the XSD type's qualified name.
475 :param python_type: the correspondent Python's type. If a tuple or list of types \
476 is provided uses the first and consider the others as compatible types.
477 :param base_type: the reference base type, None if it's a primitive type.
478 :param admitted_facets: admitted facets tags for type (required for primitive types).
479 :param facets: optional facets validators.
480 :param to_python: optional decode function.
481 :param from_python: optional encode function.
482 """
483 if isinstance(python_type, (tuple, list)):
484 self.instance_types, python_type = python_type, python_type[0]
485 else:
486 self.instance_types = python_type
487 if not callable(python_type):
488 raise XMLSchemaTypeError("%r object is not callable" % python_type.__class__)
489
490 if base_type is None and not admitted_facets:
491 raise XMLSchemaValueError("argument 'admitted_facets' must be a not empty set of a primitive type")
492 self._admitted_facets = admitted_facets
493
494 super(XsdAtomicBuiltin, self).__init__(elem, schema, None, name, facets, base_type)
495 self.python_type = python_type
496 self.to_python = to_python or python_type
497 self.from_python = from_python or unicode_type
498
500 return '%s(name=%r)' % (self.__class__.__name__, self.prefixed_name)
501
504
505 @property
508
509 - def iter_decode(self, obj, validation='lax', **kwargs):
510 if isinstance(obj, (string_base_type, bytes)):
511 obj = self.normalize(obj)
512 elif validation != 'skip' and obj is not None and not isinstance(obj, self.instance_types):
513 yield self.decode_error(validation, obj, self.to_python,
514 reason="value is not an instance of {!r}".format(self.instance_types))
515
516 if 'id_map' in kwargs:
517 if self.name == XSD_ID:
518 kwargs['id_map'][obj] += 1
519
520 if validation == 'skip':
521 try:
522 yield self.to_python(obj)
523 except (ValueError, DecimalException):
524 yield unicode_type(obj)
525 return
526
527 if self.patterns is not None:
528 for error in self.patterns(obj):
529 if validation == 'strict':
530 raise error
531 yield error
532
533 try:
534 result = self.to_python(obj)
535 except (ValueError, DecimalException) as err:
536 yield self.decode_error(validation, obj, self.to_python, reason=str(err))
537 yield None
538 return
539
540 for validator in self.validators:
541 for error in validator(result):
542 if validation == 'strict':
543 raise error
544 yield error
545
546 yield result
547
548 - def iter_encode(self, obj, validation='lax', **kwargs):
549 if isinstance(obj, (string_base_type, bytes)):
550 obj = self.normalize(obj)
551
552 if validation == 'skip':
553 try:
554 yield self.from_python(obj)
555 except ValueError:
556 yield unicode_type(obj)
557 return
558
559 elif isinstance(obj, bool):
560 types_ = self.instance_types
561 if types_ is not bool or (isinstance(types_, tuple) and bool in types_):
562 reason = "boolean value {!r} requires a {!r} decoder.".format(obj, bool)
563 yield self.encode_error(validation, obj, self.from_python, reason)
564 obj = self.python_type(obj)
565
566 elif not isinstance(obj, self.instance_types):
567 reason = "{!r} is not an instance of {!r}.".format(obj, self.instance_types)
568 yield self.encode_error(validation, obj, self.from_python, reason)
569 try:
570 value = self.python_type(obj)
571 if value != obj:
572 raise ValueError()
573 else:
574 obj = value
575 except ValueError:
576 yield self.encode_error(validation, obj, self.from_python)
577 yield None
578 return
579
580 for validator in self.validators:
581 for error in validator(obj):
582 if validation == 'strict':
583 raise error
584 yield error
585
586 try:
587 text = self.from_python(obj)
588 except ValueError:
589 yield self.encode_error(validation, obj, self.from_python)
590 yield None
591 else:
592 if self.patterns is not None:
593 for error in self.patterns(text):
594 if validation == 'strict':
595 raise error
596 yield error
597 yield text
598
601 """
602 Class for 'list' definitions. A list definition has an item_type attribute
603 that refers to an atomic or union simpleType definition.
604
605 <list
606 id = ID
607 itemType = QName
608 {any attributes with non-schema namespace ...}>
609 Content: (annotation?, simpleType?)
610 </list>
611 """
612 _admitted_tags = {XSD_LIST}
613 _white_space_elem = etree_element(XSD_WHITE_SPACE, attrib={'value': 'collapse', 'fixed': 'true'})
614
615 - def __init__(self, elem, schema, parent, name=None):
618
620 if self.name is None:
621 return '%s(item_type=%r)' % (self.__class__.__name__, self.base_type)
622 else:
623 return '%s(name=%r)' % (self.__class__.__name__, self.prefixed_name)
624
639
641 super(XsdList, self)._parse()
642 elem = self.elem
643
644 child = self._parse_component(elem, required=False)
645 if child is not None:
646
647 try:
648 base_type = xsd_simple_type_factory(child, self.schema, self)
649 except XMLSchemaParseError as err:
650 self.parse_error(err, elem)
651 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
652
653 if 'itemType' in elem.attrib:
654 self.parse_error("ambiguous list type declaration", self)
655
656 else:
657
658 try:
659 item_qname = self.schema.resolve_qname(elem.attrib['itemType'])
660 except KeyError:
661 self.parse_error("missing list type declaration", elem)
662 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
663 except ValueError as err:
664 self.parse_error(err, elem)
665 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
666 else:
667 try:
668 base_type = self.maps.lookup_type(item_qname)
669 except LookupError:
670 self.parse_error("unknown itemType %r" % elem.attrib['itemType'], elem)
671 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
672
673 if base_type.final == '#all' or 'list' in base_type.final:
674 self.parse_error("'final' value of the itemType %r forbids derivation by list" % base_type)
675
676 try:
677 self.base_type = base_type
678 except XMLSchemaValueError as err:
679 self.parse_error(str(err), elem)
680 self.base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
681
682 @property
685
686 @property
689
690 @property
693
694 @property
700
701 @staticmethod
704
705 @staticmethod
708
720
727
728 - def iter_decode(self, obj, validation='lax', **kwargs):
729 if isinstance(obj, (string_base_type, bytes)):
730 obj = self.normalize(obj)
731
732 if validation != 'skip' and self.patterns:
733 for error in self.patterns(obj):
734 if validation == 'strict':
735 raise error
736 yield error
737
738 items = []
739 for chunk in obj.split():
740 for result in self.base_type.iter_decode(chunk, validation, **kwargs):
741 if isinstance(result, XMLSchemaValidationError):
742 yield result
743 else:
744 items.append(result)
745
746 if validation != 'skip':
747 for validator in self.validators:
748 for error in validator(items):
749 if validation == 'strict':
750 raise error
751 yield error
752
753 yield items
754
755 - def iter_encode(self, obj, validation='lax', **kwargs):
756 if not hasattr(obj, '__iter__') or isinstance(obj, (str, unicode_type, bytes)):
757 obj = [obj]
758
759 if validation != 'skip':
760 for validator in self.validators:
761 for error in validator(obj):
762 if validation == 'strict':
763 raise error
764 yield error
765
766 encoded_items = []
767 for item in obj:
768 for result in self.base_type.iter_encode(item, validation, **kwargs):
769 if isinstance(result, XMLSchemaValidationError):
770 yield result
771 else:
772 encoded_items.append(result)
773
774 yield ' '.join(item for item in encoded_items if item is not None)
775
778 """
779 Class for 'union' definitions. A union definition has a member_types
780 attribute that refers to a 'simpleType' definition.
781
782 <union
783 id = ID
784 memberTypes = List of QName
785 {any attributes with non-schema namespace ...}>
786 Content: (annotation?, simpleType*)
787 </union>
788 """
789 _admitted_types = XsdSimpleType
790 _admitted_tags = {XSD_UNION}
791
792 member_types = None
793
794 - def __init__(self, elem, schema, parent, name=None):
796
798 if self.name is None:
799 return '%s(member_types=%r)' % (self.__class__.__name__, self.member_types)
800 else:
801 return '%s(name=%r)' % (self.__class__.__name__, self.prefixed_name)
802
817
863
864 @property
867
868 @property
871
872 @property
880
883
886
888 if xsd_classes is None or isinstance(self, xsd_classes):
889 yield self
890 for mt in self.member_types:
891 if not mt.is_global:
892 for obj in mt.iter_components(xsd_classes):
893 yield obj
894
895 - def iter_decode(self, obj, validation='lax', **kwargs):
896 if isinstance(obj, (string_base_type, bytes)):
897 obj = self.normalize(obj)
898
899 if validation != 'skip' and self.patterns:
900 for error in self.patterns(obj):
901 if validation == 'strict':
902 raise error
903 yield error
904
905
906 for member_type in self.member_types:
907 for result in member_type.iter_decode(obj, validation='lax', **kwargs):
908 if not isinstance(result, XMLSchemaValidationError):
909 if validation != 'skip':
910 for validator in self.validators:
911 for error in validator(result):
912 if validation == 'strict':
913 raise error
914 yield error
915
916 yield result
917 return
918 break
919
920 if validation != 'skip' and ' ' not in obj.strip():
921 reason = "no type suitable for decoding %r." % obj
922 yield self.decode_error(validation, obj, self.member_types, reason)
923
924 items = []
925 not_decodable = []
926 for chunk in obj.split():
927 for member_type in self.member_types:
928 for result in member_type.iter_decode(chunk, validation='lax', **kwargs):
929 if isinstance(result, XMLSchemaValidationError):
930 break
931 else:
932 items.append(result)
933 else:
934 break
935 else:
936 if validation != 'skip':
937 not_decodable.append(chunk)
938 else:
939 items.append(unicode_type(chunk))
940
941 if validation != 'skip':
942 if not_decodable:
943 reason = "no type suitable for decoding the values %r." % not_decodable
944 yield self.decode_error(validation, obj, self.member_types, reason)
945
946 for validator in self.validators:
947 for error in validator(items):
948 if validation == 'strict':
949 raise error
950 yield error
951
952 yield items if len(items) > 1 else items[0] if items else None
953
954 - def iter_encode(self, obj, validation='lax', **kwargs):
955 for member_type in self.member_types:
956 for result in member_type.iter_encode(obj, validation='lax', **kwargs):
957 if result is not None and not isinstance(result, XMLSchemaValidationError):
958 if validation != 'skip':
959 for validator in self.validators:
960 for error in validator(obj):
961 if validation == 'strict':
962 raise error
963 yield error
964 if self.patterns is not None:
965 for error in self.patterns(result):
966 if validation == 'strict':
967 raise error
968 yield error
969
970 yield result
971 return
972 elif validation == 'strict':
973
974 break
975
976 if hasattr(obj, '__iter__') and not isinstance(obj, (str, unicode_type, bytes)):
977 for member_type in self.member_types:
978 results = []
979 for item in obj:
980 for result in member_type.iter_encode(item, validation='lax', **kwargs):
981 if result is not None and not isinstance(result, XMLSchemaValidationError):
982 if validation != 'skip':
983 for validator in self.validators:
984 for error in validator(result):
985 if validation == 'strict':
986 raise error
987 yield error
988 if self.patterns is not None:
989 for error in self.patterns(result):
990 if validation == 'strict':
991 raise error
992 yield error
993
994 results.append(result)
995 break
996 elif validation == 'strict':
997 break
998
999 if len(results) == len(obj):
1000 yield results
1001 break
1002
1003 if validation != 'skip':
1004 reason = "no type suitable for encoding the object."
1005 yield self.encode_error(validation, obj, self.member_types, reason)
1006 yield None
1007 else:
1008 yield unicode_type(obj)
1009
1014
1017 """
1018 Class for XSD 1.0 atomic simpleType and complexType's simpleContent restrictions.
1019
1020 <restriction
1021 base = QName
1022 id = ID
1023 {any attributes with non-schema namespace . . .}>
1024 Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive |
1025 maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength |
1026 enumeration | whiteSpace | pattern)*))
1027 </restriction>
1028 """
1029 FACETS_BUILDERS = XSD_10_FACETS_BUILDERS
1030 derivation = 'restriction'
1031
1038
1040 super(XsdAtomicRestriction, self)._parse()
1041 elem = self.elem
1042 if elem.get('name') == XSD_ANY_ATOMIC_TYPE:
1043 return
1044 elif elem.tag == XSD_SIMPLE_TYPE and elem.get('name') is not None:
1045 elem = self._parse_component(elem)
1046
1047 if self.name is not None and self.parent is not None:
1048 self.parse_error("'name' attribute in a local simpleType definition", elem)
1049
1050 base_type = None
1051 facets = {}
1052 has_attributes = False
1053 has_simple_type_child = False
1054
1055 if 'base' in elem.attrib:
1056 try:
1057 base_qname = self.schema.resolve_qname(elem.attrib['base'])
1058 except ValueError as err:
1059 self.parse_error(err, elem)
1060 base_type = self.maps.type[XSD_ANY_ATOMIC_TYPE]
1061 else:
1062 if base_qname == self.name:
1063 if self.redefine is None:
1064 self.parse_error("wrong definition with self-reference", elem)
1065 base_type = self.maps.type[XSD_ANY_ATOMIC_TYPE]
1066 else:
1067 base_type = self.base_type
1068 else:
1069 if self.redefine is not None:
1070 self.parse_error("wrong redefinition without self-reference", elem)
1071
1072 try:
1073 base_type = self.maps.lookup_type(base_qname)
1074 except LookupError:
1075 self.parse_error("unknown type %r." % elem.attrib['base'])
1076 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
1077 except XMLSchemaParseError as err:
1078 self.parse_error(err)
1079 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
1080 else:
1081 if isinstance(base_type, tuple):
1082 self.parse_error("circularity definition between %r and %r" % (self, base_qname), elem)
1083 base_type = self.maps.types[XSD_ANY_ATOMIC_TYPE]
1084
1085 if base_type.is_simple() and base_type.name == XSD_ANY_SIMPLE_TYPE:
1086 self.parse_error("wrong base type {!r}, an atomic type required")
1087 elif base_type.is_complex():
1088 if base_type.mixed and base_type.is_emptiable():
1089 if self._parse_component(elem, strict=False).tag != XSD_SIMPLE_TYPE:
1090
1091 self.parse_error(
1092 "when a complexType with simpleContent restricts a complexType "
1093 "with mixed and with emptiable content then a simpleType child "
1094 "declaration is required.", elem
1095 )
1096 elif self.parent is None or self.parent.is_simple():
1097 self.parse_error("simpleType restriction of %r is not allowed" % base_type, elem)
1098
1099 for child in self._iterparse_components(elem):
1100 if child.tag in {XSD_ATTRIBUTE, XSD_ATTRIBUTE_GROUP, XSD_ANY_ATTRIBUTE}:
1101 has_attributes = True
1102 elif has_attributes:
1103 self.parse_error("unexpected tag after attribute declarations", child)
1104 elif child.tag == XSD_SIMPLE_TYPE:
1105
1106 if has_simple_type_child:
1107 self.parse_error("duplicated simpleType declaration", child)
1108
1109 if base_type is None:
1110 try:
1111 base_type = xsd_simple_type_factory(child, self.schema, self)
1112 except XMLSchemaParseError as err:
1113 self.parse_error(err)
1114 base_type = self.maps.types[XSD_ANY_SIMPLE_TYPE]
1115 elif base_type.is_complex():
1116 if base_type.admit_simple_restriction():
1117 base_type = self.schema.BUILDERS.complex_type_class(
1118 elem=elem,
1119 schema=self.schema,
1120 parent=self,
1121 content_type=xsd_simple_type_factory(child, self.schema, self),
1122 attributes=base_type.attributes,
1123 mixed=base_type.mixed,
1124 block=base_type.block,
1125 final=base_type.final,
1126 )
1127 elif 'base' in elem.attrib:
1128 self.parse_error("restriction with 'base' attribute and simpleType declaration", child)
1129
1130 has_simple_type_child = True
1131 else:
1132 try:
1133 facet_class = self.FACETS_BUILDERS[child.tag]
1134 except KeyError:
1135 self.parse_error("unexpected tag %r in restriction:" % child.tag)
1136 continue
1137
1138 if child.tag not in facets:
1139 facets[child.tag] = facet_class(child, self.schema, self, base_type)
1140 elif child.tag not in MULTIPLE_FACETS:
1141 self.parse_error("multiple %r constraint facet" % local_name(child.tag))
1142 elif child.tag != XSD_ASSERTION:
1143 facets[child.tag].append(child)
1144 else:
1145 assertion = facet_class(child, self.schema, self, base_type)
1146 try:
1147 facets[child.tag].append(assertion)
1148 except AttributeError:
1149 facets[child.tag] = [facets[child.tag], assertion]
1150
1151 if base_type is None:
1152 self.parse_error("missing base type in restriction:", self)
1153 elif base_type.final == '#all' or 'restriction' in base_type.final:
1154 self.parse_error("'final' value of the baseType %r forbids derivation by restriction" % base_type)
1155
1156 self.base_type = base_type
1157 self.facets = facets
1158
1165
1166 - def iter_decode(self, obj, validation='lax', **kwargs):
1202
1203 - def iter_encode(self, obj, validation='lax', **kwargs):
1204 if self.is_list():
1205 if not hasattr(obj, '__iter__') or isinstance(obj, (str, unicode_type, bytes)):
1206 obj = [] if obj is None or obj == '' else [obj]
1207
1208 if validation != 'skip':
1209 for validator in self.validators:
1210 for error in validator(obj):
1211 if validation == 'strict':
1212 raise error
1213 yield error
1214
1215 for result in self.base_type.iter_encode(obj, validation):
1216 if isinstance(result, XMLSchemaValidationError):
1217 if validation == 'strict':
1218 raise result
1219 yield result
1220 if isinstance(result, XMLSchemaEncodeError):
1221 yield unicode_type(obj) if validation == 'skip' else None
1222 return
1223 else:
1224 yield result
1225 return
1226
1227 if isinstance(obj, (string_base_type, bytes)):
1228 obj = self.normalize(obj)
1229
1230 if self.base_type.is_simple():
1231 base_type = self.base_type
1232 elif self.base_type.has_simple_content():
1233 base_type = self.base_type.content_type
1234 elif self.base_type.mixed:
1235 yield unicode_type(obj)
1236 return
1237 else:
1238 raise XMLSchemaValueError("wrong base type %r: a simpleType or a complexType with "
1239 "simple or mixed content required." % self.base_type)
1240
1241 for result in base_type.iter_encode(obj, validation):
1242 if isinstance(result, XMLSchemaValidationError):
1243 if validation == 'strict':
1244 raise result
1245 yield result
1246 if isinstance(result, XMLSchemaEncodeError):
1247 yield unicode_type(obj) if validation == 'skip' else None
1248 return
1249 else:
1250 if validation != 'skip':
1251 for validator in self.validators:
1252 for error in validator(obj):
1253 if validation == 'strict':
1254 raise error
1255 yield error
1256
1257 yield result
1258 return
1259
1262
1265 """
1266 Class for XSD 1.1 atomic simpleType and complexType's simpleContent restrictions.
1267
1268 <restriction
1269 base = QName
1270 id = ID
1271 {any attributes with non-schema namespace . . .}>
1272 Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive |
1273 maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength |
1274 enumeration | whiteSpace | pattern | assertion | explicitTimezone |
1275 {any with namespace: ##other})*))
1276 </restriction>
1277 """
1278 FACETS_BUILDERS = XSD_11_FACETS_BUILDERS
1279