How do I extend a base schema with custom elements while remaining open to change from new versions? How do I extend a base schema with custom elements while remaining open to change from new versions? xml xml

How do I extend a base schema with custom elements while remaining open to change from new versions?


When it comes to extending existing XML Schema, there are a few options.

Using the base schema

<?xml version="1.0" encoding="utf-8" ?><xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">    <xs:element name="Root" type="RootType" />    <xs:complexType name="RootType">        <xs:sequence>            <xs:element name="OriginalContent" />        </xs:sequence>    </xs:complexType></xs:schema>

Graphical schema representation

Extension/Restriction

You can extend/restrict a type, which effectively creates a new type with additional/less elements/attributes, however there is no way to force the use of this new type. The creator of the XML can tell you they are using their new type using the xsi:type="MyCustomType", but you can not insist its used.

<?xml version="1.0" encoding="utf-8" ?><xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">    <xs:include schemaLocation=".\Root.xsd" />    <xs:complexType name="MyNewRoot">        <xs:complexContent>            <xs:extension base="RootType">                <xs:sequence>                    <xs:element name="AdditionalElement" type="xs:string" />                </xs:sequence>            </xs:extension>        </xs:complexContent>    </xs:complexType></xs:schema>

Graphical schema representation

Sample XML File

<?xml version="1.0" encoding="utf-8"?><Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:noNamespaceSchemaLocation="Extension.xsd"       xsi:type="MyNewRoot">    <OriginalContent />    <AdditionalElement/></Root>

Graphical schema representation

Redefine

The other alternative is to use <redefine>. Basically replaces the definition of RootType, so wherever RootType appears our new version must now be used.

<?xml version="1.0" encoding="utf-8" ?><xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">    <xs:redefine schemaLocation="root.xsd">        <xs:complexType name="RootType">            <xs:complexContent>                <xs:extension base="RootType">                    <xs:sequence>                        <xs:element name="MyContent" type="xs:string" />                    </xs:sequence>                </xs:extension>            </xs:complexContent>        </xs:complexType>    </xs:redefine></xs:schema>

Sample XML File

<?xml version="1.0" encoding="utf-8"?><Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Redefine.xsd">    <OriginalContent></OriginalContent>    <MyContent>stuff</MyContent></Root>

Any

Another solution is to include a xs:any in the base elements definition. However, this is not possible if you don't control the base schema.

Open Content

** Only available in XSD 1.1 **

Open Content was added specifically to allow you to create open schemas, it has 2 'mode's interleave and suffix. When set to interleave additional elements (matching the contained xs:any clause) can be interleaved through out the element (before, between and after any of the existing elements). When in suffix mode then additional elements (matching the contained xs:any clause) can be added after the existing elements.

OpenContent can be applied to specific complexTypes or it can be applied at schema level, in which it applies to all the elements declared within it.

If you are using XSD 1.1, this is definitely the way to go in order to make your schemas extensible, however XSD 1.1 is still not well supported.

<xs:complexType name="BookType">    <xs:openContent mode="interleave">        <xs:any />    </xs:openContent>    <xs:sequence>        <xs:element name="Title"  type="xs:string" />        <xs:element name="Author" type="xs:string" maxOccurs="unbounded" />        <xs:element name="ISBN"   type="xs:string" />    </xs:sequence></xs:complexType>

Graphical schema representation

It should also be noted that if you interleave elements between runs of existing elements (i.e. Title, Author, NewElement, Author, ISBN), then most parsers will treat the second Author as a 'new' element and validate it using the openContent rules not the xs:element name="Author" type="xs:string", furthermore if the Author had a minOccurs of 2, this clause may fail as its seeing 1xAuthor, 1xNewElement, 1xAuthor and the first 1xAuthor does not for full the minoccurs clause.

Summary

All these methods have there ups and downs, but having a good XML Editor, makes it much easier to figure out what's going on.

I recommend Liquid XML Studio which is made by my company, as it has a good XSD Editor, can create sample XML from your schemas, making it easy to see the result of your work, also the XML Intellisense makes it easy to see the valid options.