XHTML Modules and Markup Languages

How to create XHTML Family modules and markup languages for fun and profit

Last Updated: $Date: 2001/08/01 19:26:28 $

Editor:
Shane McCarron, Applied Testing and Technology

Full Table of Contents

1. Introduction

XHTML Modularization provides a structure for the creation of new markup languages through the extension of the XHTML Core modules and the use of the XHTML Module Framework. In some instances, people will want to create complete, proprietary markup languages through these mechanisms. In other instances, people may wish to create new, reusable modules that will be used by their organization or by others in the definition of markup languages. In either case, the mechanics of the modules added and the markup language definition are the same. This document describes the manner in which such modules are defined, and the way in which modules should be combined to create new markup languages.

2. Terminology

Markup Language
A grammar (in this case, an XML grammar) that can be used to structure information. Once structured, the information can be processed in the context of the markup language. Such processing might include presentation to a user, extraction of key information, transformation into other forms, etc.
Hybrid Markup Language
A Markup Language that is made up of Modules from multiple Namespaces.
Namespace
A namespace is a collection of names that are delimited in some way. An XML Namespace is a W3C-defined mechanism for delimiting XML elements and attributes. XHTML-defined modules are all in the XHTML Namespace. XHTML-family modules are required to be in their own XML Namespace. XHTML Modularization defines a mechanism for declaring the XML Namespace of a module in a way that is compatible with XML DTDs and permits XML Validation of XHTML-family documents.
XML Validation
The XML Recommendation defines validation ensuring that a document is well-formed and that it conforms to the content model defined in the document's associated DTD. XHTML family documents are required to be XML Valid.
Module
In XHTML, a module is a collection of one or more files that define entities, elements, and/or attributes. A module may represent a complete, stand-alone markup language. It may also represent a small, incremental change to some other markup language or some other module. Regardless, modules can be combined with other modules using the XHTML Framework. With care, the elements defined by these modules can be combined into a complete content model for a markup language.
DTD
DTD is a grammar in which XML-based markup languages can be defined (there are others, but right now we are talking about DTDs). It is also a term commonly used to refer to the file in which a markup language definition can be found. In the context of XHTML Modules and Markup Languages, a DTD is actually a file that includes the XHTML-family modules that make up the markup language (along with some other helper files). In DTD parlance, this file can also be called a "DTD Driver" file.
Qualified Name
The combination of XML and XML Namespaces gives rise to a class of elements and attributes that have "qualified names". A qualified name consists of the element or attribute name, possibly prefixed with a namespace declarator (e.g. xhtml:p for paragraph). In XHTML, the qualified names for elements and attributes are defined in a Qname Module.
Qname Module
When defining an XHTML Module, you must create a sub-module in which the qualified names for the module are declared, and in which some set-up for XML namespaces is done. XHTML Modularization calls these sub-modules Qname Modules. A complete XHTML-family Module definition will include at least a Qname Module and a Declaration Module.
Declaration Module
A Declaration Module is an XHTML Module in which the elements, attributes, and possibly structure of a Module are defined. The Declaration Module relies upon parameter entities defined in an associated Qname Module to define the actual names of elements and attributes, so that these can be properly qualified when XML Namespace prefixes are used.

3. Module Construction

XHTML Modules are made up of at least two modules - a Qname Module and a Declaration Module. In this section we will walk through building each of these. In the next section we will use this new module with another XHTML-family module and some XHTML Core modules to define a new markup language.

3.1. Defining the Qname Module

An XHTML Qname Module should be constructed using the following process:

  1. Define a parameter entity MODULE.prefixed that announces whether the elements in the module are being used with XML Namespace prefixed names or not. This parameter entity's default value should be "%NS.prefixed;". The NS.prefixed parameter entity is defined by the XHTML framework to be IGNORE by default, and can be used in a document instance to switch on prefixing for all included namespaces (see the prefixing example for more on this).
  2. Define a parameter entity MODULE.xmlns that contains the namespace identifier for this module.
  3. Define a parameter entity MODULE.prefix that contains the default prefix string to use when prefixing is enabled.
  4. Define a parameter entity MODULE.pfx that is "%MODULE.prefix;:" when prefixing is enabled, and "" when it is not.
  5. Define a parameter entity MODULE.xmlns.extra.attrib that contains the declaration of any XML Namespace attributes for namespaces referenced by this module (e.g., xmlns:xlink). When %MODULE.prefix is set to INCLUDE, this attribute should include the xmlns:%MODULE.pfx; declaration as well.
  6. For each of the elements defined by the module, create a parameter entity of the form "MODULE.NAME.qname" to hold its qualified name. The value for this parameter entity must be "%MODULE.pfx;NAME". In this way, the parsed value will be "PREFIX:NAME" when prefixes are enabled, and "NAME" otherwise. For example:
<!ENTITY % MODULE.myelement.qname "%MODULE.pfx;myelement" >

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" >

3.2. Defining the Declaration Module

An XHTML Declaration Module should be constructed using the following process:

  1. Define a parameter entity to use within the ATTLIST of each declared element. This parameter entity should be %NS.decl.attrib; when %MODULE.prefixed; is set to INCLUDE, and %NS.decl.attrib; plus "xmlns=%MODULE.xmlns;" when %MODULE.prefixed; is set to IGNORE.
  2. Declare all of the elements and attributes for the module. Within each ATTLIST for an element, include the parameter entity defined above so that all of the required xmlns attributes are available on each element in the module.

3.3. Using the module as a stand-alone DTD

It is sometimes desirable to have an XHTML module also usable as a stand alone DTD. A good example of this might be a module that defines inventory items. These items need to be embeddable in an XHTML document, and also need to be available as free-standing documents extracted from a database (or something). 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:

  1. Include the XHTML Datatypes module (your qnames module likely uses some of these datatypes).
  2. Include the Qnames Module for your module.
  3. Define the parameter entity %NS.prefixed.attrib to be MODULE.xmlns.extra.attrib when MODULE.prefixed is set to IGNORE, or to be MODULE.xmlns.extra.attrib and "xmlns:MODULE.prefix=MODULE.xmlns" when MODULE.prefixed is set to INCLUDE.
  4. Include the Declaration Module(s) for your module.

This DTD can then be referenced by documents that use only the elements from your module.

4. DTD Construction

Once you have defined your module(s), you are going to want to combine them with XHTML and other modules to create a new markup language. Since in this document we are talking about building these markup languages using DTDs, what you need to do is define a DTD that reflects the markup language. In the remainder of this section, we will explore the process for creating such a "hybrid markup language".

4.1. Define the Content Model as a 'Model Module'

A Model Module is an XHTML Module that defines the content model for your new markup language. This module can be extremely complex, or it can be as simple as the declaration of a parameter entity and the inclusion of some other Model Module. Regardless, the purpose is the same: Define the structure of all of the elements in your markup language.

4.2. Define the qualified names collection

Your markup language may include one or more additional XHTML-family Modules. Each of these Modules will have a Qname Module. The qualified names collection is a module in which all of the Qname Modules are instantiated, and the set of prefixed attributes are defined. Specifically, a qualified names collection module contains:

  1. A reference to the Qname Module of each non-XHTML module included
  2. A definition of the parameter entity XHTML.xmlns.extra.attrib to be the collection of the MODULE.xmlns.extra.attrib parameter entities, one from each included Module.

4.3. Define the Driver

The driver is the actual file that is referenced by documents written in your new markup language. The driver may be complex or simple, depending upon the markup language. However, each XHTML-family markup language driver must contain the following elements in order to work well:

  1. A definition of the parameter entity XHTML.version. This should be set to the Formal Public Identifier for your new markup language.
  2. A definition of the parameter entity xhtml-qname-extra.mod. This must be set to the qualified names collection module defined above. It is fine to have this as only a SYSTEM identifier, since it is internal to the DTD.
  3. A definition of the parameter entity xhtml-model.mod. This must be set to the Model Module defined above. It is fine to also have this as only a SYSTEM identified, since it is internal to the DTD.
  4. A series of references to the modules that make up the DTD. This may be a reference to another DTD that you are incrementally modifying, or it may be an explicit list of the XHTML Modules that are being included, or some combination of the two. Regardless, the first thing that actually gets instantiated through this reference is the XHTML Modularization Framework Module. This Module takes care of incorporating all of the XHTML infrastructure, merging it with your specified qualified names and your content model via the parameter entities defined in steps 2 and 3. Don't forget to include your new Declaration Modules, since that is where your new markup languages elements and attributes are defined!

Now you are ready to go. Your new Markup Language, defined via a DTD, can be referenced in the DOCTYPE declaration of a document, and that document can be validated against your new DTD using common commercial and free-ware tools.

5. Module Examples

In the following sections, you will see examples of each type of module referred to in this document, as well as the components that make up two different markup language definitions.

5.1. Qname Modules

This first qname module is for an inventory module. The second is for some extensions to the inventory module.

5.1.1. Inventory Qname Module

<!-- ...................................................................... -->
<!-- Inventory Qname Module ................................................... -->
<!-- file: inventory-qname-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Qnames 1.0//EN"
     SYSTEM "http://www.my.org/DTDs/inventory-qname-1.mod"

     xmlns:inventory="http://www.my.org/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.my.org/xmlns/inventory" >

<!-- Declare the default prefix for this module -->
<!ENTITY % Inventory.prefix "inventory" >

<!-- Declare the prefix and any prefixed namespaces that are required by 
     this module -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.pfx "%Inventory.prefix;:" >
<!ENTITY % Inventory.xmlns.extra.attrib
    "xmlns:%Inventory.prefix;   %URI.datatype;  #FIXED  '%Inventory.xmlns;'" >
]]>
<!ENTITY % Inventory.pfx "" >
<!ENTITY % Inventory.xmlns.extra.attrib "" >

<!ENTITY % XHTML.xmlns.extra.attrib "%Inventory.xmlns.extra.attrib;" >

<!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" >

5.1.2. Inventory Extensions Qname Module

<!-- ...................................................................... -->
<!-- Extension Qname Module ............................................... -->
<!-- file: extension-qname-1.mod

     xmlns:invext="http://www.my.org/xmlns/invext"
     ...................................................................... -->

<!-- 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 % Extension.prefixed "%NS.prefixed;" >

<!-- Declare the actual namespace of this module -->
<!ENTITY % Extension.xmlns "http://www.my.org/xmlns/invext" >

<!-- Declare the default prefix for this module -->
<!ENTITY % Extension.prefix "invext" >

<!-- Declare the prefix and any prefixed namespaces that are required by 
     this module -->
<![%Extension.prefixed;[
<!ENTITY % Extension.pfx "%Extension.prefix;:" >
<!ENTITY % Extension.xmlns.extra.attrib
    "xmlns:%Extension.prefix;   %URI.datatype;  #FIXED  '%Extension.xmlns;'" >
]]>
<!ENTITY % Extension.pfx "" >
<!ENTITY % Extension.xmlns.extra.attrib "" >

<!ENTITY % Extension.store.qname "%Extension.pfx;store" >
<!ENTITY % Extension.aisle.qname "%Extension.pfx;aisle">

5.2. Declaration Modules

The first declaration module is for the inventory module elements. The second is for the extension elements.

5.2.1. Inventory Declaration Module

<!-- ...................................................................... -->
<!-- Inventory Elements Module ................................................... -->
<!-- file: inventory-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Elements 1.0//EN"
     SYSTEM "http://www.my.org/DTDs/inventory-1.mod"

     xmlns:inventory="http://www.my.org/xmlns/inventory"
     ...................................................................... -->

<!-- Inventory Module

     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;'"
>

<!ELEMENT %Inventory.shelf.qname;
     ( %Inventory.item.qname; )* >
<!ATTLIST %Inventory.shelf.qname;
     location   CDATA   #IMPLIED
     %Inventory.xmlns.attrib;
>
<!ELEMENT %Inventory.item.qname;
     ( %Inventory.desc.qname;, %Inventory.sku.qname;, %Inventory.price.qname;) >
<!ATTLIST %Inventory.item.qname;
     location   CDATA   #IMPLIED
     %Inventory.xmlns.attrib;
>

<!ELEMENT %Inventory.desc.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.desc.qname;
     %Inventory.xmlns.attrib;
>

<!ELEMENT %Inventory.sku.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.sku.qname;
     %Inventory.xmlns.attrib;
>

<!ELEMENT %Inventory.price.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.price.qname;
     %Inventory.xmlns.attrib;
>

<!-- end of inventory-1.mod -->

5.2.2. Inventory Extensions Declaration Module

<!-- ...................................................................... -->
<!-- Extension Elements Module ................................................... -->
<!-- file: extension-1.mod

     SYSTEM "extension-1.mod"

     xmlns:invext="http://www.my.org/xmlns/invext"
     ...................................................................... -->

<!-- Extension Module

     store
       aisle

     This module defines an extension to the inventory structure
-->

<!-- Define the global namespace attributes -->
<![%Extension.prefixed;[
<!ENTITY % Extension.xmlns.attrib
    "%NS.decl.attrib;"
>
]]>
<!ENTITY % Extension.xmlns.attrib
    "%NS.decl.attrib;
     xmlns  %URI.datatype;  #FIXED '%Extension.xmlns;'"
>

<!ELEMENT %Extension.store.qname;
     ( %Extension.aisle.qname; )* >
<!ATTLIST %Extension.store.qname;
     name   CDATA   #IMPLIED
     %Extension.xmlns.attrib;
>
<!ELEMENT %Extension.aisle.qname;
     ( %Inventory.shelf.qname; )* >
<!ATTLIST %Extension.aisle.qname;
     number CDATA   #IMPLIED
     %Extension.xmlns.attrib;
>

<!-- end of extension-1.mod -->

6. Markup Language Examples

6.1. XHTML-Inventory Extensions - an XHTML Family Markup Language

This markup language complies with all of the requirements for an XHTML family markup language. It uses the XHTML Core Modules, and extends that with the Inventory and Inventory Extensions modules defined above.

6.1.1. Qname Collection Module

<!-- Bring in the inventory qualified names -->
<!ENTITY % Inventory-qname.mod
         PUBLIC "-//MY COMPANY//ENTITIES XHTML Inventory Qnames 1.0//EN"
         "inventory-qname-1.mod" >
%Inventory-qname.mod;

<!-- Bring in the local extension module -->
<!ENTITY % Extension-qname.mod
        SYSTEM "extension-qname-1.mod" >
%Extension-qname.mod;

<!-- Define the xmlns extension attributes -->
<!ENTITY % XHTML.xmlns.extra.attrib
         "%Inventory.xmlns.extra.attrib;
          %Extension.xmlns.extra.attrib;" >

6.1.2. Content Model Module

<!-- ...................................................................... -->
<!-- Inventory Extension Model Module  .................................... -->
<!-- file: xhtml-invext-model-1.mod

     SYSTEM "xhtml-invext-model-1.mod"
     ...................................................................... -->

<!-- Define the content model for Misc.extra -->
<!ENTITY % Misc.class
     "| %script.qname; | %noscript.qname; | %Extension.store.qname; ">

<!-- ....................  Inline Elements  ...................... -->

<!ENTITY % HeadOpts.mix  
     "( %meta.qname; )*" >

<!ENTITY % I18n.class "" >

<!ENTITY % InlStruct.class "%br.qname; | %span.qname;" >

<!ENTITY % InlPhras.class
     "| %em.qname; | %strong.qname; | %dfn.qname; | %code.qname; 
      | %samp.qname; | %kbd.qname; | %var.qname; | %cite.qname; 
      | %abbr.qname; | %acronym.qname; | %q.qname;" >

<!ENTITY % InlPres.class
     "| %tt.qname; | %i.qname; | %b.qname; | %big.qname; 
      | %small.qname; | %sub.qname; | %sup.qname;" >

<!ENTITY % Anchor.class "| %a.qname;" >

<!ENTITY % InlSpecial.class "| %img.qname; " >

<!ENTITY % Inline.extra "" >

<!-- %Inline.class; includes all inline elements,
     used as a component in mixes
-->
<!ENTITY % Inline.class
     "%InlStruct.class;
      %InlPhras.class;
      %InlPres.class;
      %Anchor.class;
      %InlSpecial.class;"
>

<!-- %InlNoAnchor.class; includes all non-anchor inlines,
     used as a component in mixes
-->
<!ENTITY % InlNoAnchor.class
     "%InlStruct.class;
      %InlPhras.class;
      %InlPres.class;
      %InlSpecial.class;"
>

<!-- %InlNoAnchor.mix; includes all non-anchor inlines
-->
<!ENTITY % InlNoAnchor.mix
     "%InlNoAnchor.class;
      %Misc.class;"
>

<!-- %Inline.mix; includes all inline elements, including %Misc.class;
-->
<!ENTITY % Inline.mix
     "%Inline.class;
      %Misc.class;"
>

<!-- .....................  Block Elements  ...................... -->

<!ENTITY % Heading.class 
     "%h1.qname; | %h2.qname; | %h3.qname; 
      | %h4.qname; | %h5.qname; | %h6.qname;" >

<!ENTITY % List.class "%ul.qname; | %ol.qname; | %dl.qname;" >

<!ENTITY % Blkstruct.class "%p.qname; | %div.qname;" >

<!ENTITY % Blkphras.class 
     "| %pre.qname; | %blockquote.qname; | %address.qname;" >

<!ENTITY % Blkpres.class "| %hr.qname;" >

<!ENTITY % Block.extra "" >

<!-- %Block.class; includes all block elements,
     used as an component in mixes
-->
<!ENTITY % Block.class
     "%Blkstruct.class;
      %Blkphras.class;
      %Blkpres.class;
      %Block.extra;"
>

<!-- %Block.mix; includes all block elements plus %Misc.class;
-->
<!ENTITY % Block.mix
     "%Heading.class;
      | %List.class;
      | %Block.class;
      %Misc.class;"
>

<!-- ................  All Content Elements  .................. -->

<!-- %Flow.mix; includes all text content, block and inline
-->
<!ENTITY % Flow.mix
     "%Heading.class;
      | %List.class;
      | %Block.class;
      | %Inline.class;
      %Misc.class;"
>

<!-- end of xhtml-invext-model-1.mod -->

6.1.3. DTD Driver

<!-- ....................................................................... -->
<!-- Inventory Extension DTD  .............................................. -->
<!-- file: xhtml-invext-1.dtd -->

<!-- This is the DTD driver for inventory extension 1.0.

     Please use this formal public identifier to identify it:

         "-//MY COMPANY//DTD XHTML Inventory Extension 1.0//EN"

     And this namespace for extension-unique elements:

         xmlns:inventory="http://www.my.org/xmlns/invext"
     
     Other namespaces are also included.
-->
<!ENTITY % XHTML.version  "-//MY COMPANY//DTD XHTML Inventory Extension 1.0//EN" >

<!-- Define the xhtml qualified names module to be ours -->
<!ENTITY % xhtml-qname-extra.mod
     SYSTEM "xhtml-invext-qname-1.mod" >

<!-- reserved for use with document profiles -->
<!ENTITY % XHTML.profile  "" >

<!-- Define the Content Model for the framework to use -->
<!ENTITY % xhtml-model.mod
     SYSTEM "xhtml-invext-model-1.mod" >

<!-- Disable bidirectional text support -->
<!ENTITY % XHTML.bidi  "INCLUDE" >

<!-- Bring in the XHTML Framework -->
<!ENTITY % xhtml-framework.mod
     PUBLIC "-//W3C//ENTITIES XHTML Modular Framework 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-framework-1.mod" >
%xhtml-framework.mod;

<!-- Text Module (Required)  ............................... -->
<!ENTITY % xhtml-text.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Text 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod" >
%xhtml-text.mod;

<!-- Hypertext Module (required) ................................. -->
<!ENTITY % xhtml-hypertext.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Hypertext 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod" >
%xhtml-hypertext.mod;

<!-- Lists Module (required)  .................................... -->
<!ENTITY % xhtml-list.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Lists 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod" >
%xhtml-list.mod;

<!-- Inventory Module   ........................................ -->
<!ENTITY % Inventory-elements.mod
     SYSTEM "inventory-1.mod" >
%Inventory-elements.mod;

<!-- Inventory Extension Module   .............................. -->
<!ENTITY % Invext-elements.mod
     SYSTEM "extension-1.mod" >
%Invext-elements.mod;

<!-- XHTML Images module  ........................................ -->
<!ENTITY % xhtml-image.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-image-1.mod" >
%xhtml-image.mod;

<!-- Document Metainformation Module  ............................ -->
<!ENTITY % xhtml-meta.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Metainformation 1.0//EN"
            "xhtml-meta-1.mod" >
%xhtml-meta.mod;

<!-- Document Structure Module (required)  ....................... -->
<!ENTITY % xhtml-struct.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Document Structure 1.0//EN"
            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-struct-1.mod" >
%xhtml-struct.mod;

7. Usage Examples

7.1. XHTML-Inventory with no prefixes

This example uses the new markup language in its default form - with no prefixes being defined for any module.

<!DOCTYPE html SYSTEM "xhtml-invext-1.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>An example using defaults</title>
</head>
<body>
<p>This is content in the XHTML namespace</p>
<shelf>
  <item>
    <desc>
      this is a description.
    </desc>
    <sku>
      this is the price.
    </sku>
    <price>
      this is the price.
    </price>
  </item>
</shelf>
</body>
</html>

7.2. XHTML-Inventory with Inventory prefixes

This example uses the new markup language with prefixes enabled for just the inventory and extension components.

r!DOCTYPE html SYSTEM "xhtml-invext-1.dtd" [
    <!ENTITY % Inventory.prefixed "INCLUDE">
    <!ENTITY % Inventory.prefix "i">
]>
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:i="http://www.my.org/xmlns/inventory" >
<head>
<title>An example using prefixes</title>
</head>
<body>
<p>This is content in the XHTML namespace</p>
<i:shelf>
  <i:item>
    <i:desc>
      this is a description.
    </i:desc>
    <i:sku>
      this is the sku.
    </i:sku>
    <i:price>
      this is the price.
    </i:price>
  </i:item>
</i:shelf>
</body>
</html>

7.3. XHTML-Inventory with all prefixes

This example places a prefix on every element.

<!DOCTYPE x:html SYSTEM "xhtml-invext-1.dtd" [
    <!ENTITY % NS.prefixed "INCLUDE">
    <!ENTITY % XHTML.prefix "x" >
    <!ENTITY % Inventory.prefix "i">
]>
<x:html xmlns:x="http://www.w3.org/1999/xhtml"
        xmlns:i="http://www.my.org/xmlns/inventory" >
<x:head>
<x:title>An example using prefixes</x:title>
</x:head>
<x:body>
<x:p>This is content in the XHTML namespace</x:p>
<i:shelf>
  <i:item>
    <i:desc>
      this is a description.
    </i:desc>
    <i:sku>
      this is the sku.
    </i:sku>
    <i:price>
      this is the price.
    </i:price>
  </i:item>
</i:shelf>
</x:body>
</x:html>