Using W3C XML Schema - Part 2
by Eric van der Vlist
|
Pages: 1, 2, 3, 4, 5
Namespaces
|
Table of Contents |
|
Content Types |
Namespace support in W3C XML Schema is flexible yet straightforward. It not only allows the use of any prefix in instance documents (unlike DTDs), but also lets you open your schemas to accept unknown elements and attributes from known or unknown namespaces.
Each W3C XML Schema document is bound to a specific namespace through the
targetNamespace attribute or to the absence of namespace
through the lack of such an attribute. We need at least one schema document
per namespace we want to define (elements and attributes without namespaces
can be defined in any schema, though).
Until now we have omitted the targetNamespace attribute,
which means that we were working without namespaces. To get into namespaces,
let's imagine that our example belongs to a single namespace.
<book isbn="0836217462" xmlns="http://example.org/ns/books/">
The least intrusive way to adapt our schema is to add more attributes to
our xsd:schema element.
<xsd:schema
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns="http://example.org/ns/books/"
targetNamespace="http://example.org/ns/books/"
elementFormDefault="qualified"
attributeFormDefault="unqualified" >
The namespace declarations play an important role. The first
(xmlns:xsd="http://www.w3.org/2000/10/XMLSchema") says not only
that we've chosen to use the prefix xsd to identify the
elements that will be W3C XML Schema instructions, but also that we will
prefix the W3C XML Schema predefined datatypes with xsd, as we
have done in all our examples thus far. Understand that we could have chosen
any prefix instead of xsd. We could even make
http://www.w3.org/2000/10/XMLSchema our default namespace. In this
case, we would not have prefixed the W3C XML Schema elements.
Since we are working with the http://example.org/ns/books/ namespace, we define it as our default namespace. This means that we won't prefix the references to objects (datatypes, elements, attributes, etc.) belonging to this namespace. Again we could have chosen any prefix to identify this namespace.
The targetNamespace attribute lets you define, independently
of the namespace declarations, which namespace is described in this schema.
If you need to reference objects belonging to this namespace, which is
usually the case except when using a pure Russian Doll design, you need to
provide a namespace declaration in addition to the
targetNamespace.
The final two attributes in the example, (elementFormDefault
and attributeFormDefault), are a facility provided by W3C XML
Schema to control, within a single schema, whether attributes and elements
are considered by default to be qualified (in a namespace). This
differentiation between qualified and unqualified can be indicated by
specifying the default values, as above, but also when defining the element
or attribute, by adding a form attribute of value
qualified or unqualified.
It is important to note that only local elements and attributes can be specified as unqualified. All globally defined elements and attributes must always be qualified.
Importing definitions from external namespaces
W3C XML Schema, not unlike XSLT and XPath, uses namespace prefixes within the value of some attributes to identify the namespace of data types, elements, attributes, etc. For instance, we've used this feature all along in our examples to identify the W3C XML Schema predefined datatypes. This mechanism can be extended to import definitions from any other namespace and so reuse them in our schemas.
Reusing definitions from other namespaces is done through a three-step
process. This process needs to be done even for the XML 1.0 namespace in
order to declare attributes such as xml:lang. First, the
namespace must be defined as usual.
<xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema" targetNamespace="http://example.org/ns/books/" xmlns:xml="http://www.w3.org/XML/1998/namespace" elementFormDefault="qualified" >
Then W3C XML Schema needs to be informed of the location at which it can
find the schema corresponding to the namespace. This is done using an
xsd:import element.
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="myxml.xsd"/>
W3C XML Schema now knows that it should attempt to find any reference belonging to the XML namespace in a schema located at myxml.xsd. We can now use the external definition.
<xsd:element name="title">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute ref="xml:lang"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
You may wonder why we've chosen to reference the xml:lang
attribute from the XML namespace rather than creating an attribute with a
type xml:lang. We've done so because there is an important
difference between referencing an attribute (or an element) and referencing
a datatype when namespaces are concerned.
- Referencing an element or an attribute imports the whole thing with its name and namespace.
- Referencing a datatype imports only its definition, leaving you with the task of giving a name to the element or attribute you're defining, and places your definition in the target namespace (or no namespace if your attribute or element is unqualified).
Including unknown elements
To finish this section about namespaces, we need to see how, as promised
in the introduction, we can open our schema to unknown elements, attributes
and namespaces. This is done using xsd:any and
xsd:anyAttribute, allowing, respectively, the inclusion of any
element or attribute.
For instance, if we want to extend the definition of our description type to any XHTML tag, we could declare
<xsd:complexType name="descType" mixed="true">
<xsd:sequence>
<xsd:any namespace="http://www.w3.org/1999/xhtml"
minOccurs="0" maxOccurs="unbounded"
processContents="skip"/>
</xsd:sequence>
</xsd:complexType>
The xsd:anyAttribute gives the same functionality for
attribute definitions.
The type descType is now mixed content and accepts an unbounded
number of any elements from the http://www.w3.org/1999/xhtml
namespace. The processContents attribute is set to
skip, telling a W3C XML Schema processor that no validation of these
elements should be attempted. The other permissible values for this
attribute are strict, asking to validate these elements, or
lax, asking the processor to validate them when possible. The
namespace attribute accepts a whitespace-separated list of
URIs, as well as the special values ##any (any namespace),
##local (non-qualified elements), ##targetNamespace (the
target namespace) or ##other (any namespace other than the
target).