Chapter 16: Substitution groups

Example 16-1 The head of a substitution group

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="items" type="ItemsType" />
  <xs:complexType name="ItemsType">
    <xs:sequence>
      <xs:element ref="product" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="product" type="ProductType" />
  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element name="number" type="xs:integer" />
      <xs:element name="name" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>
from dataclasses import dataclass, field
from typing import List, Optional


@dataclass
class ProductType:
    """
    :ivar number:
    :ivar name:
    """
    number: Optional[int] = field(
        default=None,
        metadata=dict(
            name="number",
            type="Element",
            namespace="",
            required=True
        )
    )
    name: Optional[str] = field(
        default=None,
        metadata=dict(
            name="name",
            type="Element",
            namespace="",
            required=True
        )
    )


@dataclass
class Product(ProductType):
    class Meta:
        name = "product"



@dataclass
class ItemsType:
    """
    :ivar product:
    """
    product: List[Product] = field(
        default_factory=list,
        metadata=dict(
            name="product",
            type="Element",
            min_occurs=1,
            max_occurs=9223372036854775807
        )
    )


@dataclass
class Items(ItemsType):
    class Meta:
        name = "items"

Example 16-10 Using block to prevent substitution group use

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="example1607.xsd" />
  <xs:element name="product" type="ProductType" block="#all" />
  <xs:element name="hat" type="HatType" block="substitution" />
</xs:schema>
from dataclasses import dataclass
from tests.fixtures.defxmlschema.chapter16.example1607 import (
    HatType,
)
from tests.fixtures.defxmlschema.chapter22.example2207 import (
    ProductType,
)


@dataclass
class Hat(HatType):
    class Meta:
        name = "hat"



@dataclass
class Product(ProductType):
    class Meta:
        name = "product"

Example 16-2 Members of a substitution group

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="chapter16.xsd" />
  <xs:element name="shirt" type="ShirtType" substitutionGroup="product" />
  <xs:complexType name="ShirtType">
    <xs:complexContent>
      <xs:extension base="ProductType">
        <xs:sequence>
          <xs:element name="size" type="ShirtSizeType" />
          <xs:element name="color" type="xs:string" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="hat" substitutionGroup="product">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="ProductType">
          <xs:sequence>
            <xs:element name="size" type="HatSizeType" />
          </xs:sequence>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  <xs:element name="umbrella" substitutionGroup="product" />
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional
from tests.fixtures.defxmlschema.chapter16.chapter16 import (
    HatSizeType,
    ProductType,
    ShirtSizeType,
)


@dataclass
class Umbrella:
    """
    :ivar any_element:
    """
    class Meta:
        name = "umbrella"

    any_element: Optional[object] = field(
        default=None,
        metadata=dict(
            type="Any",
            required=True
        )
    )


@dataclass
class ShirtType(ProductType):
    """
    :ivar size:
    :ivar color:
    """
    size: Optional[ShirtSizeType] = field(
        default=None,
        metadata=dict(
            name="size",
            type="Element",
            namespace="",
            required=True
        )
    )
    color: Optional[str] = field(
        default=None,
        metadata=dict(
            name="color",
            type="Element",
            namespace="",
            required=True
        )
    )


@dataclass
class Hat(ProductType):
    """
    :ivar size:
    """
    class Meta:
        name = "hat"

    size: Optional[HatSizeType] = field(
        default=None,
        metadata=dict(
            name="size",
            type="Element",
            namespace="",
            required=True
        )
    )


@dataclass
class Shirt(ShirtType):
    class Meta:
        name = "shirt"

Example 16-4 Substitution group with simple types

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="number" />
  <xs:element name="skuNumber" type="xs:string" substitutionGroup="number" />
  <xs:element name="productID" type="xs:integer" substitutionGroup="number" />
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional


@dataclass
class Number:
    """
    :ivar any_element:
    """
    class Meta:
        name = "number"

    any_element: Optional[object] = field(
        default=None,
        metadata=dict(
            type="Any",
            required=True
        )
    )


@dataclass
class ProductId:
    """
    :ivar value:
    """
    class Meta:
        name = "productID"

    value: Optional[int] = field(
        default=None,
        metadata=dict(
            name="value",
            type="Extension",
            required=True
        )
    )


@dataclass
class SkuNumber:
    """
    :ivar value:
    """
    class Meta:
        name = "skuNumber"

    value: Optional[str] = field(
        default=None,
        metadata=dict(
            name="value",
            type="Extension",
            required=True
        )
    )

Example 16-5 A member of two substitution groups

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="example1607.xsd" />
  <xs:element name="product" type="ProductType" />
  <xs:element name="discontinuedProduct" type="ProductType" />
  <xs:element name="hat" type="HatType" substitutionGroup="product" />
  <xs:element name="shirt" type="ShirtType" substitutionGroup="product" />
  <xs:element name="umbrella" type="UmbrellaType" substitutionGroup="product discontinuedProduct" />
</xs:schema>
from dataclasses import dataclass
from tests.fixtures.defxmlschema.chapter16.example1607 import (
    HatType,
    ShirtType,
    UmbrellaType,
)
from tests.fixtures.defxmlschema.chapter22.example2207 import (
    ProductType,
)


@dataclass
class DiscontinuedProduct(ProductType):
    class Meta:
        name = "discontinuedProduct"



@dataclass
class Hat(HatType):
    class Meta:
        name = "hat"



@dataclass
class Product(ProductType):
    class Meta:
        name = "product"



@dataclass
class Shirt(ShirtType):
    class Meta:
        name = "shirt"



@dataclass
class Umbrella(UmbrellaType):
    class Meta:
        name = "umbrella"

Example 16-6 Using a choice group

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="../chapter16/example1607.xsd" />
  <xs:element name="items" type="ItemsType" />
  <xs:complexType name="ItemsType">
    <xs:group ref="ProductGroup" maxOccurs="unbounded" />
  </xs:complexType>
  <xs:group name="ProductGroup">
    <xs:choice>
      <xs:element name="product" type="ProductType" />
      <xs:element name="shirt" type="ShirtType" />
      <xs:element name="hat" type="HatType" />
      <xs:element name="umbrella" type="ProductType" />
    </xs:choice>
  </xs:group>
</xs:schema>
from dataclasses import dataclass, field
from typing import List
from tests.fixtures.defxmlschema.chapter16.example1607 import (
    HatType,
    ShirtType,
)
from tests.fixtures.defxmlschema.chapter22.example2207 import (
    ProductType,
)


@dataclass
class ItemsType:
    """
    :ivar product:
    :ivar shirt:
    :ivar hat:
    :ivar umbrella:
    """
    product: List[ProductType] = field(
        default_factory=list,
        metadata=dict(
            name="product",
            type="Element",
            namespace="",
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )
    shirt: List[ShirtType] = field(
        default_factory=list,
        metadata=dict(
            name="shirt",
            type="Element",
            namespace="",
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )
    hat: List[HatType] = field(
        default_factory=list,
        metadata=dict(
            name="hat",
            type="Element",
            namespace="",
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )
    umbrella: List[ProductType] = field(
        default_factory=list,
        metadata=dict(
            name="umbrella",
            type="Element",
            namespace="",
            min_occurs=0,
            max_occurs=9223372036854775807
        )
    )

Example 16-7 Defining derived types

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="../chapter22/example2207.xsd" />
  <xs:complexType name="ShirtType">
    <xs:complexContent>
      <xs:extension base="ProductType">
        <xs:sequence>
          <xs:element name="size" type="xs:int" />
          <xs:element name="color" type="xs:string" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="HatType">
    <xs:complexContent>
      <xs:extension base="ProductType">
        <xs:sequence>
          <xs:element name="size" type="xs:int" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="UmbrellaType">
    <xs:complexContent>
      <xs:extension base="ProductType" />
    </xs:complexContent>
  </xs:complexType>
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional
from tests.fixtures.defxmlschema.chapter22.example2207 import (
    ProductType,
)


@dataclass
class HatType:
    """
    :ivar number:
    :ivar name:
    :ivar size:
    """
    number: Optional[int] = field(
        default=None,
        metadata=dict(
            name="number",
            type="Element",
            namespace="",
            required=True
        )
    )
    name: Optional[str] = field(
        default=None,
        metadata=dict(
            name="name",
            type="Element",
            namespace="",
            required=True
        )
    )
    size: Optional[int] = field(
        default=None,
        metadata=dict(
            name="size",
            type="Element",
            namespace="",
            required=True
        )
    )


@dataclass
class ShirtType:
    """
    :ivar number:
    :ivar name:
    :ivar size:
    :ivar color:
    """
    number: Optional[int] = field(
        default=None,
        metadata=dict(
            name="number",
            type="Element",
            namespace="",
            required=True
        )
    )
    name: Optional[str] = field(
        default=None,
        metadata=dict(
            name="name",
            type="Element",
            namespace="",
            required=True
        )
    )
    size: Optional[int] = field(
        default=None,
        metadata=dict(
            name="size",
            type="Element",
            namespace="",
            required=True
        )
    )
    color: Optional[str] = field(
        default=None,
        metadata=dict(
            name="color",
            type="Element",
            namespace="",
            required=True
        )
    )


@dataclass
class UmbrellaType(ProductType):
    pass

Example 16-9 Using final to control substitution group declaration

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="example1606.xsd" />
  <xs:include schemaLocation="../chapter13/example13011.xsd" />
  <xs:element name="product" type="ProductType" final="#all" />
  <xs:element name="items" type="ItemsType" final="extension" />
  <xs:element name="color" type="xs:string" final="restriction" />
  <xs:element name="size" type="SizeType" final="" />
</xs:schema>
from dataclasses import dataclass, field
from typing import Optional
from tests.fixtures.defxmlschema.chapter16.example1606 import (
    ItemsType,
)
from tests.fixtures.defxmlschema.chapter22.example2207 import (
    ProductType,
)
from tests.fixtures.defxmlschema.chapter13.example13011 import (
    SizeType,
)


@dataclass
class Color:
    """
    :ivar value:
    """
    class Meta:
        name = "color"

    value: Optional[str] = field(
        default=None,
        metadata=dict(
            name="value",
            type="Extension",
            required=True
        )
    )


@dataclass
class Items(ItemsType):
    class Meta:
        name = "items"



@dataclass
class Product(ProductType):
    class Meta:
        name = "product"



@dataclass
class Size(SizeType):
    class Meta:
        name = "size"

Samples Source

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