Contents
This section is normative.
XHTML modules are implemented as DTD fragments. When these fragments are assembled in a specific manner (described in Developing DTDs with defined and extended modules), the resulting DTD is a representation of a complete document type. This representation can then be used for validation of instances of the document type.
The key to combining these fragments into a meaningful DTD is the rules used to define the fragments. This section defines those rules. When these rules are followed, DTD authors can be confident that their modules will interface cleanly with other XHTML-compatible modules.
Modules conforming to these rules also need to satisfy the conformance requirements defined in XHTML Family Module Conformance in order to be called XHTML Family Modules.
This specification classifies parameter entities into seven categories and names them consistently using the following suffixes:
.mod
when they are used to represent a DTD module (a collection of elements, attributes, parameter entities, etc). In this specification, each
module is an atomic unit and may be represented as a separate file entity..module
when they are used to control the inclusion of a DTD module by containing either of the conditional section keywords INCLUDE or
IGNORE..qname
when they are used to represent the qualified name of an element. See Defining the Namespace of a
Module for more information on qualified names..content
when they are used to represent the content model of an element type..class
when they are used to represent elements of the same class..mix
when they are used to represent a collection of element types from different classes..attrib
when they are used to represent a group of tokens representing one or more complete attribute specifications within an ATTLIST
declaration.For example, in HTML 4, the %block; parameter entity is defined to represent the heterogeneous collection of element types that are block-level elements. In this specification, the corollary parameter entity is %Block.mix;.
When defining parameter entities in the classes defined here, modules should scope the names of the entities by using unique prefixes. For example, the content model for the element
myelement
in the module mymodule could be named MYMODULE.myelement.content
. Other schemes are possible. Regardless of the scheme used, module authors should strive to ensure that
parameter entities they define are named uniquely so that they do not collide with other parameter entities and so that the interface methods for the module are obvious to its users.
XHTML requires that the elements and attributes declared in a module be within a defined XML namespace [XMLNAMES]. The identification of this namespace is an arbitrary URI. XHTML requires that when a module is implemented using an XML DTD, the module declares the namespace in a special manner. The purpose of this is to permit the selection, at document parse/validation time, of the use of namespace prefixes and of the prefix that is used to identify elements and attributes from the module.
Content developers who wish to develop documents based upon hybrid document types may choose to use XML namespace prefixes on elements from the XHTML namespace, on elements from other namespaces, or on both. In order to ensure that such documents are XHTML conforming and backward compatible with non-namespace aware tools, the W3C recommends that content developers do not use XML namespace prefixes on elements from the XHTML namespace. When content developers are interested in having their content processed by namespace-aware processors, the W3C further recommends that elements in non-XHTML namespaces be specified using an XML namespace prefix rather than relying upon XML namespace defaulting mechanisms.
Each XHTML-conforming module implemented as an XML DTD is required to define a default XML namespace prefix, a method for changing this prefix within a document instance, and a marked section that turns on the processing of the prefix.
Note that it is legal and expected for multiple modules to be part of the same namespace when they are related. All of the XHTML modules, for example, are part of the same namespace.
First, you need to define a qualified names sub-module (a sub-module is just a file entity that is separated so that it can be incorporated into the ultimate DTD at the appropriate point). The qualified names sub-module is built using the following steps (where the string MODULE is replaced with an appropriate string for the new module):
If the module adds attributes to elements defined in modules that do not share the namespace of this module, declare those attributes so that they use the %MODULE.pfx prefix. For example:
<ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
An example of a qname sub-module for a hypothetical Inventory Module is included below:
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory-qname-1.mod. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory-qname-1.mod.
<!-- ...................................................................... --> <!-- Inventory Qname Module ................................................... --> <!-- file: inventory-qname-1.mod PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Qnames 1.0//EN" SYSTEM "http://www.example.com/DTDs/inventory-qname-1.mod" xmlns:inventory="http://www.example.com/xmlns/inventory" ...................................................................... --> <!-- Declare the default value for prefixing of this module's elements --> <!-- Note that the NS.prefixed will get overridden by the XHTML Framework or by a document instance. --> <!ENTITY % NS.prefixed "IGNORE" > <!ENTITY % Inventory.prefixed "%NS.prefixed;" > <!-- Declare the actual namespace of this module --> <!ENTITY % Inventory.xmlns "http://www.example.com/xmlns/inventory" > <!-- Declare the default prefix for this module --> <!ENTITY % Inventory.prefix "inventory" > <!-- Declare the prefix for this module --> <![%Inventory.prefixed;[ <!ENTITY % Inventory.pfx "%Inventory.prefix;:" > ]]> <!ENTITY % Inventory.pfx "" > <!-- Declare the xml namespace attribute for this module --> <![%Inventory.prefixed;[ <!ENTITY % Inventory.xmlns.extra.attrib "xmlns:%Inventory.prefix; %URI.datatype; #FIXED '%Inventory.xmlns;'" > ]]> <!ENTITY % Inventory.xmlns.extra.attrib "" > <!-- Declare the extra namespace that should be included in the XHTML elements --> <!ENTITY % XHTML.xmlns.extra.attrib "%Inventory.xmlns.extra.attrib;" > <!-- Now declare the qualified names for all of the elements in the module --> <!ENTITY % Inventory.shelf.qname "%Inventory.pfx;shelf" > <!ENTITY % Inventory.item.qname "%Inventory.pfx;item" > <!ENTITY % Inventory.desc.qname "%Inventory.pfx;desc" > <!ENTITY % Inventory.sku.qname "%Inventory.pfx;sku" > <!ENTITY % Inventory.price.qname "%Inventory.pfx;price" >
Next, you need to define one or more "declaration sub-modules". The purpose of these file entities is to declare the XML DTD elements and attribute lists. An XHTML declaration module should be constructed using the following process:
If the module adds attributes to elements defined in modules that do not share the namespace of this module, declare those attributes so that they use the %MODULE.pfx prefix. For example:
<ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" > <!ATTLIST %img.qname; %MODULE.img.myattr.qname; CDATA #IMPLIED >
This would add an attribute to the img
element of the Image Module, but the attribute's name will be the qualified name, including prefix, when prefixes are selected for a document
instance. It also adds the xmlns:MODULE_PREFIX attribute to the img element's attribute list so that an XML Namespace-aware parser would know how to resolve the namespace based upon its prefix.
The following example shows a declaration sub-module for a hypothetical Inventory module.
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory-1.mod. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory-1.mod.
<!-- ...................................................................... --> <!-- Inventory Elements Module ................................................... --> <!-- file: inventory-1.mod PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Elements 1.0//EN" SYSTEM "http://www.example.com/DTDs/inventory-1.mod" xmlns:inventory="http://www.example.com/xmlns/inventory" ...................................................................... --> <!-- Inventory Module shelf item sku desc price This module defines a simple inventory item structure --> <!-- Define the global namespace attributes --> <![%Inventory.prefixed;[ <!ENTITY % Inventory.xmlns.attrib "%NS.decl.attrib;" > ]]> <!ENTITY % Inventory.xmlns.attrib "%NS.decl.attrib; xmlns %URI.datatype; #FIXED '%Inventory.xmlns;'" > <!-- Define a common set of attributes for all module elements --> <!ENTITY % Inventory.Common.attrib "%Inventory.xmlns.attrib; id ID #IMPLIED" > <!-- Define the elements and attributes of the module --> <!ELEMENT %Inventory.shelf.qname; ( %Inventory.item.qname; )* > <!ATTLIST %Inventory.shelf.qname; location CDATA #IMPLIED %Inventory.Common.attrib; > <!ELEMENT %Inventory.item.qname; ( %Inventory.desc.qname;, %Inventory.sku.qname;, %Inventory.price.qname;) > <!ATTLIST %Inventory.item.qname; location CDATA #IMPLIED %Inventory.Common.attrib; > <!ELEMENT %Inventory.desc.qname; ( #PCDATA ) > <!ATTLIST %Inventory.desc.qname; %Inventory.Common.attrib; > <!ELEMENT %Inventory.sku.qname; ( #PCDATA ) > <!ATTLIST %Inventory.sku.qname; %Inventory.Common.attrib; > <!ELEMENT %Inventory.price.qname; ( #PCDATA ) > <!ATTLIST %Inventory.price.qname; %Inventory.Common.attrib; > <!-- end of inventory-1.mod -->
It is sometimes desirable to have an XHTML module also usable as a stand alone DTD. A good example of this is our Inventory module above. These items need to be embeddable in an XHTML document, and also need to be available as free-standing documents extracted from a database (for example). The easiest way to accomplish this is to define a DTD file that instantiates the components of your module. Such a DTD would have this structure:
An example of this for our Inventory module is included below:
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory-1.dtd. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory-1.dtd.
<!-- ...................................................................... --> <!-- Inventory Elements DTD ............................................... --> <!-- file: inventory-1.dtd PUBLIC "-//MY COMPANY//DTD XHTML Inventory 1.0//EN" SYSTEM "http://www.example.com/DTDs/inventory-1.dtd" xmlns:inventory="http://www.example.com/xmlns/inventory" ...................................................................... --> <!-- Inventory Module shelf item sku desc price This module defines a simple inventory item structure --> <!-- Bring in the datatypes --> <!ENTITY % xhtml-datatypes.mod PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-datatypes-1.mod" > %xhtml-datatypes.mod; <!-- Bring in the qualified names --> <!ENTITY % Inventory-qname.mod SYSTEM "inventory-qname-1.mod" > %Inventory-qname.mod; <!ENTITY % NS.decl.attrib "%Inventory.xmlns.extra.attrib;"> <!ENTITY % Inventory.mod SYSTEM "inventory-1.mod" > %Inventory.mod; <!-- end of inventory-1.dtd -->
This DTD can then be referenced by documents that use only the elements from your module:
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory.xml. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory.xml.
<!DOCTYPE shelf SYSTEM "inventory-1.dtd"> <shelf xmlns="http://www.example.com/xmlns/inventory"> <item> <desc> this is a description. </desc> <sku> this is the price. </sku> <price> this is the price. </price> </item> </shelf>
This method permits the definition of elements and attributes that are scoped within their own namespace. It also permits content developers to use the default prefix for the elements and attributes:
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory-prefixed.xml. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory-prefixed.xml.
<!DOCTYPE inventory:shelf SYSTEM "inventory-1.dtd" [ <!ENTITY % Inventory.prefixed "INCLUDE"> ]> <inventory:shelf xmlns:inventory="http://www.example.com/xmlns/inventory"> <inventory:item> <inventory:desc> this is a description. </inventory:desc> <inventory:sku> this is the sku. </inventory:sku> <inventory:price> this is the price. </inventory:price> </inventory:item> </inventory:shelf>
Finally, a document instance can use a different XML namespace prefix by redeclaring it in the DOCTYPE header and its internal subset:
You can download this version of this file from http://www.w3.org/TR/2010/REC-xhtml-modularization/DTD/examples/inventory-newprefix.xml. The latest version is available at http://www.w3.org/MarkUp/DTD/examples/inventory-newprefix.xml.
<!DOCTYPE i:shelf SYSTEM "inventory-1.dtd" [ <!ENTITY % Inventory.prefixed "INCLUDE"> <!ENTITY % Inventory.prefix "i"> ]> <i:shelf xmlns:i="http://www.example.com/xmlns/inventory"> <i:item> <i:desc> this is a description. </i:desc> <i:sku> this is the price. </i:sku> <i:price> this is the price. </i:price> </i:item> </i:shelf>
While the approach defined here permits the definition of markup languages that are XML and XML namespaces conforming, some behaviors defined by the XML namespaces specification are not supported:
XML namespaces permit the redeclaration of the xmlns attribute for a namespace at any point in the tree. It further permits this redeclaration to switch between namespace defaulting and prefixed usage, and permits the changing of the prefix. The method defined in this document does not permit this. Throughout a document instance a given namespace must continue to use the same namespace prefix (when prefixing is used), or must continue to be used in the default scope.
When using XML namespace defaulting, it is legal to rely upon the DTD of the document to inform parsers of the namespace of elements. However, since namespace aware processors are not required to include the DTD when evaluating a document, content developers should declare the XML namespace of an element whenever the namespace changes:
... <p> <myelement xmlns="..." /> </p>