Sommaire
Cette section est normative.
Les modules XHTML sont mis en œuvre comme des fragments DTD. Lorsque ces fragments sont assemblés de manière spécifique (décrite à la section Développement de définitions DTD avec des modules définis et étendus), la définition DTD obtenue est une représentation d'un type de document complet. Cette représentation peut alors être utilisée pour la validation des instances du type de document.
Les clés de la combinaison de ces fragments en une définition DTD significative sont les règles utilisées pour définir les fragments. Cette section définit ces règles. En observant ces règles, les créateurs de définitions DTD peuvent être assurés que leurs modules s'interfaceront proprement avec d'autres modules compatibles avec XHTML.
Les modules conformes à ces règles doivent également satisfaire aux exigences de conformité définies à la section Conformité du module à la famille XHTML pour prétendre au titre de modules de la famille XHTML.
Cette spécification classe les entités paramètres en sept catégories et les nomme systématiquement en utilisant les suffixes suivants :
.mod lorsqu'elles servent à représenter un module DTD
(une collection d'éléments, d'attributs, d'entités paramètres, etc.). Dans cette spécification, chaque module est une unité atomique
et peut être représenté comme une entité de fichier séparée..module lorsqu'elles servent à contrôler l'inclusion d'un module DTD
en contenant l'un des deux mots-clés de section conditionnelle INCLUDE ou IGNORE..qname lorsqu'elles servent à représenter le nom qualifié d'un élément.
Cf. la section Définition de l'espace de noms d'un module pour davantage d'informations sur les noms qualifiés..content lorsqu'elles servent à représenter le modèle de contenu d'un type d'élément..class lorsqu'elles servent à représenter des éléments de la même classe..mix lorsqu'elles servent à représenter une collection de types d'élément provenant de classes différentes..attrib lorsqu'elles servent à représenter un groupe d'atomes représentant
une ou plusieurs spécifications d'attribut complètes au sein d'une déclaration ATTLIST.Par exemple, dans HTML 4, l'entité paramètre %block; est définie pour représenter la collection hétérogène des types d'éléments qui sont des éléments de type block. Dans cette spécification, l'entité paramètre corollaire est %Block.mix;.
Lors de la définition d'entités paramètres dans les classes définies ici, les modules devraient définir la portée (scope)
la portée des noms des entités en utilisant des préfixes uniques. Par exemple, le modèle de contenu de l'élément myelement
dans le module mymodule pourrait se nommer MYMODULE.myelement.content. D'autres systèmes sont possibles. Quel que soit
le système utilisé, les créateurs de modules devraient s'efforcer d'attribuer un nom unique aux entités paramètres qu'ils définissent
afin que ces entités paramètres n'entrent pas en conflit avec d'autres et que les méthodes d'interface du module soient claires pour
leurs utilisateurs.
XHTML impose que les éléments et attributs déclarés dans un module soient dans un espace de noms XML défini [XMLNAMES]. L'identification de cet espace de noms est une adresse URI arbitraire. XHTML impose, lorsque le module est mis en œuvre à l'aide d'une définition DTD XML, que ce module déclare l'espace de noms d'une manière spéciale. La raison de cela est de permettre, au moment de l'analyse ou de la validation du document, la sélection de l'utilisation des préfixes d'espace de noms et du préfixe utilisé pour identifier les éléments et attributs du module.
Les développeurs de contenus qui souhaitent créer des documents fondés sur des types de document hybrides peuvent choisir d'employer des préfixes d'espace de noms XML sur les éléments de l'espace de noms XHTML, sur les éléments d'autres espaces de noms, ou sur les deux. Pour assurer que de tels documents soient conformes et rétrocompatibles avec les outils qui ne gèrent pas les espaces de noms, le W3C recommande aux développeurs de contenus de ne pas utiliser de préfixes d'espace de noms XML sur les éléments de l'espace de noms XHTML. Lorsque l'intérêt des développeurs de contenus est d'avoir leurs contenus traités par des processeurs compatibles avec les espaces de noms, le W3C recommande en outre de spécifier les éléments des espaces de noms non-XHTML à l'aide d'un préfixe d'espace de nom XML plutôt que de compter sur les mécanismes par défaut des espaces de noms XML (XML namespace defaulting mechanisms).
Chaque module conforme à XHTML mis en œuvre en tant que définition DTD XML doit obligatoirement définir un préfixe d'espace de noms XML par défaut, une méthode pour changer ce préfixe dans une instance de document et une section marquée qui active le traitement du préfixe.
Notez qu'il est légal et prévu que plusieurs modules fassent partie du même espace de noms lorsque ceux-ci sont liés. Ainsi tous les modules XHTML appartiennent au même espace de noms.
Il faut d'abord définir un sous-module des noms qualifiés (un sous-module est simplement une entité de fichier à part afin qu'on puisse l'incorporer dans la définition DTD finale à l'endroit approprié). Le sous-module des noms qualifiés se construit en observant les étapes suivantes (où on remplace la chaîne "MODULE" par la chaîne appropriée du nouveau module) :
Si le module ajoute des attributs aux éléments définis dans des modules qui ne partagent pas son espace de noms, déclarer ces attributs pour qu'ils utilisent le préfixe %MODULE.pfx. Par exemple :
<ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
Voici l'exemple du sous-module de noms qualifiés d'un hypothétique module Inventory :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory-qname-1.mod. La dernière version est disponible à 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" >
Il faut ensuite définir un ou plusieurs sous-modules de déclaration (declaration sub-modules). La raison-d'être de ces entités fichiers est de déclarer les éléments et les listes d'attributs de la définition DTD XML. La construction d'un module de déclaration XHTML devrait se dérouler comme suit :
Si le module ajoute des attributs aux éléments définis dans des modules qui ne partagent pas son espace de noms, déclarer ces attributs pour utiliser le préfixe %MODULE.pfx. Par exemple :
<ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
<!ATTLIST %img.qname;
%MODULE.img.myattr.qname; CDATA #IMPLIED
>
Cela ajoutera un attribut à l'élément img du module Image, mais l'attribut aura un
nom qualifié, incluant le préfixe, lorsque les préfixes sont sélectionnés pour une instance du document. Cela ajoute aussi
l'attribut xmlns:MODULE_PREFIX à la liste d'attributs de l'élément img afin qu'un analyseur compatible avec les
espaces de noms XML sache comment résoudre l'espace de noms d'après son préfixe.
L'exemple suivant montre un sous-module de déclaration du module hypothétique Inventory :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory-1.mod. La dernière version est disponible à 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 -->
Il est parfois souhaitable d'avoir un module XHTML qui soit aussi utilisable comme une définition DTD autonome. Un bon exemple serait notre module Inventory ci-dessus. Ces éléments (items) doivent pouvoir être incorporés dans un document XHTML et aussi être disponibles comme des documents autonomes, par exemple, extraits d'une base de données. La méthode la plus facile d'y parvenir est de définir un fichier DTD qui instancie les composants du module. Une telle définition DTD aurait la structure suivante :
En voici un exemple pour notre module Inventory :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory-1.dtd. La dernière version est disponible à 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 -->
Cette définition DTD peut alors être référencée par les documents qui utilisent seulement les éléments du module :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory.xml. La dernière version est disponible à 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>
Cette méthode permet la définition d'éléments et d'attributs qui sont visibles (scoped) dans leur propre espace de noms. Elle permet aussi aux développeurs de contenus d'utiliser le préfixe par défaut des éléments et attributs :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory-prefixed.xml. La dernière version est disponible à 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>
Enfin, une instance du document peut employer un préfixe d'espace de noms XML différent en le redéclarant dans l'en-tête DOCTYPE et son sous-ensemble interne (internal subset) :
Cette version du fichier est récupérable à http://www.w3.org/TR/2008/REC-xhtml-modularization/DTD/examples/inventory-newprefix.xml. La dernière version est disponible à 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>
Bien que l'approche décrite ici permette la définition de langages de balisages compatibles avec XML et les espaces de noms XML, certains comportements définis par la spécification des espaces de noms XML ne sont pas gérés :
Les espaces de noms XML permettent la redéclaration de l'attribut xmlns pour un espace de noms en tout point dans l'arbre. Cela permet en outre à cette redéclaration de basculer entre espace de noms par défaut et utilisation avec préfixe, et permet le changement du préfixe. La méthode définie dans ce document ne le permet pas. Partout dans une instance de document, un espace de noms donné doit continuer d'utiliser le même préfixe d'espace de noms (lorsque le préfixage est utilisé), ou continuer d'être utilisé dans la visibilité par défaut (default scope) ;
Lors d'une utilisation de l'espace de noms par défaut, il est légal de compter sur la définition DTD du document pour communiquer aux analyseurs l'espace de noms des éléments. Toutefois, puisque les processeurs compatibles avec les espaces de noms ne sont pas obligés d'inclure la définition DTD lors de l'évaluation d'un document, les développeurs de contenus devraient déclarer l'espace de noms XML à chaque fois que l'espace de noms change :
... <p> <myelement xmlns="..." /> </p>