Compound FieldsΒΆ

For repeating choice elements or complicated sequence elements you can use compound fields in order to preserve the elements ordering during roundtrip conversions.

$ xsdata tests/fixtures/defxmlschema/chapter12.xsd  --compound-fields --package tests.fixtures.defxmlschema
  <xsd:complexType name="ProductType">
    <xsd:sequence>
      <xsd:element name="number" type="xsd:integer" />
      <xsd:element name="name" type="xsd:string" />
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="size" type="SizeType" />
        <xsd:element name="color" type="ColorType" />
        <xsd:element name="description" type="DescriptionType" />
      </xsd:choice>
    </xsd:sequence>
    <xsd:attribute name="effDate" type="xsd:date" default="1900-01-01" />
    <xsd:anyAttribute namespace="##other" processContents="lax" />
  </xsd:complexType>
@dataclass
class ProductType:
    number: Optional[int] = field(
        default=None,
        metadata={
            "type": "Element",
            "namespace": "",
            "required": True,
        }
    )
    name: Optional[str] = field(
        default=None,
        metadata={
            "type": "Element",
            "namespace": "",
            "required": True,
        }
    )
    size_or_color_or_description: List[object] = field(
        default_factory=list,
        metadata={
            "type": "Elements",
            "choices": (
                {
                    "name": "size",
                    "type": SizeType,
                    "namespace": "",
                },
                {
                    "name": "color",
                    "type": ColorType,
                    "namespace": "",
                },
                {
                    "name": "description",
                    "type": DescriptionType,
                    "namespace": "",
                },
            ),
        }
    )
    eff_date: XmlDate = field(
        default=XmlDate(1900, 1, 1),
        metadata={
            "name": "effDate",
            "type": "Attribute",
        }
    )
    other_attributes: Dict = field(
        default_factory=dict,
        metadata={
            "type": "Attributes",
            "namespace": "##other",
        }
    )

All choice elements are grouped into a single list field.

from pathlib import Path
from tests.fixtures.defxmlschema.chapter12 import Items
from tests import fixtures_dir
from xsdata.formats.dataclass.parsers import XmlParser

xml_string = fixtures_dir.joinpath("defxmlschema/chapter12.xml").read_text()
parser = XmlParser()
items = parser.from_string(xml_string, Items)
print(items.shirt_or_hat_or_umbrella[0].size_or_color_or_description)
[SizeType(value=10, system='US-DRESS'), ColorType(value='blue'), DescriptionType(w3_org_1999_xhtml_element=['\n      This shirt is the ', AnyElement(qname='{http://www.w3.org/1999/xhtml}b', text='best-selling', tail=' shirt in\n      our catalog! ', children=[], attributes={}), AnyElement(qname='{http://www.w3.org/1999/xhtml}br', text='', tail=' Note: runs large.\n    ', children=[], attributes={})])]