Extensibility, XML Vocabularies, and XML Schema
by David Orchard
|
Pages: 1, 2, 3, 4, 5, 6
Versioning
A language designer decides how new versions of their language, as well as extensions, are related to previous versions. They decide how to use namespace names, component names for their language, as well as possibly introducing versioning-specific components such as version identifiers and incompatible extension identifiers. When a new version of a language is required, the author must make a decision about the namespace name for names in the new language.
Version identification has traditionally been done with a decimal separating the major versions from the minor versions, ie “8.1”, “1.0”. Often the definition of a “major” change is that it is incompatible, and the definition of a “minor” change is that it is forwards- and/or backwards-compatible.
Usually the first broadly available version starts at “1.0”. A compatible version change from 1.0 might be identified as “1.1” and an incompatible change as “2.0”. It should be noted that this is idealistic as there abundant cases where this system does not hold. New major version identifiers are often aligned with product releases, or incompatible changes identified as a “minor” change. A good example of an incompatible changed identified as a minor change is XML 1.1. XML 1.0 processors cannot process all XML 1.1 documents because XML 1.1 extended XML 1.0 where XML 1.0 does not allow such extension.
Version Identification Strategies
There are a large variety of version identification designs. A few of the most common are listed below and described in more detail later.
- All components in new namespace(s) for each version, ie version 1 consists of namespaces a + b, version 1.1 consists of namespaces c + d; or version 1 consists of namespace a, version 1.1 consists of namespace b.
- All new components in new namespace(s) for each compatible version, ie version 1 consists of namespaces a + b; version 1.1 consists of namespaces a + b + c; version 2.0 consists of namespaces d + e.
- All new components in existing or new namespace(s) for each compatible version, ie version 1 consists of namespace a, version 1.1 consists of namespace a, version 2 consists of namespace b; or version 1 consists of namespace a, version 1.1 consists of namespace a + b.
- All new components in existing or new namespace(s) for each version and a version identifier, ie version 1 consists of namespace a + b + version attribute “1”, version 2 consists of namespace c + d + version attribute “2”.
Whatever the design chosen, the language designer must decide the component name, namespace name, and any version identifier for new and all existing components. The tradeoffs between the decisions relate to the importance of:
- Supporting compatible evolution.
- Namespaces for identifying compatible components. Changing namespace names is typically a very invasive change
- A complete Schema for the language. We will see how some designs preclude full Schema description
- Use of generic XML and namespace only (precluding vocabulary specific versions) tools.
Elaborating on these designs is illustrative. The first option, new namespace(s) for each version, typically preclude compatible evolution, so we will not describe this in detail.
Version Strategy
All new components in new namespace(s) for each compatible version (#2)
Schema example 3 showed a schema that allowed new components in new namespace(s), so the following names would be valid:
<name xmlns="http://www.openuri.org/name/1">
<first>Dave</first>
<last>Orchard</last>
</name>
<name xmlns="http://www.openuri.org/name/1">
<first>Dave</first>
<last>Orchard</last>
<middle>Bryce</middle>
</name>
<name xmlns="http://www.openuri.org/name/1">
<first>Dave</first>
<last>Orchard</last>
<pref1:prefix xmlns:pref1="http://www.openuri.org/name/pref/1">Mr.</pref1:prefix>
</name>
<name xmlns="http://www.openuri.org/name/1">
<first>Dave</first>
<last>Orchard</last>
<pref2:prefix xmlns:pref2="http://www.example.org/name/pref/1">Mr.</pref2:prefix>
</name>
Example 4 – New components in new namespace(s) instances
The second example shows the use of the optional middle name in the name namespace. The third and fourth examples show an additional prefix element in two different namespace names. The first prefix, the third example, comes from a namespace name that is in the same domain as the name element’s namespace name. The fourth example shows a complete different namespace name for the prefix. It is probable that the pref1:prefix was created by the name author, and the pref2:prefix was created by a third party.
Using XML Schema, the name owner has three fairly unappealing options for the v2 schema for name and prefix, listed below and detailed subsequently:
- Optional prefix, extensibility retained, but name type does not refer to prefix;
- Optional prefix, extensibility is lost, name type refers to prefix;
- Required prefix, extensibility retained, name type refers to prefix but compatibility is lost;
If they leave the prefix as optional and retain the extensibility point, the best schema that they can write is:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.openuri.org/name/1"
xmlns:name="http://www.openuri.org/name/1">
<xs:complexType name="name">
<xs:sequence>
<xs:element name="first" type="xs:string"/>
<xs:element name="last" type="xs:string"/>
<xs:element name="middle" type="xs:string" minOccurs="0"/>
<xs:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.openuri.org/name/pref/1"
xmlns:pref="http://www.openuri.org/name/pref/1">
<xs:element name="prefix" type="xs:string"/>
</xs:schema>
Example 5 – New components in new namespace(s) schema V2, no change to name type
This is not a very helpful XML Schema change. The problem is that they cannot insert the reference to the optional pref:prefix element in the name schema and retain the extensibility point because of the aforementioned Non-Determinism Constraint.
The core of the problem is that there is no mechanism for constraining the content of a wildcard. For example, imagine that ns1 contains foo and bar. It is not possible to take the SOAP schema -- an example of a schema with a wildcard -- and require that ns1:foo element must be a child of the header element and ns1:bar must not be a child of the header element using just W3C XML Schema constructs. Indeed, the need for this functionality spawned some of the WSDL functionality.
They could decide to lose the extensibility point (option #2), such as:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.openuri.org/name/1"
xmlns:name="http://www.openuri.org/name/1"
xmlns:pref="http://www.openuri.org/name/pref/1">
<xs:complexType name="name">
<xs:sequence>
<xs:element name="first" type="xs:string"/>
<xs:element name="last" type="xs:string"/>
<xs:element name="middle" type="xs:string" minOccurs="0"/>
<xs:element ref="pref:prefix" minOccurs="0"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.openuri.org/name/pref/1"
xmlns:pref="http://www.openuri.org/name/pref/1">
<xs:element name="prefix" type="xs:string"/>
</xs:schema>
Example 6 – New components in new namespace(s) schema V2, no extensibility
The final option, #3, is adding required prefix. They must indicate the change is incompatible. A new namespace name for the name element can be created, shown below.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.openuri.org/name/2"
xmlns:name="http://www.openuri.org/name/2">
<xs:complexType name="name">
<xs:sequence>
<xs:element name="first" type="xs:string"/>
<xs:element name="last" type="xs:string"/>
<xs:element name="middle" type="xs:string" minOccurs="0"/>
<xs:element name="prefix" type="xs:string"/>
<xs:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:schema>
Example 7 – New components in new namespace(s) schema V2, incompatible change
However, this breaks compatibility, which is often very undesirable.
The downsides of the three options for new components in new namespace name(s) design have been described. Additionally, the design can result in specifications and namespaces that are inappropriately factored, as related constructs will be in separate namespaces.