The W3C released Namespaces in XML about a year after XML 1.0. Namespaces provide a URI-based mechanism that helps differentiate XML vocabularies. Rather than update XML 1.0’s DTDs to provide explicit namespace support, the W3C chose to implement namespace support in W3C XML Schema. Support of namespaces was eagerly awaited by the XML community and, thus, are especially well-polished by the W3C XML Schema editors.
Namespaces caused two problems to DTDs. One was how to recognize namespaces defined using different prefixes in instance documents. The other was how best to facilitate the definition of schemas with multiple namespaces. The problem of open schemas tightly controlling some namespaces while keeping the flexibility to add unknown elements and attributes from unknown namespaces, was especially difficult.
W3C XML Schema has gone beyond these expectations for its use of namespaces by associating a namespace to all the objects (elements and attributes, but also simple and complex types as well as groups of elements and attributes) defined in a schema, allowing the use of namespaces to build modular libraries of schemas.
Namespace prefixes should only be considered to be local shortcuts to replace the URI references that are the real identifiers for a namespace. The following documents should, therefore, be considered strictly equivalent by namespace-aware applications:
<?xml version="1.0"?> <library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <person id="CMS"> <name> Charles M Schulz </name> </person> </authors> </book> </library>
In the document above, the namespace "http://dyomedea.com/ns/library" is defined as the default namespace and applies to all the elements within the document. Next, we’ll show a namespace-equivalent, but very different-looking, document:
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <lib:library xmlns:lib="http://dyomedea.com/ns/library"> <lib:book id="b0836217462"> <lib:title> Being a Dog Is a Full-Time Job </lib:title> <lib:authors> <lib:person id="CMS"> <lib:name> Charles M Schulz </lib:name> </lib:person> </lib:authors> </lib:book> </lib:library>
The namespace "http://dyomedea.com/ns/library"
is defined as mapping to the prefix lib
and is
used as a prefix for all the elements within the document. Next,
we’ll create another namespace-equivalent document
using a different prefix.
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <l:library xmlns:l="http://dyomedea.com/ns/library"> <l:book id="b0836217462"> <l:title> Being a Dog Is a Full-Time Job </l:title> <l:authors> <l:person id="CMS"> <l:name> Charles M Schulz </l:name> </l:person> </l:authors> </l:book> </l:library>
The namespace "http://dyomedea.com/ns/library"
is defined as mapping to the prefix l
and is used
as a prefix for all the elements within the document. Finally,
we’ll mix all of these possibilities in a single
document still namespace-equivalent to the others.
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <l:library xmlns:l="http://dyomedea.com/ns/library"> <l:book id="b0836217462" xmlns:lib="http://dyomedea.com/ns/library"> <l:title> Being a Dog Is a Full-Time Job </l:title> <lib:authors> <l:person id="CMS" xmlns="http://dyomedea.com/ns/library"> <name> Charles M Schulz </name> </l:person> </lib:authors> </l:book> </l:library>
The same namespace is defined and used as l
,
lib
, and even as a default namespace, depending on
its location in the document. This last example is, of course, an
extreme case that isn’t recommended. This document
conforms to the namespaces recommendation, however, and the
specification states that it is strictly equivalent to the three
previous ones.
DTDs are not aware of the namespaces. Since the colon
(:
) is allowed in the XML names,
lib:person
, l:person
, and
person
are three different, valid names for a DTD.
Furthermore, a DTD sees namespace declaration attributes
(xmlns
, xmlns:l
,
xmlns:lib
) as ordinary attributes that need to be
declared.
A XML document using namespaces is a well-formed XML 1.0 document and it is perfectly possible to write a DTD to describe it. Nevertheless, you must define the prefixes that can be used and the location where the namespace declarations must be inserted. This is acceptable only if you can fully control or specify the authoring processes of the documents.
The second and larger issue is design. Since XML is often used as the glue between different applications, it is becoming increasingly important to be able to define modular vocabularies that can live together in the same document, and namespaces were invented to make this possible. To take advantage of this feature, it is often necessary to define open vocabularies that will define places where external elements and attributes from external namespaces may be included without breaking the applications.
Imagine a marketing department wants to add the type of cover and the number of pages to the information about a particular book. A neat way to do this—if this new information is specific to their needs and we don’t want to break the existing applications—is to create a new namespace:
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <library xmlns="http://dyomedea.com/ns/library" xmlns:mkt="http://dyomedea.com/ns/library/mkt"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <person id="CMS"> <name> Charles M Schulz </name> </person> </authors> <mkt:cover> Paperback </mkt:cover> <mkt:pages> 128 </mkt:pages> </book> </library>
However, if we want to keep our schema independent of the marketing
application, we need a flexible way to open it and say
“accept any element from the marketing namespace at
the end of our book
element.”
Also, even if there might be other applications that work with our
vocabulary, we can say to accept any element from any other namespace
at the end of our book
element.
Until now, we have seen schemas for documents that had no namespace declarations of any kind and, therefore, did not belong to any namespace. To match the documents without namespaces, the schemas had no namespace declaration either, except the one needed to identify the W3C XML Schema namespace itself.
To match the elements and attributes that belong to a namespace, we
need to associate this namespace with our schema through the
targetNamespace
attribute of
the xs:schema
element.
If we modify our library to use a single namespace:
<library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> .../... </book> </library>
We need to modify our schema to declare the namespace and to define it as the target namespace:
<xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> .../... </xs:schema>
The definition of the namespaces is especially important here, since W3C XML Schema uses them for two purposes.
As for any XML document that conforms to the namespaces Recommendation, the first purpose of the namespace declaration is to associate a URI reference that is the identifier of a namespace to a prefix, which is a shortcut for this identifier.
In our example, we have two such declarations:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
and
xmlns:lib="http://dyomedea.com/ns/library"
.
The first declaration associates the W3C XML Schema namespace with
the prefix xs
. We could, of course, have chosen
any prefix, or even used this namespace as the default namespace; the
choice of xs
is just common usage.
The second declaration defines the namespace used in our instance
document,
xmlns:lib="http://dyomedea.com/ns/library"
.
Here we chose to use the lib
prefix, even though
this namespace is never used for any element or attribute of the
schema itself. We could also have chosen any prefix for this
namespace, or even have defined it as our default namespace.
This second declaration is needed for the second usage of namespace
prefixes. W3C XML Schema uses the namespace prefixes to resolve all
the references to the components of a schema (datatypes, elements,
attributes, groups, etc.), as well as for the XPath expressions used
in the
xs:unique
,
xs:key
, and
xs:keyref
declarations.
We haven’t yet mentioned which namespace this schema
describes. We must do so using the targetNamespace
attribute that defines the
URI reference that identifies
the target namespace.
With this last piece of information, a schema processor knows what the target namespace is. With the two namespaces declarations already complete, it also knows which prefix we want to use for it and for the W3C XML Schema namespace. This is sufficient information to write our schema.
This use of the namespace prefixes, common to W3C XML Schema and XSLT, is very controversial, since it creates a dependency between W3C XML Schema (considered an application) and the prefixes chosen for the namespaces. This breaks the layered structure of the XML specifications: the markup and its content become interdependent and cannot be changed independently any longer.
Not unlike a communication protocol, the XML specifications may be seen as a set of envelopes. XML 1.0 is the outermost envelope into which the namespaces are included. While the applications should be independent of these envelopes, the fact that W3C XML Schema is making use of the namespace prefixes inside its own attributes glues the schema to its envelope. This is a very dangerous practice that should be discouraged for other vocabularies that define their own sets of prefixes.
One of the consequences of this practice is that Canonical XML has been obliged to remove namespace prefix rewriting from its requirements, meaning that the four flavors of our library that are strictly equivalent, per the namespace recommendation, will have four different canonical values, and different digital signatures as a result.
The schemas that we have written up to this point have had no target namespace declaration. We also could only describe elements and attributes that didn’t belong to any namespace.
The declaration of a target namespace gives us the possibility of defining elements and attributes that belong to the target namespace (called “qualified”) and elements and attributes that don’t belong to any namespace (called “unqualified”).
The purpose of a schema is to describe a vocabulary, in which top-level nodes belong to its target namespace. For this reason, it is forbidden to define global elements that are unqualified when a target namespace is declared.
The distinction between qualified and unqualified elements and
attributes is made through their <form>
attributes—for example:
<xs:element name="book" form="qualified"/> <xs:attribute name="isbn" form="qualified"/> <xs:attribute name="lang" form="unqualified"/> <xs:element name="character" form="unqualified"/>
The default values of these form
attributes are
defined in the elementFormDefault
and
attributeFormDefault
attributes that we have added in our
xs:schema
element.
These attributes both have default values of their own, which are:
elementFormDefault="unqualified"
and
attributeFormDefault="unqualified"
. These values
are appropriate to the case in which only the document element uses a
namespace:
<lib:library xmlns:lib="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> </book> </lib:library>
Since global elements and attributes must be qualified, defining this schema as a single schema requires that all the elements and attributes are locally defined.
Another combination,
elementFormDefault="qualified"
and
attributeFormDefault="unqualified"
matches the
common case in which a namespace is attached to the root element as
the default namespace that will, by definition apply to the included
elements but not to the attributes. (Per the Namespaces
Recommendation, the default
namespace does not apply to attributes.)
<library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> </book> </library>
The usage considers that unqualified attributes belong to the same
vocabulary as their
parent element, and the vocabularies that take advantage of qualified
attributes are often vocabularies that supply attributes used in
elements from other namespaces. Examples of such vocabularies include
RDF and attribute-only vocabularies such as XLink and XML Base. The
schemas for these vocabularies will benefit from an
attributeFormDefault
set to qualified.
One should pay attention to the special status of the attributes in the namespace specification. The default namespace does not apply to attributes. This means that an attribute without a prefix is considered to have no namespace.
Another confusing aspect of attributes with a prefix (which thus belong to a namespace) is these attributes are called "global attributes” in the namespaces recommendation. In W3C XML Schema the term global is used differently, in opposition to local elements or attributes. A global attribute, per namespaces, is therefore a qualified attribute per W3C XML Schema, and may be globally or locally defined.
Remember that <elementFormDefault>
and
<attributeFormDefault>
define default values
and that you can specify—element by element and attribute by
attribute—if they are qualified or not.
Before we see how we can bring more namespaces into the game, let’s look at a simple instance document with a single namespace and unqualified attributes:
<?xml version="1.0"?> <library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> <authors> <person id="CMS"> <name> Charles M Schulz </name> <born> 1922-11-26 </born> <dead> 2000-02-12 </dead> </person> </authors> <characters> <person id="PP"> <name> Peppermint Patty </name> <born> 1966-08-22 </born> <qualification> bold, brash and tomboyish </qualification> </person> <person id="Snoopy"> <name> Snoopy </name> <born> 1950-10-04 </born> <qualification> extroverted beagle </qualification> </person> <person id="Schroeder"> <name> Schroeder </name> <born> 1951-05-30 </born> <qualification> brought classical music to the Peanuts strip </qualification> </person> <person id="Lucy"> <name> Lucy </name> <born> 1952-03-03 </born> <qualification> bossy, crabby and selfish </qualification> </person> </characters> </book> </library>
If we want to avoid confusion while writing a schema for this instance document, we can define prefixes in the schema for both our target namespace and for the W3C XML Schema namespace, leading to a schema such as:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="born" type="xs:date"/> <xs:element name="dead" type="xs:date" minOccurs="0"/> <xs:element name="qualification" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="isbn" type="xs:NMTOKEN"/> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="lib:person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="characters"> <xs:complexType> <xs:sequence> <xs:element ref="lib:person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="available" type="xs:string" use="required"/> </xs:complexType> </xs:schema>
In this example, the names of components defined by the schema are
always unprefixed when they are defined. Because this schema only
defines components in the single http://dyomedea.com/ns/library namespace
(identified as the targetNamespace
attribute of
the xs:schema
element), there isn’t any risk of
confusion. The only other namespaces used here are the namespace for
W3C XML Schema itself, identified with an xs
prefix, and another mapping for the http://dyomedea.com/ns/library namespace,
using lib
as the prefix. The
lib
-prefixed form is used for cross-references
between declarations.
A strictly equivalent schema, defining the exact same data model, can be defined using the target namespace as the default namespace of the schema document:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://dyomedea.com/ns/library"> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="born" type="xs:date"/> <xs:element name="dead" type="xs:date" minOccurs="0"/> <xs:element name="qualification" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="isbn" type="xs:NMTOKEN"/> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="characters"> <xs:complexType> <xs:sequence> <xs:element ref="person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="available" type="xs:string" use="required"/> </xs:complexType> </xs:schema>
In this version, all references to W3C XML Schema’s
own elements are still made using the xs
prefix.
Names of components are still unprefixed, but the
lib
prefix is now unnecessary, so all of those
prefixes can disappear. Because the default namespace is defined in
this document, W3C XML Schema will understand the connection between
the components it defines and references to those components.
If you prefer to use prefixes on the components you are defining and
use the W3C XML Schema vocabulary without prefixes, you can also
define the W3C XML Namespace as the default namespace and declare a
prefixed namespace (here, lib
) for the components
you’re
defining:
<?xml version="1.0"?> <schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:lib="http://dyomedea.com/ns/library"> <element name="library"> <complexType> <sequence> <element name="book" type="lib:bookType"/> </sequence> </complexType> </element> <element name="person"> <complexType> <sequence> <element name="name" type="string"/> <element name="born" type="date"/> <element name="dead" type="date" minOccurs="0"/> <element name="qualification" type="string" minOccurs="0"/> </sequence> <attribute name="id" type="ID" use="required"/> </complexType> </element> <complexType name="bookType"> <sequence> <element name="isbn" type="NMTOKEN"/> <element name="title" type="string"/> <element name="authors"> <complexType> <sequence> <element ref="lib:person" maxOccurs="unbounded"/> </sequence> </complexType> </element> <element name="characters"> <complexType> <sequence> <element ref="lib:person" maxOccurs="unbounded"/> </sequence> </complexType> </element> </sequence> <attribute name="id" type="ID" use="required"/> <attribute name="available" type="string" use="required"/> </complexType> </schema>
The references to W3C XML Schema data types are now done without a prefix while the references to components defined in the target namespace are done with a “lib” prefix.
So far we have seen that W3C XML Schema treats global attributes and elements alike, requiring both types to be explicitly namespace-qualified to be global. Although this approach makes sense—there’s little reason to treat elements and attributes differently—it’s different from the approach the Namespaces in XML Recommendation took. Global attributes turn out to be a rather unusual, though useful, case.
To understand this phenomenon, we need to examine the Namespaces in XML Recommendation closely. This differentiates qualified and unqualified attributes, explaining that only attributes applied to elements from another namespace need to be qualified (these are also called global attributes), and that unqualified attributes are considered to belong to the vocabulary from their parent element without needing to belong to their namespace. In this case, they inherit the membership to the namespace of their parent element without needing to show it. This is tightly linked to the fact that default namespaces do not apply to attributes (they don’t need to since attributes are considered members of the namespace of their parent without needing default namespaces). In practice, most XML vocabularies will use unqualified attributes, such as:
<book id="b0836217462" xmlns="http://dyomedea.com/ns/library"/>
or:
<lib:book id="b0836217462" xmlns:lib="http://dyomedea.com/ns/library"/>
Very few would use qualified attributes, such as:
<lib:book lib:id="b0836217462" xmlns:lib="http://dyomedea.com/ns/library"/>
Also, very few would use that or its equivalent if we use a default namespace for the element that doesn’t apply to the attribute:
<book lib:id="b0836217462" xmlns="http://dyomedea.com/ns/library" xmlns:lib="http://dyomedea.com/ns/library"/>
Unfortunately, since the W3C XML Schema requires that all the global
attributes be qualified, this means that global attributes
can’t be used for those unqualified attributes that
are used most of the time in XML vocabularies, and that our
unqualified id
attribute cannot be declared as
global. In practice, this means that most of the time we will just
define local attributes within the element or complex type
definitions. When we want to define unqualified attributes that may
be reused in different elements, we will either define them in a
specific schema without a target namespace, which will be imported
(but there is risk of collision if we mix several schemas for
different target namespaces following this policy), or
“hide” those attributes inside of
attribute groups, such as:
<xs:attributeGroup name="id"> <xs:attribute name="id" form="unqualified" type="xs:ID"/> </xs:attributeGroup>
It’s
time to remember that
default namespaces do not apply to
XPath expressions, and that a
prefix needs to be defined
for each namespace used in the XPath expressions of the
xs:unique
,
xs:key
, and
xs:keyref
declarations!
A prefix declaration is therefore required to write expressions that
reference qualified elements and attributes, even if the target
namespace is defined as the default namespace. It’s
also important to notice that the
xs:keyref
refer
attribute is a
QName
that needs to be prefixed, and a
xs:key
/
xs:keyref
on the authors in (in our previous
example) with a namespace could become:
<xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType" maxOccurs="unbounded"/> <xs:element name="author" type="lib:authorType" maxOccurs="unbounded"/> <xs:element name="characters" type="lib:characterType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:key name="author"> <xs:selector xpath="lib:author"/> <xs:field xpath="@id"/> </xs:key> <xs:keyref name="keyref" refer="lib:author"> <xs:selector xpath="lib:book/lib:author-ref"/> <xs:field xpath="@ref"/> </xs:keyref> </xs:element> </xs:schema>
One of the goals of the namespaces specification is to allow the use of documents mixing elements and attributes from different vocabularies. W3C XML Schema lets you take full advantage of this possibility.
Part of the library vocabulary describes persons. This could be
reused by other applications, and we might want to define a specific
namespace and give it the URI reference
"http://dyomedea.com/ns/people"
:
<?xml version="1.0"?> <library xmlns:ppl="http://dyomedea.com/ns/people" xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> <authors> <ppl:person id="CMS"> <ppl:name> Charles M Schulz </ppl:name> <ppl:born> 1922-11-26 </ppl:born> <ppl:dead> 2000-02-12 </ppl:dead> </ppl:person> </authors> <characters> <ppl:person id="PP"> <ppl:name> Peppermint Patty </ppl:name> <ppl:born> 1966-08-22 </ppl:born> <ppl:qualification> bold, brash and tomboyish </ppl:qualification> </ppl:person> <ppl:person id="Snoopy"> <ppl:name> Snoopy </ppl:name> <ppl:born> 1950-10-04 </ppl:born> <ppl:qualification> extroverted beagle </ppl:qualification> </ppl:person> <ppl:person id="Schroeder"> <ppl:name> Schroeder </ppl:name> <ppl:born> 1951-05-30 </ppl:born> <ppl:qualification> brought classical music to the Peanuts strip </ppl:qualification> </ppl:person> <ppl:person id="Lucy"> <ppl:name> Lucy </ppl:name> <ppl:born> 1952-03-03 </ppl:born> <ppl:qualification> bossy, crabby and selfish </ppl:qualification> </ppl:person> </characters> </book> </library>
To handle these two namespaces, we need to define two different
schemas (one per namespace). One will describe our vocabulary about
persons as well as include the definitions of the element
person
and its child elements:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/people" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:ppl="http://dyomedea.com/ns/people" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="born" type="xs:date"/> <xs:element name="dead" type="xs:date" minOccurs="0"/> <xs:element name="qualification" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:element> </xs:schema>
This schema describes the namespace
"http://dyomedea.com/ns/people"
,
and this vocabulary doesn’t include anything from
any other namespace. The schema is then similar to the examples
we’ve seen in this chapter so far. It can be used
alone with documents that use only this namespace, but can also be
“imported” by schemas that describe
other namespaces but would like to use some of its definitions.
To do this, the schema that describes the including vocabulary needs
two pieces of information. It must have a prefix for the namespaces
that will be included; this is done by a usual namespace declaration.
It also must have a hint on where it can find the schema for this
namespace; this is done using a
xs:import
element:
<xs:import namespace="http://dyomedea.com/ns/people" schemaLocation="simple-2-ns-ppl.xsd"/>
The schema now has all the information it needs to resolve references
to schema components that belong to the
http://dyomedea.com/ns/people
namespace.
References can be made just using its prefix:
<xs:element ref="ppl:person"/>
A full schema for the library vocabulary can then be:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ppl="http://dyomedea.com/ns/people" xmlns:lib="http://dyomedea.com/ns/library"> <xs:import namespace="http://dyomedea.com/ns/people" schemaLocation="simple-2-ns-ppl.xsd"/> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="isbn" type="xs:NMTOKEN"/> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="ppl:person"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="characters"> <xs:complexType> <xs:sequence> <xs:element ref="ppl:person" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="available" type="xs:string" use="required"/> </xs:complexType> </xs:schema>
XML Base, XLink, and XML 1.0 all define vocabularies that are
composed only of attributes. Attributes such as
xml:base
,
xlink:href
, or
xml:lang
are designed to work with elements from
any vocabulary, imparting their meaning to those elements and
sometimes the descendants of those elements.
In
this section, we will discuss
how to allow the use of a XML attribute in our document. To
illustrate this, let’s use a
xml:lang
attribute
to qualify the language of several descriptions in several languages
for our book:
<?xml version="1.0"?> <library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <description xml:lang="en"> Its title says it all ! </description> <description xml:lang="fr"> Son titre le résume parfaitement ! </description> </book> </library>
Following Namespaces in XML 1.0, W3C XML Schema
considers xml:lang
,
xml:space
(from the
XML 1.0 recommendation) and
xml:base
(from the
XML Base specification) to belong to the XML 1.0
namespace identified by the URI reference
"http://www.w3.org/XML/1998/namespace"
.
The XML 1.0 namespace is an exception in the namespaces world, since we don’t need to declare it in the instance documents. Its prefix “xml” is reserved for this usage and has a special meaning, even for the parsers that do not support the namespaces. In theory, any other prefix can be assigned to the XML 1.0 namespace, but this practice is confusing and shouldn’t be encouraged.
To use attributes from this namespace, we will declare the XML namespace, import a schema, and reference both of them, as we’ve done previously for the elements from our “people” namespace:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/> <xs:element name="description"> <xs:complexType> <xs:simpleContent> <xs:restriction base="xs:string"> <xs:attribute ref="xml:lang"/> </xs:restriction> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element ref="lib:book"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element ref="lib:description" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:element> </xs:schema>
In this example, we import a local schema
(xml.xsd
) for the XML namespace. The
W3C has defined its own schema for the
xml:lang
, xml:space
, and
xml:base
attributes. This is available at
http://www.w3.org/2001/xml.xsd:
<?xml version='1.0'?> <!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" > <xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http:// www.w3.org/2001/XMLSchema" xml:lang="en"> <xs:annotation> <xs:documentation> See http://www.w3.org/XML/1998/namespace.html and http://www.w3.org/TR/REC-xml for information about this namespace. </xs:documentation> </xs:annotation> <xs:annotation> <xs:documentation>This schema defines attributes and an attribute group suitable for use by schemas wishing to allow xml:base, xml:lang or xml:space attributes on elements they define. To enable this, such a schema must import this schema for the XML namespace, e.g. as follows: <schema . . .> . . . <import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> Subsequently, qualified reference to any of the attributes or the group defined below will have the desired effect, e.g. <type . . .> . . . <attributeGroup ref="xml:specialAttrs"/> will define a type which will schema-validate an instance element with any of those attributes</xs:documentation> </xs:annotation> <xs:annotation> <xs:documentation>In keeping with the XML Schema WG's standard versioning policy, this schema document will persist at http://www.w3.org/2001/03/xml.xsd. At the date of issue it can also be found at http://www.w3.org/2001/xml.xsd. The schema document at that URI may however change in the future, in order to remain compatible with the latest version of XML Schema itself. In other words, if the XML Schema namespace changes, the version of this document at http://www.w3.org/2001/xml.xsd will change accordingly; the version at http://www.w3.org/2001/03/xml.xsd will not change. </xs:documentation> </xs:annotation> <xs:attribute name="lang" type="xs:language"> <xs:annotation> <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter codes as the enumerated possible values . . .</xs:documentation> </xs:annotation> </xs:attribute> <xs:attribute name="space" default="preserve"> <xs:simpleType> <xs:restriction base="xs:NCName"> <xs:enumeration value="default"/> <xs:enumeration value="preserve"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="base" type="xs:anyURI"> <xs:annotation> <xs:documentation>See http://www.w3.org/TR/xmlbase/ for information about this attribute.</xs:documentation> </xs:annotation> </xs:attribute> <xs:attributeGroup name="specialAttrs"> <xs:attribute ref="xml:base"/> <xs:attribute ref="xml:lang"/> <xs:attribute ref="xml:space"/> </xs:attributeGroup> </xs:schema>
Among the many controversial issues surrounding the usage of URIs, the decision to use a schema at its original location (on the W3C web site) versus using a local copy is not easy. Using a schema at its original location provides a guarantee of always accessing the most recent version, but this can be a problem if the schema becomes out of sync with the applications using it. It can also impact the ability to process documents when the hosting site is unreachable and may open a possibility of malicious substitutions of schemas.
To illustrate the usage of
XLink
attributes, we can replace the definition of the author that is
currently within the description of a book under the
authors
element, with a reference to an author
described as a “person” in another
XML document:
<?xml version="1.0"?> <library xmlns="http://dyomedea.com/ns/library" xmlns:xlink="http://www.w3.org/1999/xlink"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <person xlink:href="authors.xml#CMS"/> </authors> </book> </library>
Again, we need to define the namespace for XLink and to import a schema before referencing the XLink attributes:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:lib="http://dyomedea.com/ns/library"> <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="xlink.xsd"/> <xs:element name="person"> <xs:complexType> <xs:attribute ref="xlink:href" use="required"/> <xs:attribute ref="xlink:type" fixed="simple"/> <xs:attribute ref="xlink:show" fixed="embed"/> <xs:attribute ref="xlink:actuate" fixed="onLoad"/> </xs:complexType> </xs:element> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element ref="lib:book"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element ref="lib:authors"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:element> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="lib:person"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Following the suggestion of the XLink specification, we have defined
additional XLink attributes (type
,
show
, and actuate
) as fixed
values. While this is legitimate, one should note that these values
are only available to the applications that use a W3C XML
Schema
post-schema validation infoset
(PSVI).
Although the XLink specification doesn’t provide a schema, creating the parts we need is very straightforward:
<?xml version="1.0"?> <xs:schema targetNamespace="http://www.w3.org/1999/xlink" elementFormDefault="qualified" attributeFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink"> <xs:attribute name="type"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="simple"/> <xs:enumeration value="extended"/> <xs:enumeration value="locator"/> <xs:enumeration value="arc"/> <xs:enumeration value="resource"/> <xs:enumeration value="title"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="href" type="xs:anyURI"/> <xs:attribute name="role" type="xs:anyURI"/> <xs:attribute name="arcrole" type="xs:anyURI"/> <xs:attribute name="title" type="xs:string"/> <xs:attribute name="show"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="new"/> <xs:enumeration value="replace"/> <xs:enumeration value="embed"/> <xs:enumeration value="other"/> <xs:enumeration value="none"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="label" type="xs:NMTOKEN"/> <xs:attribute name="actuate"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="onLoad"/> <xs:enumeration value="onRequest"/> <xs:enumeration value="other"/> <xs:enumeration value="none"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="from" type="xs:NMTOKEN"/> <xs:attribute name="to" type="xs:NMTOKEN"/> </xs:schema>
You may be wondering about the different approaches used to identify the namespaces for the elements defined by the schema and the data types defined by W3C XML Schema. Importing schemas imposes certain restrictions on the use of namespaces in the imported schema.
When we define an element or attribute, we give it a namespace. That namespace must be the same as the target namespace of the schema doing the importing, even if the datatype of the element or attribute belongs to a different namespace.
The rules are slightly different when we define an element or attribute by reference to a component which is in a different namespace, rather than a datatype. In that case, the name of the referenced component is imported, and that namespace must be the target namespace of the imported schema.
To illustrate how this works, we’ll take a closer look at two ways to create schemas described in this simple example:
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <library xmlns:ppl="http://dyomedea.com/ns/people" xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <ppl:person id="CMS"> <ppl:name> Charles M Schulz </ppl:name> </ppl:person> </authors> </book> </library>
This document contains two namespaces. Everything except the contents
of the authors
element is in the
http://dyomedea.com/ns/library
namespace. The
contents of the authors
element
(ppl:person
and ppl:name
) are
in the http://dyomedea.com/ns/people
namespace.
We have two main options for representing this document using W3C XML
Schema. Both approaches start by defining a schema for the elements
in the http://dyomedea.com/ns/library
namespace.
The first approach imports the schema defining the
http://dyomedea.com/ns/people
namespace, and then
uses a reference to the ppl:person
element to use
it inside the authors
element:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ppl="http://dyomedea.com/ns/people" xmlns:lib="http://dyomedea.com/ns/library"> <xs:import namespace="http://dyomedea.com/ns/people" schemaLocation="very-simple-2-ns-ppl.xsd"/> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="ppl:person"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:schema>
The second approach does the same import, but defines the
authors
element as having the type
ppl:authorType
rather than defining its complex
type explicitly, resulting in a shorter schema:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:ppl="http://dyomedea.com/ns/people" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://dyomedea.com/ns/people" schemaLocation="very-simple-2-ns-ppl.xsd"/> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="authors" type="ppl:authorType"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:schema>
Although the two schemas will validate the same instance documents,
the design style is quite different. Applications relying on the
schema for information about the document will see it in two very
different ways. The first approach provides a cleaner separation
between the two namespaces. The use of the reference allows the
ppl:person
element to appear inside the
authors
element but does nothing to mix the
authors
element with the
http://dyomedea.com/ns/people
namespace directly.
The second approach is briefer, but assigns a datatype in one
namespace to an element in another namespace.
If you are using your schemas purely for validation, this distinction is unimportant. Both schemas will validate identical sets of documents. If, however, your applications rely on your schemas for type information (using the PSVI or perhaps compile-time data-binding based on the schema), the perspective shift may matter. Using the datatype approach will mean that your applications need to understand quite a bit more about the contents of your schema and creates new dependencies between your application and the details of W3C XML Schema processing.
We have seen how we can reference components from other namespaces and how the elements and attributes included in these components keep their full name, namespaces, and form (in Section 10.3). However, this mechanism has a restriction: you can only reference global elements and attributes, and global elements and attributes must always be qualified.
Therefore, the only solution to importing elements and attributes with no namespace is to import a schema without any target namespace. Let’s say that we want to describe a document in which the vocabulary to describe people has no namespace:
<?xml version="1.0"?> <lib:library xmlns:lib="http://dyomedea.com/ns/library"> <lib:book id="b0836217462"> <lib:title> Being a Dog Is a Full-Time Job </lib:title> <lib:authors> <person id="CMS"> <name> Charles M Schulz </name> </person> </lib:authors> </lib:book> </lib:library>
The import of the schema without a
namespace is done exactly as we’ve seen earlier with
schemas having target namespaces, except now we omit the
namespace
attribute. Another point to note is that
to be able to reference the components from the schema you are
including, you will have to keep the default namespace (unprefixed)
available:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:lib="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import schemaLocation="very-simple-2-ns-ppl-nons.xsd"/> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book" type="lib:bookType"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="bookType"> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="person"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:schema>
The included schema is:
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="person" type="personType"/> <xs:complexType name="personType"> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> </xs:schema>
In this case, all the components are considered unqualified. All the other behavior, including the difference between referencing elements or attributes and using datatypes, is relevant.
We see then that to define unqualified elements and attributes in a schema with a target namespace, we have to choose between defining them locally in the schema or defining them in a separate schema without an imported target namespace.
This
chapter wouldn’t
be complete without a look at the impact of namespaces on the
inclusion of schemas through
xs:include
and
xs:redefine
.
When we initially introduced these features, we didn’t worry about namespaces. However, these features have some important interactions with namespaces, since W3C XML Schema restricts inclusion (or redefinition) to pieces of schema with either the same target namespace or without any target namespace (schemas for other languages being “imported” rather than “included”).
When a piece of schema that has no target namespace is included in a schema with a target namespace, the included definition acquires the target namespace of the including schema and behaves exactly as if it added the same target namespace. This feature allows creation of libraries with pieces of schema that are “namespace-transparent,” and which take the namespace of the schema in which they are imported. This method is often called “chameleon,” since the included schema takes the “color” of the context in which it is included.
To illustrate this feature and see its implication, let’s look again at the example that we’ve used throughout this chapter:
<?xml version="1.0"?> <library xmlns="http://dyomedea.com/ns/library"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <person id="CMS"> <name> Charles M Schulz </name> </person> </authors> </book> </library>
If we want a library of schema parts that describe a person and can be included within several vocabularies, we can include a piece of schema that has no target namespace. This piece of schema would be something like the following (note that we do not define any target namespace):
<?xml version="1.0"?> <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:schema>
And the including schema would look similar to the following example:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" xmlns="http://dyomedea.com/ns/library" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:include schemaLocation="very-simple-1-ns-ppl.xsd"/> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element ref="person"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id" type="xs:ID"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
While this looks very easy and neat, we may wonder if we are really building something modular. Including a piece of schema is similar to including a C header file. While this is slightly better than a copy/paste, the level of modularity that can be achieved in this way is very restricted.
The namespace of the element person
is the
namespace given to our library. An application cannot guess from
looking at the instance document that this element is the same as a
person
element that it will find in another
document describing, for example, an employee.
Looking at the modified infoset and checking the datatype doesn’t help either, since the datatype will be defined as a datatype from a schema with the target namespace of our library, and won’t match other target namespaces, including the same piece of schema.
The fact that the same person
element is used by
different vocabularies is totally lost by the processing of the
include (or redefine). Before using it, you may consider if it
isn’t more useful to include information in the
instance document using a separate namespace, or at least include
information in the modified infoset by importing datatypes from
another namespace rather than
including
common definitions.
We are going to see how to accommodate any element or attribute from
other namespaces
using our marketing extension, the
http://dyomedea.com/ns/library/mkt
namespace, as
an example:
<?xml version="1.0"?> <!-- Namespace: http://dyomedea.com/ns/library --> <library xmlns="http://dyomedea.com/ns/library" xmlns:mkt="http://dyomedea.com/ns/library/mkt"> <book id="b0836217462"> <title> Being a Dog Is a Full-Time Job </title> <authors> <person id="CMS"> <name> Charles M Schulz </name> </person> </authors> <mkt:cover> Paperback </mkt:cover> <mkt:pages> 128 </mkt:pages> </book> </library>
To allow any elements from the
http://dyomedea.com/ns/library/mkt
namespace after
the author
element, we use a
xs:any
element:
<xs:any namespace="http://dyomedea.com/ns/library/mkt" processContents="skip"minOccurs="0" maxOccurs="unbounded"/>
xs:anyAttribute
should be used to allow attributes:
<xs:anyAttribute namespace="http://dyomedea.com/ns/library/mkt" processContents="skip"/>
The two new attributes shown above are
namespace
and
processContents
.
namespace
specifies the namespaces of the elements
or attributes that will be accepted. The value should be a list of
namespaces that
URIs allow a number of
wildcards. The wildcards permitted
within the list are
##local
(a nonqualified
element) and
##targetNamespace
(the target namespace). Two wildcards
can also be used instead of the list:
##any
(any namespace) and
##other
(any namespace other
than the target namespace).
It is not possible to specify that the possible namespaces are all the namespaces not defined in a schema, or even all the namespaces except those in a list. This is a serious limitation for multi-namespace vocabularies that would like to restrict some of the imported namespaces while remaining open to undefined namespaces.
processContents
specifies the behavior of the
validator regarding the elements or attributes from the specified
namespaces. The possible values are
“skip” (no validation is attempted
on these elements or attributes),
“strict” (schemas for the
namespaces that will be included need to be available, and validators
will validate the elements and attributes against these schemas), or
“lax” (validators will do their
best to find a schema for the included elements and attributes,
validate them when they have found one, and silently skip the
validation when they haven’t). For example:
<?xml version="1.0"?> <xs:schema targetNamespace="http://dyomedea.com/ns/library" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://dyomedea.com/ns/library"> <xs:element name="library"> <xs:complexType> <xs:sequence> <xs:element ref="book"/> </xs:sequence> <xs:anyAttribute namespace="http://dyomedea.com/ns/library/mkt" processContents="skip"/> </xs:complexType> </xs:element> <xs:element name="book"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="authors"> <xs:complexType> <xs:sequence> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:any namespace="http://dyomedea.com/ns/library/mkt" processContents="skip"minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" use="required"> <xs:simpleType> <xs:restriction base="xs:hexBinary"/> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>
This schema has been opened to accept any element from a single namespace and can be further opened to accept any element from any namespace other than the target namespace:
<xs:anyAttribute namespace="##other" processContents="skip"/>
This mechanism is flexible enough (with the exception of the lack of support for any undefined namespaces already mentioned) to accommodate a large majority of applications, but we must note that these wildcards are considered particles and can’t replace global element definitions. The unfortunate consequence is that document elements cannot be wildcarded because a schema needs to provide a closed list of possible document elements.
3.144.98.13