diff --git a/tests/codegen/handlers/test_create_compound_fields.py b/tests/codegen/handlers/test_create_compound_fields.py index 903adcda6..dc6c3e799 100644 --- a/tests/codegen/handlers/test_create_compound_fields.py +++ b/tests/codegen/handlers/test_create_compound_fields.py @@ -92,7 +92,7 @@ def test_group_fields(self): name="choice", tag="Choice", index=0, - types=[AttrTypeFactory.native(DataType.ANY_TYPE)], + types=list({t for attr in target.attrs for t in attr.types}), choices=[ AttrFactory.create( tag=target.attrs[0].tag, diff --git a/tests/fixtures/compound/models.py b/tests/fixtures/compound/models.py index a0b067a66..5ba180738 100644 --- a/tests/fixtures/compound/models.py +++ b/tests/fixtures/compound/models.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field -from typing import List +from typing import List, Union @dataclass @@ -35,7 +35,7 @@ class Root: class Meta: name = "root" - alpha_or_bravo: List[object] = field( + alpha_or_bravo: List[Union[Bravo, Alpha]] = field( default_factory=list, metadata={ "type": "Elements", diff --git a/xsdata/codegen/handlers/create_compound_fields.py b/xsdata/codegen/handlers/create_compound_fields.py index 5735bb119..8bf7e105d 100644 --- a/xsdata/codegen/handlers/create_compound_fields.py +++ b/xsdata/codegen/handlers/create_compound_fields.py @@ -7,13 +7,11 @@ from xsdata.codegen.mixins import ContainerInterface from xsdata.codegen.mixins import RelativeHandlerInterface from xsdata.codegen.models import Attr -from xsdata.codegen.models import AttrType from xsdata.codegen.models import Class from xsdata.codegen.models import get_restriction_choice from xsdata.codegen.models import Restrictions from xsdata.codegen.utils import ClassUtils from xsdata.formats.dataclass.models.elements import XmlType -from xsdata.models.enums import DataType from xsdata.models.enums import Tag from xsdata.utils.collections import group_by @@ -86,18 +84,18 @@ def group_fields(self, target: Class, attrs: List[Attr]): ClassUtils.remove_attribute(target, attr) names.append(attr.local_name) choices.append(self.build_attr_choice(attr)) - self.update_counters(attr, counters) min_occurs, max_occurs = self.sum_counters(counters) name = self.choose_name(target, names) + types = list({t for attr in attrs for t in attr.types}) target.attrs.insert( pos, Attr( name=name, index=0, - types=[AttrType(qname=str(DataType.ANY_TYPE), native=True)], + types=types, tag=Tag.CHOICE, restrictions=Restrictions( min_occurs=sum(min_occurs), diff --git a/xsdata/formats/dataclass/models/builders.py b/xsdata/formats/dataclass/models/builders.py index e07b277ea..50c83ec76 100644 --- a/xsdata/formats/dataclass/models/builders.py +++ b/xsdata/formats/dataclass/models/builders.py @@ -526,8 +526,8 @@ def is_valid( # xs:NMTOKENS need origin list return False - if object in types: - # Any type, secondary types are not allowed + if object in types and xml_type != XmlType.ELEMENTS: + # Any type, secondary types are not allowed except for 'Elements' XML type return len(types) == 1 return self.is_typing_supported(types) diff --git a/xsdata/formats/dataclass/models/elements.py b/xsdata/formats/dataclass/models/elements.py index 4ba505f5f..7ee49ed9f 100644 --- a/xsdata/formats/dataclass/models/elements.py +++ b/xsdata/formats/dataclass/models/elements.py @@ -176,10 +176,10 @@ def __init__( self.is_attribute = False self.is_attributes = False - if xml_type == XmlType.ELEMENT or self.clazz: - self.is_element = True - elif xml_type == XmlType.ELEMENTS: + if xml_type == XmlType.ELEMENTS: self.is_elements = True + elif xml_type == XmlType.ELEMENT or self.clazz: + self.is_element = True elif xml_type == XmlType.ATTRIBUTE: self.is_attribute = True elif xml_type == XmlType.ATTRIBUTES: