[Top] [Contents]
10 - Defining More Restricted Simple Types
The XML Schema specification defines a number of simple types. However, in a number of cases you may wish to use more restricted simple types. For example, you may wish to limit the range of an integer to specific values, and restrict the length of a string. This section briefly describes how to do that.
The simple types defined in XML Schema can be further restricted using what are called facets. The XML Schema specification defines which facets can be applied to each simple type.
The XML Schema facets are: xs:length, xs:minLength, xs:maxLength, xs:pattern, xs:enumeration, xs:whiteSpace, xs:maxInclusive, xs:maxExclusive, xs:minExclusive, xs:minInclusive, xs:totalDigits, xs:fractionDigits. We will only explain a few of these facets here.
The general form for restricting a simple type is:
<xs:simpleType name="MyNewType">
<xs:restriction base="...type being restrict...">
...restricting facets...
</xs:restriction>
</xs:simpleType>
Here, the type specified by the base attribute is the initial type from which the new type is being derived (by restriction).
Perhaps the most useful types to restrict are the integers and xs:string.
The most common restriction of an integer is to limit the range of valid values it can take. This can be done using the xs:maxInclusive, xs:maxExclusive, xs:minExclusive, xs:minInclusive facets. For example, to limit an integer to the range 0 <= x <= 100, you can do:
<xs:simpleType name="My0to100IntType">
<xs:restriction base="xs:int">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
Or, to limit an integer to the range 0 < x < 100, you can do:
<xs:simpleType name="MyEx0to100IntType">
<xs:restriction base="xs:int">
<xs:minExclusive value="0"/>
<xs:maxExclusive value="100"/>
</xs:restriction>
</xs:simpleType>
Note that it is legal to restrict a value that has already been restricted. For example, you may choose to define a type that is a restriction of xs:int to the range 0 to 100. You could then define a further type that restricted this new type to the range 0 to 10. This could be done by doing:
<xs:simpleType name="My0to100IntType">
<xs:restriction base="xs:int">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="My0to10IntType">
<xs:restriction base="My0to100IntType">
<xs:maxInclusive value="10"/>
</xs:restriction>
</xs:simpleType>
Note that the order of definitions in XML schema is not important, so this could equally be written as:
<xs:simpleType name="My0to10IntType">
<xs:restriction base="My0to100IntType">
<xs:maxInclusive value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="My0to100IntType">
<xs:restriction base="xs:int">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
The most common restrictions applied to strings is to their lengths, and the patterns they are allowed. Restricting a string may also be used to define an enumerated value.
To restrict the length of a string, you can do:
<xs:simpleType name="My0to100CharStringType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
To limit the valid patterns of a string, you can do:
<xs:simpleType name="MyPatternCharStringType">
<xs:restriction base="xs:string">
<xs:pattern value="ABC\d+"/>
</xs:restriction>
</xs:simpleType>
Here, the value of the value attribute contains a Perl-like regular expression. The main difference is that the specified regular expression is implicitly anchored to the beginning and end of the string being matched, so that the whole XML instance value must match the pattern, not just a fragment of it. Put another way, if converted to Perl, the pattern above would become ^ABC\d+$.
Multiple facets can be applied to a type at the same time, so you can do:
<xs:simpleType name="MyPattern0to10CharStringType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="10"/>
<xs:pattern value="ABC\d+"/>
</xs:restriction>
</xs:simpleType>
In this case, all the constraints applied to a type using facets must all be valid in an XML instance.
Another common case of applying restrictions to strings is forming enumerations. This can be done as:
<xs:simpleType name="MyGenderType">
<xs:restriction base="xs:string">
<xs:enumeration value="Female"/>
<xs:enumeration value="Male"/>
</xs:restriction>
</xs:simpleType>
With the above example, the string is only allowed to be "Female" or "Male". For example, if you have an element definition of:
<xs:element name="MyElement" type="MyGenderType"/>
The only valid instances of this are:
<MyElement>Female</MyElement>
or:
<MyElement>Male</MyElement>
Note that with enumerations it is very important to consider what will happen when you want to upgrade your schema to the next version. Using the form above, it would be illegal to add an additional enumeration value in a subsequent version of the schema. (Check for other tutorials in our series for how this might be made possible.) Thus it is important to make sure that when using the definition method described here, the enumerated values are a closed set that will provably not need extending at a later date.
[Top] [Contents]
11 - Defining Elements (Part 2) - Defining Elements using Local Types
For simplicity we have chosen to separate definition of elements from the definition of types. Element definitions are then linked to type definitions using the form:
<xs:element name="MyElement" type="...Type..."/>
In general, this is a good approach.
You may wish to combine a type definition with an element definition. This is called a local type.
To define a local type you basically remove the type attribute from the element definition, remove the name attribute from the type definition, and move the type definition into the body of the element definition. For example, instead of:
<xs:element name="MyElement" type="MyGenderType"/>
<xs:simpleType name="MyGenderType">
<xs:restriction base="xs:string">
<xs:enumeration value="Female"/>
<xs:enumeration value="Male"/>
</xs:restriction>
</xs:simpleType>
You use:
<xs:element name="MyElement">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Female"/>
<xs:enumeration value="Male"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Now more about the nature of element and types definitions has been covered, we can present a more complete example of a schema. For this we reproduce the example given earlier.
As you can see, we've made the element definitions and type definitions section more complete here.