Empty content models are elements that can only accept attributes. W3C XML Schema does not include any special support for empty content models, which can be considered either complex content models without elements or simple content models with a value restricted to the null string.
W3C
XML Schema considers empty
content models to be the intersection between complex content models
(in the case in which no compositors are specified) and simple
content models (in the case in which no text nodes are expected,
which W3C XML Schema handles as if an empty text node was found). We
will, therefore, be able to choose between the two methods to create
an empty content model. Where we extended our
title
element to become mixed content, we
carefully avoided adding empty elements, such as the HTML
img
or br
.
Let’s see how we could define a
br
element with its id
and
class
attributes using both methods.
This is done by defining a simple
type that can only accept the empty string as a value. Strictly
speaking, empty content models do not accept any whitespace between
their start and end tags. Since we want to control this, we must use
a datatype that does not alter the whitespaces, i.e.,
xs:string
. Our empty content model is then
derived by extension from this simple type:
<xs:simpleType name="empty"> <xs:restriction base="xs:string"> <xs:enumeration value=""/> </xs:restriction> </xs:simpleType> <xs:element name="br"> <xs:complexType> <xs:simpleContent> <xs:extension base="empty"> <xs:attribute name="id" type="xs:ID"/> <xs:attribute name="class" type="xs:NMTOKEN"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>
Each of the two empty content types keeps the derivation methods of its content model (simple or complex). The main difference between these two methods is essentially a matter of which derivations may be applied on the base type and what effect it will have.
If we try to remember and compare what we’ve learned about deriving complex and simple contents by extension, we can see that both allow addition of new attributes to the complex type. However, while we can add new subelements to complex content, we cannot change the type of the text node for a simple content model. Thus, this is the first difference between the two methods: when the empty content model is built on a simple type, it will not be possible to add anything other than attributes, while if it is built on top of a complex type, it will be possible to extend it to accept elements.
At
first
glance, it seems that there are fewer differences here. The
restriction methods of both simple and complex contents allow the
restriction the scope of the attributes; restricting the content,
which is already empty, doesn’t seem to be very
interesting. It’s time, though, to remember what
we’ve learned about a simple type derivation facet,
which actually extends the set of valid instance documents! The
“empty” simple type that we created
to derive our empty simple content model has a base type equal to
xs:string
. When this simple type is derived
through
xs:whiteSpace
, the result may be an expansion
of the sets of valid instance structures. In our case, setting
xs:whiteSpace
to
“collapse” has the effect of
accepting any sequence of whitespaces between the start and closing
tags. This new type is not “empty,”
strictly speaking, but may be useful for some (if not for most)
applications that are normalizing the whitespaces and do not make any
difference between these two cases. Such a derivation can be done on
the simple content complex type like this:
<xs:simpleType name="empty"> <xs:restriction base="xs:string"> <xs:enumeration value=""/> </xs:restriction> </xs:simpleType> <xs:complexType name="emptyBr"> <xs:simpleContent> <xs:extension base="empty"> <xs:attribute name="id" type="xs:ID"/> <xs:attribute name="class" type="xs:NMTOKEN"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:complexType name="allmostEmptyBr"> <xs:simpleContent> <xs:restriction base="emptyBr"> <xs:whiteSpace value="collapse"/> <xs:attribute name="id" type="xs:ID"/> <xs:attribute name="class" type="xs:NMTOKEN"/> </xs:restriction> </xs:simpleContent> </xs:complexType>
As we have seen, choosing a simple or complex type doesn’t make an awful lot of difference, except for extensibility. If we want to keep the possibility of adding subelements by derivation in the content model, we’d better choose an empty complex content model. However, if we want to be able to accept whitespaces in a derived type, an empty simple content model is a better bet.