Derivation By Union

Derivation by union allows defining datatypes by merging the lexical spaces of several predefined or user datatypes.

As we’ve seen with the derivation by list, W3C XML Schema has defined two syntaxes, both using a xs:union element, allowing a definition by reference to existing types or by embedding type definition (these two syntaxes can be mixed). The definition of a union datatype by reference to existing types is done through a memberType attribute containing a whitespace-separated list of datatypes:

<xs:simpleType name="integerOrDate">
  <xs:union memberTypes="xs:integer xs:date"/>
</xs:simpleType>

The definition of a union datatype can also be done by embedding one or more <xs:simpleType> elements:

<xs:simpleType name="myIntegerUnion">
  <xs:union>
    <xs:simpleType>
      <xs:restriction base="xs:integer"/>
    </xs:simpleType>
    <xs:simpleType>
      <xs:restriction base="xs:NMTOKEN">
        <xs:enumeration value="undefined"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:union>
</xs:simpleType>

Both styles can be mixed and the previous example can be written as:

<xs:simpleType name="myIntegerUnion">
  <xs:union memberTypes="xs:integer">
    <xs:simpleType>
      <xs:restriction base="xs:NMTOKEN">
        <xs:enumeration value="undefined"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:union>
</xs:simpleType>

The resulting datatype is a merge that, as a whole, has lost the semantical meaning—and facets—from the member types. In the earlier example, we couldn’t constrain the myIntegerUnion type to be either less than 100 or undefined except by defining a pattern. To do so, we can create a type derived by restriction from a built-in type to be less than 100, and perform the union to allow the value to be “undefined” afterward. The only two facets that can be applied to a union datatype are xs:pattern and xs:enumeration .

Those two facets are the only facets that are common to almost all the datatypes. The only exception is xs:enumeration , which is not allowed for xs:boolean . Defining a “dummy” union over an xs:boolean could be a workaround to define an xs:enumeration facet over this type.