Package xmlschema_acue :: Package validators :: Module complex_types

Source Code for Module xmlschema_acue.validators.complex_types

  1  # -*- coding: utf-8 -*- 
  2  # 
  3  # Copyright (c), 2016-2019, SISSA (International School for Advanced Studies). 
  4  # All rights reserved. 
  5  # This file is distributed under the terms of the MIT License. 
  6  # See the file 'LICENSE' in the root directory of the present 
  7  # distribution, or http://opensource.org/licenses/MIT. 
  8  # 
  9  # @author Davide Brunato <brunato@sissa.it> 
 10  # 
 11  from __future__ import unicode_literals 
 12   
 13  from xmlschema_acue.exceptions import XMLSchemaValueError 
 14  from xmlschema_acue.qnames import XSD_GROUP, XSD_ATTRIBUTE_GROUP, XSD_SEQUENCE, XSD_ALL, XSD_CHOICE, \ 
 15      XSD_ANY_ATTRIBUTE, XSD_ATTRIBUTE, XSD_COMPLEX_CONTENT, XSD_RESTRICTION, XSD_COMPLEX_TYPE, \ 
 16      XSD_EXTENSION, XSD_ANY_TYPE, XSD_SIMPLE_CONTENT, XSD_ANY_SIMPLE_TYPE, XSD_OPEN_CONTENT, XSD_ASSERT 
 17  from xmlschema_acue.helpers import get_qname, local_name, get_xml_bool_attribute, get_xsd_derivation_attribute 
 18  from xmlschema_acue.etree import etree_element 
 19   
 20  from xmlschema_acue.validators.exceptions import XMLSchemaValidationError, XMLSchemaDecodeError 
 21  from xmlschema_acue.validators.xsdbase import XsdType, ValidationMixin 
 22  from xmlschema_acue.validators.assertions import XsdAssert 
 23  from xmlschema_acue.validators.attributes import XsdAttributeGroup 
 24  from xmlschema_acue.validators.simple_types import XsdSimpleType 
 25  from xmlschema_acue.validators.groups import XsdGroup 
 26   
 27  XSD_MODEL_GROUP_TAGS = {XSD_GROUP, XSD_SEQUENCE, XSD_ALL, XSD_CHOICE} 
 28   
 29  SEQUENCE_ELEMENT = etree_element(XSD_SEQUENCE) 
30 31 32 -class XsdComplexType(XsdType, ValidationMixin):
33 """ 34 Class for XSD 1.0 'complexType' definitions. 35 36 <complexType 37 abstract = boolean : false 38 block = (#all | List of (extension | restriction)) 39 final = (#all | List of (extension | restriction)) 40 id = ID 41 mixed = boolean : false 42 name = NCName 43 {any attributes with non-schema namespace . . .}> 44 Content: (annotation?, (simpleContent | complexContent | 45 ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) 46 </complexType> 47 """ 48 _admitted_tags = {XSD_COMPLEX_TYPE, XSD_RESTRICTION} 49 assertions = () 50 mixed = False 51 _block = None 52 _derivation = None 53 54 @staticmethod
55 - def normalize(text):
56 return text.decode('utf-8') if isinstance(text, bytes) else text
57
58 - def __init__(self, elem, schema, parent, name=None, **kwargs):
59 if kwargs: 60 if 'content_type' in kwargs: 61 self.content_type = kwargs['content_type'] 62 if 'attributes' in kwargs: 63 self.attributes = kwargs['attributes'] 64 if 'mixed' in kwargs: 65 self.mixed = kwargs['mixed'] 66 if 'block' in kwargs: 67 self._block = kwargs['block'] 68 if 'final' in kwargs: 69 self._final = kwargs['final'] 70 super(XsdComplexType, self).__init__(elem, schema, parent, name)
71
72 - def __repr__(self):
73 if self.name is not None: 74 return '%s(name=%r)' % (self.__class__.__name__, self.prefixed_name) 75 elif not hasattr(self, 'content_type'): 76 return '%s(id=%r)' % (self.__class__.__name__, id(self)) 77 else: 78 return '%s(content=%r, attributes=%r)' % ( 79 self.__class__.__name__, self.content_type_label, 80 [a if a.name is None else a.prefixed_name for a in self.attributes.values()] 81 )
82
83 - def __setattr__(self, name, value):
84 if name == 'content_type': 85 assert isinstance(value, (XsdSimpleType, XsdGroup)), \ 86 "The attribute 'content_type' must be a XsdSimpleType or an XsdGroup instance." 87 elif name == 'attributes': 88 assert isinstance(value, XsdAttributeGroup), \ 89 "The attribute 'attributes' must be an XsdAttributeGroup." 90 super(XsdComplexType, self).__setattr__(name, value)
91
92 - def _parse(self):
93 super(XsdComplexType, self)._parse() 94 elem = self.elem 95 if elem.tag == XSD_RESTRICTION: 96 return # a local restriction is already parsed by the caller 97 98 if 'abstract' in elem.attrib: 99 try: 100 self.abstract = get_xml_bool_attribute(elem, 'abstract') 101 except ValueError as err: 102 self.parse_error(err, elem) 103 104 if 'block' in elem.attrib: 105 try: 106 self._block = get_xsd_derivation_attribute(elem, 'block', ('extension', 'restriction')) 107 except ValueError as err: 108 self.parse_error(err, elem) 109 110 if 'final' in elem.attrib: 111 try: 112 self._final = get_xsd_derivation_attribute(elem, 'final', ('extension', 'restriction')) 113 except ValueError as err: 114 self.parse_error(err, elem) 115 116 if 'mixed' in elem.attrib: 117 try: 118 self.mixed = get_xml_bool_attribute(elem, 'mixed') 119 except ValueError as err: 120 self.parse_error(err, elem) 121 122 try: 123 self.name = get_qname(self.target_namespace, elem.attrib['name']) 124 except KeyError: 125 self.name = None 126 else: 127 if self.parent is not None: 128 self.parse_error("attribute 'name' not allowed for a local complexType", elem) 129 130 content_elem = self._parse_component(elem, required=False, strict=False) 131 if content_elem is None or content_elem.tag in \ 132 {XSD_ATTRIBUTE, XSD_ATTRIBUTE_GROUP, XSD_ANY_ATTRIBUTE}: 133 # 134 # complexType with empty content 135 self.content_type = self.schema.BUILDERS.group_class(SEQUENCE_ELEMENT, self.schema, self) 136 self._parse_content_tail(elem) 137 138 elif content_elem.tag in {XSD_GROUP, XSD_SEQUENCE, XSD_ALL, XSD_CHOICE}: 139 # 140 # complexType with child elements 141 self.content_type = self.schema.BUILDERS.group_class(content_elem, self.schema, self) 142 self._parse_content_tail(elem) 143 144 elif content_elem.tag == XSD_SIMPLE_CONTENT: 145 if 'mixed' in content_elem.attrib: 146 self.parse_error("'mixed' attribute not allowed with simpleContent", content_elem) 147 148 derivation_elem = self._parse_derivation_elem(content_elem) 149 if derivation_elem is None: 150 return 151 152 self.base_type = self._parse_base_type(derivation_elem) 153 if derivation_elem.tag == XSD_RESTRICTION: 154 self._parse_simple_content_restriction(derivation_elem, self.base_type) 155 else: 156 self._parse_simple_content_extension(derivation_elem, self.base_type) 157 158 if content_elem is not elem[-1]: 159 k = 2 if content_elem is not elem[0] else 1 160 self.parse_error("unexpected tag %r after simpleContent declaration:" % elem[k].tag, elem) 161 162 elif content_elem.tag == XSD_COMPLEX_CONTENT: 163 # 164 # complexType with complexContent restriction/extension 165 if 'mixed' in content_elem.attrib: 166 self.mixed = content_elem.attrib['mixed'] in ('true', '1') 167 168 derivation_elem = self._parse_derivation_elem(content_elem) 169 if derivation_elem is None: 170 return 171 172 base_type = self._parse_base_type(derivation_elem, complex_content=True) 173 if derivation_elem.tag == XSD_RESTRICTION: 174 self._parse_complex_content_restriction(derivation_elem, base_type) 175 else: 176 self._parse_complex_content_extension(derivation_elem, base_type) 177 178 if content_elem is not elem[-1]: 179 k = 2 if content_elem is not elem[0] else 1 180 self.parse_error("unexpected tag %r after complexContent declaration:" % elem[k].tag, elem) 181 if self.redefine or base_type is not self: 182 self.base_type = base_type 183 184 elif content_elem.tag == XSD_OPEN_CONTENT and self.schema.XSD_VERSION != '1.0': 185 self.open_content = None 186 187 if content_elem is elem[-1]: 188 self.content_type = self.schema.BUILDERS.group_class(SEQUENCE_ELEMENT, self.schema, self) 189 else: 190 for child, index in enumerate(elem): 191 if content_elem is not child: 192 continue 193 elif elem[index + 1].tag in {XSD_GROUP, XSD_SEQUENCE, XSD_ALL, XSD_CHOICE}: 194 self.content_type = self.schema.BUILDERS.group_class(elem[index + 1], self.schema, self) 195 else: 196 self.content_type = self.schema.BUILDERS.group_class(SEQUENCE_ELEMENT, self.schema, self) 197 break 198 self._parse_content_tail(elem) 199 200 else: 201 if self.schema.validation == 'skip': 202 # Also generated by meta-schema validation for 'lax' and 'strict' modes 203 self.parse_error("unexpected tag %r for complexType content:" % content_elem.tag, elem) 204 self.content_type = self.schema.create_any_content_group(self) 205 self.attributes = self.schema.create_any_attribute_group(self) 206 207 if self.redefine is None: 208 if self.base_type is not None and self.base_type.name == self.name: 209 self.parse_error("wrong definition with self-reference", elem) 210 elif self.base_type is None or self.base_type.name != self.name: 211 self.parse_error("wrong redefinition without self-reference", elem)
212
213 - def _parse_content_tail(self, elem, **kwargs):
214 self.attributes = self.schema.BUILDERS.attribute_group_class(elem, self.schema, self, **kwargs)
215
216 - def _parse_derivation_elem(self, elem):
217 derivation_elem = self._parse_component(elem, required=False) 218 if getattr(derivation_elem, 'tag', None) not in (XSD_RESTRICTION, XSD_EXTENSION): 219 self.parse_error("restriction or extension tag expected", derivation_elem) 220 self.content_type = self.schema.create_any_content_group(self) 221 self.attributes = self.schema.create_any_attribute_group(self) 222 return 223 224 derivation = local_name(derivation_elem.tag) 225 if self._derivation is None: 226 self._derivation = derivation == 'extension' 227 elif self.redefine is None: 228 raise XMLSchemaValueError("%r is expected to have a redefined/overridden component" % self) 229 230 if self.base_type is not None and derivation in self.base_type.final: 231 self.parse_error("%r derivation not allowed for %r." % (derivation, self)) 232 return derivation_elem
233
234 - def _parse_base_type(self, elem, complex_content=False):
235 try: 236 base_qname = self.schema.resolve_qname(elem.attrib['base']) 237 except KeyError: 238 self.parse_error("'base' attribute required", elem) 239 return self.maps.types[XSD_ANY_TYPE] 240 except ValueError as err: 241 self.parse_error(err, elem) 242 return self.maps.types[XSD_ANY_TYPE] 243 244 try: 245 base_type = self.maps.lookup_type(base_qname) 246 except KeyError: 247 self.parse_error("missing base type %r" % base_qname, elem) 248 if complex_content: 249 return self.maps.types[XSD_ANY_TYPE] 250 else: 251 return self.maps.types[XSD_ANY_SIMPLE_TYPE] 252 else: 253 if isinstance(base_type, tuple): 254 self.parse_error("circularity definition found between %r and %r" % (self, base_qname), elem) 255 return self.maps.types[XSD_ANY_TYPE] 256 elif complex_content and base_type.is_simple(): 257 self.parse_error("a complexType ancestor required: %r" % base_type, elem) 258 return self.maps.types[XSD_ANY_TYPE] 259 return base_type
260
261 - def _parse_simple_content_restriction(self, elem, base_type):
262 # simpleContent restriction: the base type must be a complexType with a simple 263 # content or a complex content with a mixed and emptiable content. 264 if base_type.is_simple(): 265 self.parse_error("a complexType ancestor required: %r" % base_type, elem) 266 self.content_type = self.schema.create_any_content_group(self) 267 self._parse_content_tail(elem) 268 else: 269 if base_type.has_simple_content(): 270 self.content_type = self.schema.BUILDERS.restriction_class(elem, self.schema, self) 271 if not self.content_type.is_derived(base_type.content_type, 'restriction'): 272 self.parse_error("Content type is not a restriction of base content type", elem) 273 274 elif base_type.mixed and base_type.is_emptiable(): 275 self.content_type = self.schema.BUILDERS.restriction_class(elem, self.schema, self) 276 else: 277 self.parse_error("with simple content cannot restrict an empty or " 278 "an element-only content type ", base_type.elem) 279 self.content_type = self.schema.create_any_content_group(self) 280 281 self._parse_content_tail(elem, derivation='restriction', base_attributes=base_type.attributes)
282
283 - def _parse_simple_content_extension(self, elem, base_type):
284 # simpleContent extension: the base type must be a simpleType or a complexType 285 # with simple content. 286 child = self._parse_component(elem, required=False, strict=False) 287 if child is not None and child.tag not in \ 288 {XSD_ATTRIBUTE_GROUP, XSD_ATTRIBUTE, XSD_ANY_ATTRIBUTE}: 289 self.parse_error("unexpected tag %r." % child.tag, child) 290 291 if base_type.is_simple(): 292 self.content_type = base_type 293 self._parse_content_tail(elem) 294 else: 295 if base_type.has_simple_content(): 296 self.content_type = base_type.content_type 297 else: 298 self.parse_error("base type %r has not simple content." % base_type, elem) 299 self.content_type = self.schema.create_any_content_group(self) 300 301 self._parse_content_tail(elem, derivation='extension', base_attributes=base_type.attributes)
302
303 - def _parse_complex_content_restriction(self, elem, base_type):
304 if 'restriction' in base_type.final: 305 self.parse_error("the base type is not derivable by restriction") 306 if base_type.is_simple() or base_type.has_simple_content(): 307 self.parse_error("base %r is simple or has a simple content." % base_type, elem) 308 base_type = self.maps.types[XSD_ANY_TYPE] 309 310 # complexContent restriction: the base type must be a complexType with a complex content. 311 group_elem = self._parse_component(elem, required=False, strict=False) 312 if group_elem is not None and group_elem.tag in XSD_MODEL_GROUP_TAGS: 313 content_type = self.schema.BUILDERS.group_class(group_elem, self.schema, self) 314 else: 315 # Empty content model 316 content_type = self.schema.BUILDERS.group_class(elem, self.schema, self) 317 318 if base_type.is_element_only() and content_type.mixed: 319 self.parse_error( 320 "derived a mixed content from a base type that has element-only content.", elem 321 ) 322 elif base_type.is_empty() and not content_type.is_empty(): 323 self.parse_error( 324 "derived an empty content from base type that has not empty content.", elem 325 ) 326 327 if base_type.name != XSD_ANY_TYPE and not base_type.is_empty() and False: 328 if not content_type.has_occurs_restriction(base_type.content_type): 329 self.parse_error("The derived group %r is not a restriction of the base group." % elem, elem) 330 331 self.content_type = content_type 332 self._parse_content_tail(elem, derivation='restriction', base_attributes=base_type.attributes)
333
334 - def _parse_complex_content_extension(self, elem, base_type):
335 if 'extension' in base_type.final: 336 self.parse_error("the base type is not derivable by extension") 337 338 group_elem = self._parse_component(elem, required=False, strict=False) 339 if base_type.is_empty(): 340 # Empty model extension: don't create a nested group. 341 if group_elem is not None and group_elem.tag in XSD_MODEL_GROUP_TAGS: 342 self.content_type = self.schema.BUILDERS.group_class(group_elem, self.schema, self) 343 else: 344 # Empty content model 345 self.content_type = self.schema.BUILDERS.group_class(elem, self.schema, self) 346 else: 347 # Set the content type using a dummy sequence element 348 sequence_elem = etree_element(XSD_SEQUENCE) 349 sequence_elem.text = '\n ' 350 content_type = self.schema.BUILDERS.group_class(sequence_elem, self.schema, self) 351 352 if group_elem is not None and group_elem.tag in XSD_MODEL_GROUP_TAGS: 353 # Illegal derivation from a simple content. Applies to both XSD 1.0 and XSD 1.1. 354 # For the detailed rule refer to XSD 1.1 documentation: 355 # https://www.w3.org/TR/2012/REC-xmlschema11-1-20120405/#sec-cos-ct-extends 356 if base_type.is_simple() or base_type.has_simple_content(): 357 self.parse_error("base %r is simple or has a simple content." % base_type, elem) 358 base_type = self.maps.types[XSD_ANY_TYPE] 359 360 group = self.schema.BUILDERS.group_class(group_elem, self.schema, self) 361 if group.model == 'all': 362 self.parse_error("Cannot extend a complex content with an all model") 363 364 content_type.append(base_type.content_type) 365 content_type.append(group) 366 sequence_elem.append(base_type.content_type.elem) 367 sequence_elem.append(group.elem) 368 369 # complexContent extension: base type must be a complex type with complex content. 370 # A dummy sequence group is added if the base type has not empty content model. 371 if base_type.content_type.model == 'all' and base_type.content_type and group \ 372 and self.schema.XSD_VERSION == '1.0': 373 self.parse_error("XSD 1.0 does not allow extension of a not empty 'ALL' model group.", elem) 374 375 if base_type.mixed != self.mixed and base_type.name != XSD_ANY_TYPE: 376 self.parse_error("base has a different content type (mixed=%r) and the " 377 "extension group is not empty." % base_type.mixed, elem) 378 379 elif not base_type.is_simple() and not base_type.has_simple_content(): 380 content_type.append(base_type.content_type) 381 sequence_elem.append(base_type.content_type.elem) 382 if base_type.mixed != self.mixed and base_type.name != XSD_ANY_TYPE and self.mixed: 383 self.parse_error("extended type has a mixed content but the base is element-only", elem) 384 385 self.content_type = content_type 386 387 self._parse_content_tail(elem, derivation='extension', base_attributes=base_type.attributes)
388 389 @property
390 - def built(self):
391 try: 392 return self.content_type.built and self.attributes.built and self.mixed in (False, True) 393 except AttributeError: 394 return False
395 396 @property
397 - def validation_attempted(self):
398 if self.built: 399 return 'full' 400 elif self.attributes.validation_attempted == 'partial': 401 return 'partial' 402 elif self.content_type.validation_attempted == 'partial': 403 return 'partial' 404 else: 405 return 'none'
406 407 @property
408 - def block(self):
409 return self.schema.block_default if self._block is None else self._block
410 411 @staticmethod
412 - def is_simple():
413 return False
414 415 @staticmethod
416 - def is_complex():
417 return True
418
419 - def is_empty(self):
420 if self.name == XSD_ANY_TYPE: 421 return False 422 return self.content_type.is_empty()
423
424 - def is_emptiable(self):
425 return self.content_type.is_emptiable()
426
427 - def has_simple_content(self):
428 try: 429 return self.content_type.is_simple() 430 except AttributeError: 431 if self.content_type or self.content_type.mixed or self.base_type is None: 432 return False 433 else: 434 return self.base_type.is_simple() or self.base_type.has_simple_content()
435
436 - def has_mixed_content(self):
437 try: 438 return self.content_type.mixed 439 except AttributeError: 440 return False
441
442 - def is_element_only(self):
443 if self.name == XSD_ANY_TYPE: 444 return False 445 try: 446 return not self.content_type.mixed 447 except AttributeError: 448 return False
449
450 - def is_list(self):
451 return self.has_simple_content() and self.content_type.is_list()
452
453 - def is_valid(self, source, use_defaults=True):
454 if hasattr(source, 'tag'): 455 return super(XsdComplexType, self).is_valid(source, use_defaults) 456 elif isinstance(self.content_type, XsdSimpleType): 457 return self.content_type.is_valid(source) 458 else: 459 return self.base_type is not None and self.base_type.is_valid(source) or self.mixed
460
461 - def is_derived(self, other, derivation=None):
462 if self is other: 463 return True 464 elif derivation and self.derivation and derivation != self.derivation and other.is_complex(): 465 return False 466 elif other.name == XSD_ANY_TYPE: 467 return True 468 elif self.base_type is other: 469 return True 470 elif hasattr(other, 'member_types'): 471 return any(self.is_derived(m, derivation) for m in other.member_types) 472 elif self.base_type is None: 473 if not self.has_simple_content(): 474 return False 475 return self.content_type.is_derived(other, derivation) 476 elif self.has_simple_content(): 477 return self.content_type.is_derived(other, derivation) or self.base_type.is_derived(other, derivation) 478 else: 479 return self.base_type.is_derived(other, derivation)
480
481 - def iter_components(self, xsd_classes=None):
482 if xsd_classes is None or isinstance(self, xsd_classes): 483 yield self 484 if self.attributes.parent is not None: 485 for obj in self.attributes.iter_components(xsd_classes): 486 yield obj 487 if self.content_type.parent is not None: 488 for obj in self.content_type.iter_components(xsd_classes): 489 yield obj 490 491 for obj in self.assertions: 492 if xsd_classes is None or isinstance(obj, xsd_classes): 493 yield obj
494 495 @staticmethod
496 - def get_facet(*_args, **_kwargs):
497 return None
498
499 - def admit_simple_restriction(self):
500 if 'restriction' in self.final: 501 return False 502 else: 503 return self.has_simple_content() or self.mixed and self.is_emptiable()
504 505 @property
506 - def derivation(self):
507 return 'extension' if self._derivation else 'restriction' if self._derivation is False else None
508
509 - def has_restriction(self):
510 return self._derivation is False
511
512 - def has_extension(self):
513 return self._derivation is True
514
515 - def decode(self, data, *args, **kwargs):
516 if hasattr(data, 'attrib') or self.is_simple(): 517 return super(XsdComplexType, self).decode(data, *args, **kwargs) 518 elif self.has_simple_content(): 519 return self.content_type.decode(data, *args, **kwargs) 520 else: 521 raise XMLSchemaDecodeError(self, data, "cannot decode %r data with %r" % (data, self))
522
523 - def iter_decode(self, elem, validation='lax', converter=None, **kwargs):
524 """ 525 Decode an Element instance. 526 527 :param elem: the Element that has to be decoded. 528 :param validation: the validation mode. Can be 'lax', 'strict' or 'skip. 529 :param converter: an :class:`XMLSchemaConverter` subclass or instance. 530 :param kwargs: keyword arguments for the decoding process. 531 :return: yields a 3-tuple (simple content, complex content, attributes) containing \ 532 the decoded parts, eventually preceded by a sequence of validation or decoding errors. 533 """ 534 # XSD 1.1 assertions 535 for assertion in self.assertions: 536 for error in assertion(elem): 537 yield self.validation_error(validation, error, **kwargs) 538 539 for result in self.attributes.iter_decode(elem.attrib, validation, **kwargs): 540 if isinstance(result, XMLSchemaValidationError): 541 yield result 542 else: 543 attributes = result 544 break 545 else: 546 attributes = None 547 548 if self.has_simple_content(): 549 if len(elem) and validation != 'skip': 550 reason = "a simple content element can't has child elements." 551 yield self.validation_error(validation, reason, elem, **kwargs) 552 553 if elem.text is not None: 554 text = elem.text or kwargs.pop('default', '') 555 for result in self.content_type.iter_decode(text, validation, **kwargs): 556 if isinstance(result, XMLSchemaValidationError): 557 yield result 558 else: 559 yield result, None, attributes 560 else: 561 yield None, None, attributes 562 else: 563 for result in self.content_type.iter_decode(elem, validation, converter, **kwargs): 564 if isinstance(result, XMLSchemaValidationError): 565 yield result 566 else: 567 yield None, result, attributes
568
569 - def iter_encode(self, element_data, validation='lax', converter=None, **kwargs):
570 """ 571 Encode an element data instance. 572 573 :param element_data: an ElementData instance with unencoded data. 574 :param validation: the validation mode: can be 'lax', 'strict' or 'skip'. 575 :param converter: an :class:`XMLSchemaConverter` subclass or instance. 576 :param kwargs: keyword arguments for the encoding process. 577 :return: yields a 3-tuple (text, content, attributes) containing the encoded parts, \ 578 eventually preceded by a sequence of validation or decoding errors. 579 """ 580 for result in self.attributes.iter_encode(element_data.attributes, validation, **kwargs): 581 if isinstance(result, XMLSchemaValidationError): 582 yield result 583 else: 584 attributes = result 585 break 586 else: 587 attributes = () 588 589 if self.has_simple_content(): 590 if element_data.text is None: 591 yield None, element_data.content, attributes 592 else: 593 for result in self.content_type.iter_encode(element_data.text, validation, **kwargs): 594 if isinstance(result, XMLSchemaValidationError): 595 yield result 596 else: 597 yield result, element_data.content, attributes 598 else: 599 for result in self.content_type.iter_encode(element_data, validation, converter, **kwargs): 600 if isinstance(result, XMLSchemaValidationError): 601 yield result 602 elif result: 603 yield result[0], result[1], attributes 604 else: 605 yield None, None, attributes
606
607 608 -class Xsd11ComplexType(XsdComplexType):
609 """ 610 Class for XSD 1.1 'complexType' definitions. 611 612 <complexType 613 abstract = boolean : false 614 block = (#all | List of (extension | restriction)) 615 final = (#all | List of (extension | restriction)) 616 id = ID 617 mixed = boolean 618 name = NCName 619 defaultAttributesApply = boolean : true 620 {any attributes with non-schema namespace . . .}> 621 Content: (annotation?, (simpleContent | complexContent | (openContent?, 622 (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))) 623 </complexType> 624 """
625 - def _parse(self):
626 super(Xsd11ComplexType, self)._parse() 627 628 # Add inheritable attributes 629 if hasattr(self.base_type, 'attributes'): 630 for name, attr in self.base_type.attributes.items(): 631 if name and attr.inheritable: 632 if name not in self.attributes: 633 self.attributes[name] = attr 634 elif not self.attributes[name].inheritable: 635 self.parse_error("attribute %r must be inheritable") 636 637 # Add default attributes 638 if isinstance(self.schema.default_attributes, XsdAttributeGroup) and self.default_attributes_apply: 639 self.attributes.update( 640 (k, v) for k, v in self.schema.default_attributes.items() if k not in self.attributes 641 )
642
643 - def _parse_content_tail(self, elem, **kwargs):
644 self.attributes = self.schema.BUILDERS.attribute_group_class(elem, self.schema, self, **kwargs) 645 self.assertions = [] 646 for child in self._iterparse_components(elem): 647 if child.tag == XSD_ASSERT: 648 self.assertions.append(XsdAssert(child, self.schema, self, self))
649 650 @property
651 - def default_attributes_apply(self):
652 return get_xml_bool_attribute(self.elem, 'defaultAttributesApply', default=True)
653