How to extend the basic layout with customizable elements while staying open to upgrade from new versions?

Given the XSD as follows:

<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:std="http://..." targetNamespace="..."> <xs:element name="SomeRootNode" type="std:SomeRootNodeType" /> ... </xs:schema> 

which defines some elements that allow any child from another namespace.

I want to expand this schema with my own and insert child elements and attributes of certain elements in the base document. For example, myElementX or myAttributeY must have a parent node std: SomeRootNode. Then, the merged document should allow any third parties to continue to expand the document in any way that is already resolved by the base schema, but for the elements and attributes from my namespace, I want to check that all the elements and attributes have the correct parent nodes and are displayed only in allowed places in the base document.

How can this be achieved?

I hope that there is a clean solution that does not resort to redefining the basic scheme that I am expanding. I want to be able to adapt easily if new versions of the base schema are released. I do not want to change my version with new overrides every time a new version of the base document is released (unless it has changes for my design).

+6
xml xsd xsd-validation
source share
1 answer

When it comes to extending an existing XML schema, there are several options.

Using the basic scheme

 <?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

You can expand / restrict the type that effectively creates a new type with additional / smaller elements / attributes, however there is no way to force the use of this new type. An XML creator can tell you that it uses a new type using xsi: type = "MyCustomType", but you cannot insist on using it.

 <?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

XML file example

 <?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

Override

Another alternative is to use <redefine> . It basically replaces the definition of RootType, so wherever RootType appears, our new version should 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> 

XML file example

 <?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> 

Everything

Another solution is to include xs:any in the definition of the underlying elements. However, this is not possible if you are not in control of the basic scheme.

Open content

** Available only in XSD 1.1 **

Open content has been added specifically so you can create open circuits, it has a 2 'mode of alternation and suffix. When alternating additional elements (matching the contained xs: any clause) is specified, you can alternate the element (before, between, and after any of the existing elements). In suffix mode, additional elements can be added after existing elements (corresponding to the contained position xs: any).

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

If you are using XSD 1.1, this is definitely a way to make your circuits extensible, however XSD 1.1 is still not 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 representation of the circuit

It should also be noted that if you alternate elements between runs of existing elements (ie Title, Author, NewElement, Author, ISBN), then most parsers will consider the second author as a β€œnew” element and check it with openContent is not an element xs: element name = "Author" type = "xs: string", in addition, if the author had minOccurs of 2, this section may fail because his vision is 1xAuthor, 1xNewElement, 1xAuthor and the first 1xAuthor is not for the full minoccurs clause .

Summary

All of these methods have ups and downs, but with a good XML Editor, figuring out what happens is greatly simplified.

I recommend Liquid XML Studio , created by my company , because it has a good XSD editor, can create an XML sample from your schemas, which will simplify viewing the result of your work, and XML Intellisense makes it easy to view valid options.

+11
source share

All Articles