Chapter 10

Union and list types

Binding Test

Schema

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:annotation>
    <xsd:documentation>
      This example illustrates list and union types.
    </xsd:documentation>
  </xsd:annotation>

  <xsd:element name="sizes" type="SizesType"/>

  <xsd:complexType name="SizesType">
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="size" type="SizeType"/>
      <xsd:element name="smallSize" type="SmallSizeType"/>
      <xsd:element name="internationalSize" type="InternationalSizeType"/>
      <xsd:element name="availableSizes" type="AvailableSizesType"/>
      <xsd:element name="applicableSizes" type="ApplicableSizesType"/>
    </xsd:choice>
  </xsd:complexType>

  <xsd:simpleType name="SizeType">
    <xsd:union memberTypes="DressSizeType">
      <xsd:simpleType>
        <xsd:restriction base="xsd:token">
          <xsd:enumeration value="small"/>
          <xsd:enumeration value="medium"/>
          <xsd:enumeration value="large"/>
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:union>
  </xsd:simpleType>

  <xsd:simpleType name="DressSizeType">
    <xsd:restriction base="xsd:integer">
      <xsd:minInclusive value="2"/>
      <xsd:maxInclusive value="18"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="SmallSizeType">
    <xsd:restriction base="SizeType">
      <xsd:enumeration value="2"/>
      <xsd:enumeration value="4"/>
      <xsd:enumeration value="6"/>
      <xsd:enumeration value="small"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="InternationalSizeType">
    <xsd:union memberTypes="SizeType">
      <xsd:simpleType>
        <xsd:restriction base="xsd:integer">
          <xsd:minInclusive value="24"/>
          <xsd:maxInclusive value="54"/>
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:union>
  </xsd:simpleType>

  <xsd:simpleType name="AvailableSizesType">
    <xsd:list itemType="SizeType"/>
  </xsd:simpleType>

  <xsd:simpleType name="ApplicableSizesType">
    <xsd:restriction>
      <xsd:simpleType>
        <xsd:list itemType="SizeType"/>
      </xsd:simpleType>
      <xsd:enumeration value="small medium large"/>
      <xsd:enumeration value="2 4 6 8 10 12 14 16 18"/>
    </xsd:restriction>
  </xsd:simpleType>

</xsd:schema>

XML Document

<sizes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="chapter11.xsd">
  <size>12</size>
  <size>medium</size>
  <smallSize>6</smallSize>
  <smallSize>small</smallSize>
  <internationalSize>12</internationalSize>
  <internationalSize>24</internationalSize>
  <internationalSize>large</internationalSize>
  <availableSizes>10 large 2</availableSizes>
  <applicableSizes>small medium large</applicableSizes>
</sizes>

xsData XML Document

<sizes>
  <size>12</size>
  <size>medium</size>
  <smallSize>6</smallSize>
  <smallSize>small</smallSize>
  <internationalSize>12</internationalSize>
  <internationalSize>24</internationalSize>
  <internationalSize>large</internationalSize>
  <availableSizes>10 large 2</availableSizes>
  <applicableSizes>small medium large</applicableSizes>
</sizes>

xsData JSON

{
    "size": [
        12,
        "medium"
    ],
    "small_size": [
        "6",
        "small"
    ],
    "international_size": [
        12,
        24,
        "large"
    ],
    "available_sizes": [
        "10 large 2"
    ],
    "applicable_sizes": [
        "small medium large"
    ]
}

Example 10-1 Defining a union type

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="SizeType">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:integer">
          <xs:minInclusive value="2" />
          <xs:maxInclusive value="18" />
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:enumeration value="small" />
          <xs:enumeration value="medium" />
          <xs:enumeration value="large" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:element name="Size" type="SizeType" />
</xs:schema>
from enum import Enum
from dataclasses import dataclass, field
from typing import Optional, Union


@dataclass
class Size:
    """
    :ivar value:
    """
    value: Optional[Union[int, "Size.Value"]] = field(
        default=None,
        metadata=dict(
            required=True,
            min_inclusive=2.0,
            max_inclusive=18.0
        )
    )

    class Value(Enum):
        """
        :cvar LARGE:
        :cvar MEDIUM:
        :cvar SMALL:
        """
        LARGE = "large"
        MEDIUM = "medium"
        SMALL = "small"

Example 10-2 Using the memberTypes attribute

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="../chapter08/example0801.xsd" />
  <xs:import schemaLocation="../chapter08/example0810.xsd" />
  <xs:simpleType name="SizeType">
    <xs:union memberTypes="DressSizeType SMLSizeType" />
  </xs:simpleType>
  <xs:element name="SizeType" type="SizeType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional, Union
from tests.fixtures.defxmlschema.chapter08.example0810 import (
    SmlsizeType,
)


@dataclass
class SizeType:
    """
    :ivar value:
    """
    value: Optional[Union[int, SmlsizeType]] = field(
        default=None,
        metadata=dict(
            required=True,
            min_inclusive=2.0,
            max_inclusive=18.0
        )
    )

Example 10-3 Combining memberTypes and simpleType

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="../chapter08/example0803.xsd" />
  <xs:simpleType name="SizeType">
    <xs:union memberTypes="DressSizeType">
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:enumeration value="small" />
          <xs:enumeration value="medium" />
          <xs:enumeration value="large" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:element name="Size" type="SizeType" />
</xs:schema>
from enum import Enum
from dataclasses import dataclass, field
from typing import Optional, Union


@dataclass
class Size:
    """
    :ivar value:
    """
    value: Optional[Union[str, "Size.Value"]] = field(
        default=None,
        metadata=dict(
            required=True,
            min_inclusive=2.0,
            max_inclusive=18.0,
            pattern=r"\d{1,2}"
        )
    )

    class Value(Enum):
        """
        :cvar LARGE:
        :cvar MEDIUM:
        :cvar SMALL:
        """
        LARGE = "large"
        MEDIUM = "medium"
        SMALL = "small"

Example 10-4 Restricting a union

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="example1001.xsd" />
  <xs:simpleType name="SmallSizeType">
    <xs:restriction base="SizeType">
      <xs:enumeration value="2" />
      <xs:enumeration value="4" />
      <xs:enumeration value="6" />
      <xs:enumeration value="small" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
from enum import Enum


class SmallSizeType(Enum):
    """
    :cvar VALUE_2:
    :cvar VALUE_4:
    :cvar VALUE_6:
    :cvar SMALL:
    """
    VALUE_2 = "2"
    VALUE_4 = "4"
    VALUE_6 = "6"
    SMALL = "small"

Example 10-5 A union of a union

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="example1001.xsd" />
  <xs:simpleType name="InternationalSizeType">
    <xs:union memberTypes="SizeType">
      <xs:simpleType>
        <xs:restriction base="xs:integer">
          <xs:minInclusive value="24" />
          <xs:maxInclusive value="54" />
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:element name="InternationalSizeType" type="InternationalSizeType" />
</xs:schema>
from enum import Enum
from dataclasses import dataclass, field
from typing import Optional, Union


@dataclass
class InternationalSizeType:
    """
    :ivar value:
    """
    value: Optional[Union[int, "InternationalSizeType.Value"]] = field(
        default=None,
        metadata=dict(
            required=True,
            min_inclusive=24.0,
            max_inclusive=54.0
        )
    )

    class Value(Enum):
        """
        :cvar LARGE:
        :cvar MEDIUM:
        :cvar SMALL:
        """
        LARGE = "large"
        MEDIUM = "medium"
        SMALL = "small"

Example 10-7 Defining a list type using an itemType attribute

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="../chapter08/example0808.xsd" />
  <xs:simpleType name="AvailableSizesType">
    <xs:list itemType="DressSizeType" />
  </xs:simpleType>
  <xs:element name="AvailableSizesType" type="AvailableSizesType" />
</xs:schema>
from enum import Enum
from dataclasses import dataclass, field
from typing import List, Union


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    """
    value: List[Union[int, "AvailableSizesType.Value"]] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807,
            min_inclusive=2.0,
            max_inclusive=18.0
        )
    )

    class Value(Enum):
        """
        :cvar VALUE:
        """
        VALUE = ""

Example 10-9 Defining a list type using a simpleType child

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="AvailableSizesType">
    <xs:list>
      <xs:simpleType>
        <xs:restriction base="xs:integer">
          <xs:minInclusive value="2" />
          <xs:maxInclusive value="18" />
        </xs:restriction>
      </xs:simpleType>
    </xs:list>
  </xs:simpleType>
  <xs:element name="AvailableSizesType" type="AvailableSizesType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    """
    value: List[str] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )

Example 10-10 Length facet applied to a list

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="../chapter08/example0810.xsd" />
  <xs:simpleType name="AvailableSizesType">
    <xs:restriction>
      <xs:simpleType>
        <xs:list itemType="SMLSizeType" />
      </xs:simpleType>
      <xs:maxLength value="3" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    """
    value: Optional[str] = field(
        default=None,
        metadata=dict(
            name="value",
            type="Restriction",
            max_length=3.0
        )
    )

Example 10-12 Enumeration applied inappropriately to a list type

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="AvailableSizesType">
    <xs:restriction>
      <xs:simpleType>
        <xs:list itemType="xs:token" />
      </xs:simpleType>
      <xs:enumeration value="small" />
      <xs:enumeration value="medium" />
      <xs:enumeration value="large" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="AvailableSizesType" type="AvailableSizesType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    :ivar small:
    :ivar medium:
    :ivar large:
    """
    value: List[str] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )
    small: str = field(
        default="small",
        metadata=dict(
            required=True
        )
    )
    medium: str = field(
        default="medium",
        metadata=dict(
            required=True
        )
    )
    large: str = field(
        default="large",
        metadata=dict(
            required=True
        )
    )

Example 10-13 Enumeration applied to the item type of a list

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="AvailableSizesType">
    <xs:list>
      <xs:simpleType>
        <xs:restriction base="xs:token">
          <xs:enumeration value="small" />
          <xs:enumeration value="medium" />
          <xs:enumeration value="large" />
        </xs:restriction>
      </xs:simpleType>
    </xs:list>
  </xs:simpleType>
</xs:schema>
from enum import Enum
from dataclasses import dataclass, field
from typing import List


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    """
    value: List["AvailableSizesType.Value"] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )

    class Value(Enum):
        """
        :cvar LARGE:
        :cvar MEDIUM:
        :cvar SMALL:
        """
        LARGE = "large"
        MEDIUM = "medium"
        SMALL = "small"

Example 10-14 Enumeration correctly applied to a list type

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="example1002.xsd" />
  <xs:simpleType name="ApplicableSizesType">
    <xs:restriction>
      <xs:simpleType>
        <xs:list itemType="SizeType" />
      </xs:simpleType>
      <xs:enumeration value="small medium large" />
      <xs:enumeration value="2 4 6 8 10 12 14 16 18" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="ApplicableSizesType" type="ApplicableSizesType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List, Union
from tests.fixtures.defxmlschema.chapter08.example0810 import (
    SmlsizeType,
)


@dataclass
class ApplicableSizesType:
    """
    :ivar value:
    :ivar small_medium_large:
    :ivar value_2_4_6_8_10_12_14_16_18:
    """
    value: List[Union[int, SmlsizeType]] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807,
            min_inclusive=2.0,
            max_inclusive=18.0
        )
    )
    small_medium_large: str = field(
        default="small medium large",
        metadata=dict(
            required=True
        )
    )
    value_2_4_6_8_10_12_14_16_18: str = field(
        default="2 4 6 8 10 12 14 16 18",
        metadata=dict(
            required=True
        )
    )

Example 10-15 Pattern applied to a list type

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="VectorType">
    <xs:restriction>
      <xs:simpleType>
        <xs:list itemType="xs:unsignedInt" />
      </xs:simpleType>
      <xs:pattern value="\d+\s+\d+\s+((\d+\s+){3})*\d+" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="VectorType" type="VectorType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List


@dataclass
class VectorType:
    """
    :ivar value:
    """
    value: List[int] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )

Example 10-16 Defining a list of a string-based type

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="AvailableSizesType">
    <xs:list itemType="SMLXSizeType" />
  </xs:simpleType>
  <xs:simpleType name="SMLXSizeType">
    <xs:restriction base="xs:token">
      <xs:enumeration value="small" />
      <xs:enumeration value="medium" />
      <xs:enumeration value="large" />
      <xs:enumeration value="extra large" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
from enum import Enum


class SmlxsizeType(Enum):
    """
    :cvar EXTRA_LARGE:
    :cvar LARGE:
    :cvar MEDIUM:
    :cvar SMALL:
    """
    EXTRA_LARGE = "extra large"
    LARGE = "large"
    MEDIUM = "medium"
    SMALL = "small"

Example 10-18 Defining a list of a union

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="../chapter08/example0801.xsd" />
  <xs:import schemaLocation="../chapter08/example0809.xsd" />
  <xs:simpleType name="SizeType">
    <xs:union memberTypes="DressSizeType SMLXSizeType" />
  </xs:simpleType>
  <xs:simpleType name="AvailableSizesType">
    <xs:list itemType="SizeType" />
  </xs:simpleType>
  <xs:element name="AvailableSizesType" type="AvailableSizesType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List, Union
from tests.fixtures.defxmlschema.chapter08.example0809 import (
    SmlxsizeType,
)


@dataclass
class AvailableSizesType:
    """
    :ivar value:
    """
    value: List[Union[int, SmlxsizeType]] = field(
        default_factory=list,
        metadata=dict(
            min_occurs=0,
            max_occurs=9223372036854775807,
            min_inclusive=2.0,
            max_inclusive=18.0
        )
    )

Example 10-21 An array using markup

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="VectorType">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="e" type="xs:integer" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayType">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="r" type="VectorType" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="array" type="ArrayType" />
</xs:schema>
from dataclasses import dataclass, field
from typing import List


@dataclass
class VectorType:
    """
    :ivar e:
    """
    e: List[int] = field(
        default_factory=list,
        metadata=dict(
            type="Element",
            namespace="",
            min_occurs=1,
            max_occurs=9223372036854775807
        )
    )


@dataclass
class ArrayType:
    """
    :ivar r:
    """
    r: List[VectorType] = field(
        default_factory=list,
        metadata=dict(
            type="Element",
            namespace="",
            min_occurs=1,
            max_occurs=9223372036854775807
        )
    )


@dataclass
class Array(ArrayType):
    class Meta:
        name = "array"

Samples Source

Definitive XML Schema by Priscilla Walmsley (c) 2012 Prentice Hall PTR