DO NOT use schema without the targetNamespace attribute
(AKA chameleon schema.) (why?)

The fact is, you don't lose anything by following these DON'Ts, as the rest of this paper
demonstrates.

Too long to remember? Then here is the one line version.

Consider W3C XML Schema as DTD + datatype + namespace

Motivation for this document

Several similar documents are already available on the web.
But I discovered that those documents are written by some special people;
they are brilliant people who always drive things to the limit.
They simply can't stop inventing cool tricks that even the working group member
can't imagine.

XML Schema is their new favorite toy.

There has to be a different document. A document for those who use W3C XML Schema
for business --- for those who are at a loss how to use it.

So the goal of this document is to provide a set of solid guidelines
about what you should do and what you shouldn't do.

If you don't know what a complex type is, then don't let it trouble you.
Whatever small gain this functionality offers is vastly outweighed by its complexity.

Furthermore, you won't lose anything by losing complex types;
the fact is, if a schema can be written by using complex types, then you can always
write it without complex types.

To be precise, you can always write it without understanding complex types,
but unfortunately you have to type <complexType> elements.

So what you should do is to consider a <complexType> as something you have to write
as a sole child of the <element> element.
That is, you write element declarations as follows:

...

So why spend your precious time learning something you don't need?

Convinced? then there is no need to read more.

In short, a complex type is a model group plus inheritance minus ease of use.
A complex type and a model group are siblings in the sense that they are used to define content models.
A complex type lacks ease of use because you can't use it from other complex types
or model groups. On the other hand, model groups can be used without such a restriction.

"Inheritance" is the only advantage that a complex type has.
So let me explain why you don't want to use inheritance.
There are two types of inheritance: specifically, extension
and restriction.

Extension allows you to append additional elements
after the content model of the base type. So the following model group
reproduces the semantics of the extension.

....

Restriction allows you to restrict the content model of the base type.
But even if you use this functionality, you still have to write the whole content model
of the new type.
Basically you type the same thing whether you use a complex type or a model group.

So, what do you get by using the restriction? The only thing you get is
error checking. Validators are supposed to report an error if you fail
to make a content model a restricted one.

But unfortunately, this is hardly an advantage.

First, it is a tough job for validators to strictly enforce this check.
You can have a look at
the part of the spec that defines this constraint
.
The entire section 3.9.6 is devoted to specifying what is allowed and what is not.
And you should know that there exists a strong temptation for developers
to skip the enforcement of this constraint because most people won't notice
that the check is skipped.
At the time of this writing, no validators are known to strictly enforce
this constraint.

So it is highly likely that your validator is not capable of fully enforcing
this constraint. That takes away the only advantage of restriction.

Second, even if you write the restriction correctly, you may get an error from
your validator. Consider the following example:

In short, the complexity of this functionality is too much to be practical. The main difficulties are:

To write substitution groups correctly, you have to master the complex type, which is by itself
another beast that you should avoid.

It is hard to tell which elements are actually substitutable.

Simply put, a substitution group is another way to write a <choice>.
So you can always use a <choice> instead of a substitution group. And <choice> is necessary
anyway.

To use substitution groups properly, first you have to learn complex types, then several additional attributes,
rules to use them, and finally the effect of using them.
Even if you manage to get through this brave new world,
your document authors still need to follow the same path all over again because otherwise
they can't write documents properly. What a pity.

If you still think you want to use substitution groups, then let me show you
it's not as easy as you think.

Firstly, the content models of substitution group members must be related to each other by type derivation.
That means you cannot write their content models freely. Soon you'll find yourself writing an abstract
element as a substitution group head with a strange content model,
just to maintain proper derivations between members. That's not right.

Secondly, attributes to control the substitution behavior are difficult to use and understand.
There is an attribute called block, which is one of the attributes
you use to control the substitution group.
There is another attribute called final, which basically
takes one of "extension", "restriction", or "#all" as its value.

final may look irrelevant to the substitution group, but the truth is it's internally called
"substitution group exclusions" and, as its name suggests,
it controls the behavior of the substitution group.
Do you know what is the internal name for the block attribute?
It's "disallowed substitutions". Having trouble understanding the difference? Yeah, me too.
Actually, both are used to control the substitution behavior, but in a different way.

For example, to prohibit the substitution of element Y by another element Z, the only way to do this is to add
block="substitution" to Y.
But even under the presence of this attribute, it is NOT an
error to have Z in the substitution group of Y. It's just that you can never substitute Y with Z
in your documents.

Even worse, if Y designates yet another element X as its substitution group head ( X <- Y <- Z ),
then it is OK to substitute X with Z.

All these things make it impractical to use a substitution group in the real world, although it may look
harmless when you are experimenting. And that's why you should avoid it.

W3C XML Schema allows the schema element without
the targetNamespace attribute. And some people
call those schemas chameleon schemas.
Why they are called "chameleon" is irrelevant; what you should know
is to avoid them.

One reason is that it is highly likely that validators will
have interoperability problems here.

Another reason is that some people like to invent cool tricks by using
a chameleon schema.
But don't be fooled by those tricks;
they are for schema hackers, not for ordinary good citizens.

Unfortunately, if you want to know exactly why you should avoid them, then
you have to learn what they are.

Consider the following chameleon schema

Then you write another schema file and include the above by using
the include element.

targetNamespace="http://example.com">

It seems OK, but actually it's not. Look at the line written in red.
It looks like a reference to the familyName element. But it's wrong.
Since this chameleon schema is included by a schema with
targetNamespace="http://example.com/",
the familyName element is in this namespace. So to refer to this
declaration, you have to rewrite the red line to

Now what happens if you want to reuse this chameleon schema from a schema
whose target namespace is http://www.foo.com?
The answer is you can't.

As you can see, the only merit of the chameleon schema is gone.

Even worse, you can't detect this error in some validators because they
think that those missing components may appear afterward.

Conclusion

As you see, there are many pitfalls that should be avoided.
But avoiding those pitfalls will make your life actually easier, because you
have less to learn.
You don't even lose the expressiveness of W3C XML Schema.