Namespaces are completely independent of DTDs and can be used in
both valid and invalid documents. A document can have a DTD but not
use namespaces or use namespaces but not have a DTD. It can use both
namespaces and DTDs or neither namespaces nor DTDs. Namespaces do not
in any way change DTD syntax nor do they change the definition of
validity. For instance, the DTD of a valid document that uses an
element named dc:title
must include
an ELEMENT
declaration properly
specifying the content of the dc:title
element. For example:
<!ELEMENT dc:title (#PCDATA)>
The name of the element in the document must exactly match the
name of the element in the DTD, including the prefix. The DTD cannot
omit the prefix and simply declare a title
element. The same is true of prefixed
attributes. For instance, if an element used in the document has
xlink:type
and xlink:href
attributes, then the DTD must
declare the xlink:type
and xlink:href
attributes, not simply type
and href
.
Conversely, if an element uses an xmlns
attribute to set the default namespace
and does not attach prefixes to elements, then the names of the
elements must be declared without prefixes in the DTD. The validator
neither knows nor cares about the existence of namespaces. All it sees
is that some element and attribute names happen to contain colons; as
far as it's concerned, such names are perfectly valid as long as
they're declared.
Requiring DTDs to declare the prefixed names, instead of the raw names or some combination of local part and namespace URI, makes it difficult to change the prefix in valid documents. The problem is that changing the prefix requires changing all declarations that use that prefix in the DTD. However, with a little forethought, parameter entity references can alleviate the pain quite a bit.
The trick is to define both the namespace prefix and the colon that separates the prefix from the local name as parameter entities, like this:
<!ENTITY % dc-prefix "dc"> <!ENTITY % dc-colon ":">
The second step is to define the qualified names as more parameter entity references, like these:
<!ENTITY % dc-title "%dc-prefix;%dc-colon;title"> <!ENTITY % dc-creator "%dc-prefix;%dc-colon;creator"> <!ENTITY % dc-description "%dc-prefix;%dc-colon;description"> <!ENTITY % dc-date "%dc-prefix;%dc-colon;date">
Do not omit this step and try to use the dc-prefix
and dc-colon
parameter entities directly in
ELEMENT
and ATTLIST
declarations. This will fail
because XML parsers add extra space around the entity's
replacement text when they're used outside another entity's
replacement text.
Then you use the entity references for the qualified name in all declarations, like this:
<!ELEMENT %dc-title; (#PCDATA)> <!ELEMENT %dc-creator; (#PCDATA)> <!ELEMENT %dc-description; (#PCDATA)> <!ELEMENT %dc-date; (#PCDATA)> <!ELEMENT rdf:Description ((%dc-title; | %dc-creator; | %dc-description; | %dc-date; )*) >
Now a document that needs to change the prefix simply changes
the parameter entity definitions. In some cases, this will be done
by editing the DTD directly. In others, it may be done by overriding
the definitions in the document's internal DTD subset. For example,
to change the prefix from dc
to
dublin
, you'd add this entity
definition somewhere in the DTD before the normal definition:
<!ENTITY % dc-prefix "dublin">
If you wanted to use the default namespace instead of explicit
prefixes, you'd redefine both the dc-prefix
and dc-colon
entities as the empty string,
like this:
<!ENTITY % dc-prefix ""> <!ENTITY % dc-colon "">