Chapter 16¶
Substitution groups¶
Binding Test¶
Schema
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation>
This example illustrates substitution groups.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="items" type="ItemsType"/>
<xsd:complexType name="ItemsType">
<xsd:sequence>
<xsd:element ref="product" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="product" type="ProductType"/>
<xsd:complexType name="ProductType">
<xsd:sequence>
<xsd:element name="number" type="xsd:integer"/>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="shirt" type="ShirtType"
substitutionGroup="product"/>
<xsd:complexType name="ShirtType">
<xsd:complexContent>
<xsd:extension base="ProductType">
<xsd:sequence>
<xsd:element name="size" type="ShirtSizeType"/>
<xsd:element name="color" type="ColorType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="hat" substitutionGroup="product">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="ProductType">
<xsd:sequence>
<xsd:element name="size" type="HatSizeType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="umbrella" substitutionGroup="product"/>
<xsd:complexType name="ShirtSizeType">
<xsd:simpleContent>
<xsd:extension base="xsd:integer">
<xsd:attribute name="system" type="xsd:token"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="HatSizeType">
<xsd:simpleContent>
<xsd:extension base="xsd:token">
<xsd:attribute name="system" type="xsd:token"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="ColorType">
<xsd:attribute name="value" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
XML Document
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="chapter16.xsd">
<product>
<number>999</number>
<name>Special Seasonal</name>
</product>
<shirt>
<number>557</number>
<name>Short-Sleeved Linen Blouse</name>
<size>10</size>
<color value="blue"/>
</shirt>
<hat>
<number>563</number>
<name>Ten-Gallon Hat</name>
<size>L</size>
</hat>
<umbrella>
<number>443</number>
<name>Deluxe Golf Umbrella</name>
</umbrella>
</items>
xsData XML Document
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<umbrella>
<number>443</number>
<name>Deluxe Golf Umbrella</name>
</umbrella>
<hat>
<number>563</number>
<name>Ten-Gallon Hat</name>
<size>L</size>
</hat>
<shirt>
<number>557</number>
<name>Short-Sleeved Linen Blouse</name>
<size>10</size>
<color value="blue"/>
</shirt>
<product>
<number>999</number>
<name>Special Seasonal</name>
</product>
</items>
xsData JSON
{
"umbrella": [
{
"any_element": {
"qname": null,
"text": null,
"tail": null,
"ns_map": {},
"children": [
{
"qname": "number",
"text": "443",
"tail": null,
"ns_map": {
"xsi": "http://www.w3.org/2001/XMLSchema-instance"
},
"children": [],
"attributes": {}
},
{
"qname": "name",
"text": "Deluxe Golf Umbrella",
"tail": null,
"ns_map": {
"xsi": "http://www.w3.org/2001/XMLSchema-instance"
},
"children": [],
"attributes": {}
}
],
"attributes": {}
}
}
],
"hat": [
{
"number": 563,
"name": "Ten-Gallon Hat",
"size": {
"value": "L",
"system": null
}
}
],
"shirt": [
{
"number": 557,
"name": "Short-Sleeved Linen Blouse",
"size": {
"value": 10,
"system": null
},
"color": {
"value": "blue"
}
}
],
"product": [
{
"number": 999,
"name": "Special Seasonal"
}
]
}
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(
type="Element",
namespace="",
required=True
)
)
name: Optional[str] = field(
default=None,
metadata=dict(
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(
type="Element",
min_occurs=1,
max_occurs=9223372036854775807
)
)
@dataclass
class Items(ItemsType):
class Meta:
name = "items"
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="Wildcard",
namespace="##any",
required=True
)
)
@dataclass
class ShirtType(ProductType):
"""
:ivar size:
:ivar color:
"""
size: Optional[ShirtSizeType] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
color: Optional[str] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
@dataclass
class Hat(ProductType):
"""
:ivar size:
"""
class Meta:
name = "hat"
size: Optional[HatSizeType] = field(
default=None,
metadata=dict(
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="Wildcard",
namespace="##any",
required=True
)
)
@dataclass
class ProductId:
"""
:ivar value:
"""
class Meta:
name = "productID"
value: Optional[int] = field(
default=None,
metadata=dict(
required=True
)
)
@dataclass
class SkuNumber:
"""
:ivar value:
"""
class Meta:
name = "skuNumber"
value: Optional[str] = field(
default=None,
metadata=dict(
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(
type="Element",
namespace="",
min_occurs=0,
max_occurs=9223372036854775807
)
)
shirt: List[ShirtType] = field(
default_factory=list,
metadata=dict(
type="Element",
namespace="",
min_occurs=0,
max_occurs=9223372036854775807
)
)
hat: List[HatType] = field(
default_factory=list,
metadata=dict(
type="Element",
namespace="",
min_occurs=0,
max_occurs=9223372036854775807
)
)
umbrella: List[ProductType] = field(
default_factory=list,
metadata=dict(
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(
type="Element",
namespace="",
required=True
)
)
name: Optional[str] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
size: Optional[int] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
@dataclass
class ShirtType:
"""
:ivar number:
:ivar name:
:ivar size:
:ivar color:
"""
number: Optional[int] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
name: Optional[str] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
size: Optional[int] = field(
default=None,
metadata=dict(
type="Element",
namespace="",
required=True
)
)
color: Optional[str] = field(
default=None,
metadata=dict(
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(
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"
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"
Samples Source
Definitive XML Schema by Priscilla Walmsley (c) 2012 Prentice Hall PTR