XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Extensibility, XML Vocabularies, and XML Schema
by David Orchard | Pages: 1, 2, 3, 4, 5, 6

Version Strategy

All new components in existing or new namespace(s) for each version and a version identifier(#4)

Using a version identifier, the name instances would change to show the version of the name they use, such as:

<name xmlns="http://www.openuri.org/name/1" version="1.0">
<first>Dave</first>
  <last>Orchard</last>
</name>
<name xmlns="http://www.openuri.org/name/1" version="1.0">
  <first>Dave</first>
  <last>Orchard</last>
  <middle>Bryce</middle>
</name>
<name xmlns="http://www.openuri.org/name/1" version="1.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" version="1.0">
  <first>Dave</first>
  <last>Orchard</last>
  <pref2:prefix xmlns:pref2="http://www.example.org/name/pref/1">Mr.</pref2:prefix>
</name>

<name xmlns="http://www.openuri.org/name/1" version="2.0">
  <first>Dave</first>
  <last>Orchard</last>
  <pref1:prefix xmlns:pref1="http://www.openuri.org/name/pref/1">Mr.</pref1:prefix>
</name>

Example 8 – New components in existing or new namespace(s) with version identifier instances

The last example shows that the prefix is now a mandatory part of the name. As with Design #2, the schema for the optional prefix cannot fully express the content model. A schema for the mandatory prefix 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"
      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"/>
      <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 9 – New components in existing or new namespace(s) with version identifier schema v2, incompatible change

A significant downside with using version identifiers is that software that supports both versions of the name must perform special processing on top of XML and namespaces. For example, many components “bind” XML types into particular programming language types. Custom software must process the version attribute before using any of the “binding” software. In web services, toolkits often take SOAP body content, parse it into types and invoke methods on the types. There are rarely “hooks” for the custom code to intercept processing between the “SOAP” processing and the “name” processing. Further, if version attributes are used by any third-party extensions – say pref:prefix has a version – then the schema cannot refer to the correct prefix.

Version Strategy

All new components in existing or new namespace(s) for each compatible version(#3)

It is possible to create schemas with additional optional components. This requires reusing the namespace name for optional components and special schema design techniques. The reusing namespace rule is:

8. Re-use namespace names rule: If a backwards compatible change can be made to a specification, then the old namespace name SHOULD be used in conjunction with XML’s extensibility model.

An important conclusion is that a new namespace name is not required whenever a specification evolves, only if an incompatible change is made.

9. New namespaces to break rule: A new namespace name is used when backwards compatibility is not permitted, that is software MUST break if it does not understand the new language components.

Example #2 showed that it is not possible to have a wildcard with ##any (or even ##targetnamespace) following optional elements in the target namespace. The solution to this problem is to introduce an element in the schema that will always appear if the extension appears. The content model of the extensibility point is then the element + the extension. There are two styles for this. The first was published in an earlier version of this article in December 2003. It uses an extensibility element with the extensions nested inside. The second was published in July 2004, then updated on MSDN. It uses a Sentry or Marker element with extensions following it.

A name type with extension elements 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"/>
      <s:element name="Extension" type="name:ExtensionType" 
             minOccurs="0" maxOccurs="1"/>
      <xs:any namespace="##other" processContents="lax"
            minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType>
  
  <xs:complexType name="ExtensionType">
    <xs:sequence>
      <xs:any processContents="lax" minOccurs="1" 
             maxOccurs="unbounded" namespace="##targetnamespace"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType> 
</xs:schema>

Example 10 – New components in existing or new namespace(s) with Extension Type Schema version 1

Because each extension in the target namespace is inside an extension element, each subsequent target namespace extensions will increase nesting by another layer. While this layer of nesting per extension is not desirable, it is what can be accomplished today when applying strict XML Schema validation.

It seems to at least this author that potentially having multiple nested elements is worthwhile if multiple compatible revisions can be made to a language. This technique allows validation of extensions in the target namespace and retaining validation of the target namespace itself.

The previous schema allows the following sample name:

<name xmlns="http://www.openuri.org/name/1">
  <first>Dave</first>
  <last>Orchard</last>
  <Extension>
    <prefix>Mr.</prefix>
  </Extension>
</name>

Example 11 – New components in existing or new namespace(s) with Extension Type instances

The namespace author can create a schema for this type:

<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"/>
      <s:element name="Extension" type="name:PrefixExtensionType" 
             minOccurs="0" maxOccurs="1"/>
      <xs:any namespace="##other" processContents="lax"
            minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType>
  <xs:complexType name="PrefixExtensionType">
    <xs:sequence>
       <xs:element name="prefix" type="xs:string"/>
       <xs:element name="Extension" type="name:PrefixExtensionType" 
       "FR">minOccurs="0" maxOccurs="1"/>
   </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType> 
  <xs:complexType name="ExtensionType">
    <xs:sequence>
      <xs:any processContents="lax" minOccurs="1" 
             maxOccurs="unbounded" namespace="##targetnamespace"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType> 
</xs:schema>

Example 12 – New components in existing or new namespace(s) with Extension Type Schema version 2

The advantage of this design technique is that a forwards- and backwards-compatible schema V2 can be written. The V2 schema can validate documents with or without the prefix, and the V1 schema can validate documents with or without the prefix.

Further, the reuse of the same namespace has better tooling support. Many applications use a single schema to create the equivalent programming constructs. These tools often work best with single namespace support for the “generated” constructs. The reuse of the namespace name allows at least the namespace author to make changes to the namespace and perform validation of the extensions.

An obvious downside of this approach is the complexity of the schema design. Another downside is that changes are linear, so two potentially parallel extensions must be nested rather than parallel.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow