Guideline:Schema development

From BioSchemas

Contents

Extension points and the empty namespace

Extension points should not only permit elements from a foreign namespace but also from the empty namespace. In addition extension elements should be located before the regular elements:

<xs:sequence>
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:any namespace="##other" processContents="lax"/>
    <xs:any namespace="##local" processContents="lax"/>
  </xs:choice>
  <xs:element name="subelement" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>

Optional attribute and key declarations

Optional attributes without a default value should not be used within a key declaration as a key field because a key requires every field to be set on the selected element. Thus it is best practice to declare an enumeration value ##missing for the default value:

<xs:simpleType name="missing">
  <xs:restriction base="xs:token">
    <xs:enumeration value="##missing"/>
  </xs:restriction>  
</xs:simpleType>

The attribute type should be declared this way:

<xs:simpleType name="key">
  <xs:union memberTypes="xs:token missing"/>
</xs:simpleType>

The attribute itself must use this type:

<xs:attribute name="key" type="key" use="optional" default="##missing"/>

The key may then be declared this way:

<xs:key name="key">
  <xs:selector xpath="element"/>
  <xs:field xpath="@key"/>
</xs:key>

Namespace declaration for the schema itself

Every schema should declare its namespace using a prefix and not the default namespace (without prefix):

 
<xs:schema 
  targetNamespace="http://schemas.bioservices.net/2005/biotypes/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:bt="http://schemas.bioservices.net/2005/biotypes/" 
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified"
  id="biotypes" version="0.1"
>

Otherwise you won't be able to declare keys and unique constraints using XPath, because XPath maps the default namespace to the empty namespace (xmlns=""):

 
  <xs:element name="source" type="bt:source">
    <xs:key name="sourceItemKey">
      <xs:annotation><xs:documentation>
      </xs:documentation></xs:annotation>
      <xs:selector xpath="./bt:item"/>
      <xs:field xpath="@name"/>
    </xs:key>
  </xs:element>

However attributes belong to the empty namespace as long as you do not qualify them! That's why you have to omit the prefix for attributes in XPath expressions.

Nillable root elements

Root elements should be nillable, so that e.g. web services can return an empty document for a query that does not match anything without violating the schema's specification:

 
<xs:element name="root" nillable="true">
...

It's not a good design to mark the subordinated elements as optional. Instead allow the root element to be nillable and set in the root element the xsi:nil attribute to true:

 
<root
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:nil="true"
/>

xml:* Attributes

Every element you declare should explicitly allow the xml:* attributes, especially the xml:base attribute. The latter is required for XInclude as described here.

To allow the xml:* attributes or any other attributes from a foreign namespace include the following declaration in your type or element definition:

<xs:anyAttribute namespace="##other" processContents="lax"/>

See also

Personal tools
partners