Substitution groups and their effects on type derivation

If you’ve been playing with Xml schema collections in SQL Server 2005, you might have noticed that it is forbidden to expand substitution groups membership in ALTER XML SCHEMA COLLECTION statements.

What this mean practically is that already-persisted elements should not be used as substitution group heads when altering a collection

Fro example, this is valid

CREATE XML SCHEMA COLLECTION SC1 AS '
<schema xmlns="https://www.w3.org/2001/XMLSchema"
targetNamespace="myNS"
xmlns:ns="myNS">

 <element name="Head" type="decimal"/>

 <element name="member1" substitutionGroup="ns:Head"/>

</schema>
'
go

But the example below is invalid

CREATE XML SCHEMA COLLECTION SC2 AS '
<schema xmlns="https://www.w3.org/2001/XMLSchema"
targetNamespace="myNS"
xmlns:ns="myNS">

 <element name="Head" type="decimal"/>

</schema>
'
go

ALTER XML SCHEMA COLLECTION SC2 ADD '
<schema xmlns="https://www.w3.org/2001/XMLSchema"
targetNamespace="myNS"
xmlns:ns="myNS">

 <element name="member1" substitutionGroup="ns:Head"/>

</schema>
'
go

The last batch will fail with the following error message: “Invalid definition for element 'myNS:member1'. SQL Server does not currently permit additions to existing substitution groups via ALTER XML SCHEMA COLLECTION.”.
The reason for this is that adding members to a substitutionGroup might render previously defined type derivations invalid. Let’s look at a simple example.

create xml schema collection mySC AS '
<schema xmlns="https://www.w3.org/2001/XMLSchema" targetNamespace="https://ns" xmlns:ns="https://ns">

<element name="E" type="long"/>

 <complexType name="myCt1">
<sequence>
<element ref="ns:E"/>
</sequence>
</complexType>

 <complexType name="myCt2">
<complexContent>
<restriction base="ns:myCt1">
<choice>
<element ref="ns:E1"/>
<element name="E" form="qualified" type="byte"/>
</choice>
</restriction>
</complexContent>
</complexType>

<element name="E1" type="short" substitutionGroup="ns:E"/>

 <element name="E2" type="short" substitutionGroup="ns:E1"/>

</schema>'
go

This statement will fail with the following error: “Invalid restriction for type 'https://ns:myCt2'. Invalid model group restriction.”
It is the declaration of element E2 that causes the restriction from myCt1 to myCt2 to be invalid (because E2 could be substituted for E1 in any element of type myCt2)

Remove the element definition for E2 and the schema becomes valid, like this

create xml schema collection mySC AS '
<schema xmlns="https://www.w3.org/2001/XMLSchema" targetNamespace="https://ns" xmlns:ns="https://ns">

<element name="E" type="long"/>

 <complexType name="myCt1">
<sequence>
<element ref="ns:E"/>
</sequence>
</complexType>

 <complexType name="myCt2">
<complexContent>
<restriction base="ns:myCt1">
<choice>
<element ref="ns:E1"/>
<element name="E" form="qualified" type="byte"/>
</choice>
</restriction>
</complexContent>
</complexType>

<element name="E1" type="short" substitutionGroup="ns:E"/>

</schema>'
go

The problem is, now we could very well try to add E2 to the schema collection, like this

alter xml schema collection mySC ADD '
<schema xmlns="https://www.w3.org/2001/XMLSchema" targetNamespace="https://ns" xmlns:ns="https://ns"> 

 <element name="E2" type="short" substitutionGroup="ns:E1"/>

</schema>'
go

The statement above would render the derivation by restriction from myCt1 to myCt2 illegal, even though the definitions of the types themselves remain the same.
This is in short why we prohibit the use of already-persisted elements as substitution groups heads.

-
Disclaimer:
This posting is provided “AS IS” with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.