Let’s leave our library for a while to look at XHTML. XHTML modularization breaks the monolithic XHTML 1.0 DTD into a set of independent modules described as in independent DTDs. Those modules can be combined to create as many flavors of XHTML as people may want. However, this has proven to be one of the most challenging exercises for schema languages. In their Working Drafts, the W3C HTML Working Group, the group in charge of XHTML, has published a set of RELAX NG schemas to describe XHTML 2.0. Its many interconnected modules illustrate the flexibility of RELAX NG to perform this type of exercises.
The solution chosen by XHTML 2.0 (see http://www.w3.org/TR/xhtml2/xhtml20_relax.html#a_xhtml20_relaxng for more detail) is to define each module in its own schema and then include all these modules in a top-level schema (called the RELAX NG XHTML 2.0 Driver). The driver schema looks like this:
<?xml version="1.0" encoding="UTF-8"?> <grammar ns="http://www.w3.org/2002/06/xhtml2" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:x="http://www.w3.org/1999/xhtml"> <x:h1>RELAX NG schema for XHTML 2.0</x:h1> <x:pre> Copyright ©2003 W3C® (MIT, ERCIM, Keio), All Rights Reserved. Editor: Masayasu Ishikawa <[email protected]> Revision: $Id: ch10.xml,v 1.7 2004/01/05 20:47:21 becki Exp $ Permission to use, copy, modify and distribute this RELAX NG schema for XHTML 2.0 and its accompanying documentation for any purpose and without fee is hereby granted in perpetuity, provided that the above copyright notice and this paragraph appear in all copies. The copyright holders make no representation about the suitability of this RELAX NG schema for any purpose. It is provided "as is" without expressed or implied warranty. For details, please refer to the W3C software license at: <x:a href="http://www.w3.org/Consortium/Legal/copyright-software"> http://www.w3.org/Consortium/Legal/copyright-software</x:a> </x:pre> <div> <x:h2>XHTML 2.0 modules</x:h2> <x:h3>Attribute Collections Module</x:h3> <include href="xhtml-attribs-2.rng"/> <x:h3>Structure Module</x:h3> <include href="xhtml-struct-2.rng"/> <x:h3>Block Text Module</x:h3> <include href="xhtml-blktext-2.rng"/> <x:h3>Inline Text Module</x:h3> <include href="xhtml-inltext-2.rng"/> <x:h3>Hypertext Module</x:h3> <include href="xhtml-hypertext-2.rng"/> <x:h3>List Module</x:h3> <include href="xhtml-list-2.rng"/> <x:h3>Linking Module</x:h3> <include href="xhtml-link-2.rng"/> <x:h3>Metainformation Module</x:h3> <include href="xhtml-meta-2.rng"/> <x:h3>Object Module</x:h3> <include href="xhtml-object-2.rng"/> <x:h3>Scripting Module</x:h3> <include href="xhtml-script-2.rng"/> <x:h3>Style Attribute Module</x:h3> <include href="xhtml-inlstyle-2.rng"/> <x:h3>Style Sheet Module</x:h3> <include href="xhtml-style-2.rng"/> <x:h3>Tables Module</x:h3> <include href="xhtml-table-2.rng"/> <x:h3>Support Modules</x:h3> <x:h4>Datatypes Module</x:h4> <include href="xhtml-datatypes-2.rng"/> <x:h4>Events Module</x:h4> <include href="xhtml-events-2.rng"/> <x:h4>Param Module</x:h4> <include href="xhtml-param-2.rng"/> <x:h4>Caption Module</x:h4> <include href="xhtml-caption-2.rng"/> </div> <div> <x:h2>XML Events module</x:h2> <include href="xml-events-1.rng"/> </div> <div> <x:h2>Ruby module</x:h2> <include href="full-ruby-1.rng"/> </div> <div> <x:h2>XForms module</x:h2> <x:p>To-Do: work out integration of XForms</x:p> <!--include href="xforms-1.rng"/--> </div> </grammar>
Don’t worry for the moment about the
ns
attribute (Chapter 11), nor
about the foreign (non-RELAX NG) namespaces and the
div
elements (Chapter 13). One
of these modules, the Structure Module, defines the basic structure
of a
XHTML 2.0 document. For instance, the
head
element is defined as:
<define name="head"> <element name="head"> <ref name="head.attlist"/> <ref name="head.content"/> </element> </define> <define name="head.attlist"> <ref name="Common.attrib"/> </define> <define name="head.content"> <ref name="title"/> </define>
or:
head = element head { head.attlist, head.content } head.attlist = Common.attrib head.content = title
This example shows another design decision. For each element, the
XHTML Working Group decided to define a
named pattern with the same name as the element
(head
) and two separated named patterns to define
the list of its attributes (head.attlist
) and its
content (head.content
). This design decision makes
it easy for other modules to add new elements and attributes just by
combining these named patterns by interleave. For instance, the
Metainformation Module adds a
meta
element to the content of the
head
element by combining via interleave the
head.content
pattern with zero or more
meta
elements:
<?xml version="1.0" encoding="UTF-8"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:x="http://www.w3.org/1999/xhtml"> <x:h1>Metainformation Module</x:h1> <div> <x:h2>The meta element</x:h2> <define name="meta"> <element name="meta"> <ref name="meta.attlist"/> <choice> <ref name="Inline.model"/> <oneOrMore> <ref name="meta"/> </oneOrMore> </choice> </element> </define> <define name="meta.attlist"> <ref name="Common.attrib"/> <optional> <attribute name="name"> <ref name="NMTOKEN.datatype"/> </attribute> </optional> </define> </div> <define name="head.content" combine="interleave"> <zeroOrMore> <ref name="meta"/> </zeroOrMore> </define> </grammar>
or:
namespace x = "http://www.w3.org/1999/xhtml" meta = element meta { meta.attlist, (Inline.model | meta+) } meta.attlist = Common.attrib, attribute name { NMTOKEN.datatype }? head.content &= meta*
The fact that the content models are combined by interleave
guarantees independence between modules: you can add or remove
modules independently of each other. It also guarantees the
independence of the resulting schema over the order in which the
different modules are included in the top-level schema; you can
switch the Metainformation Module and the
Scripting Module, which both add content
into the head
element, without any impact on the
set of valid documents.
This modularity fully relies on combinations by interleave and RELAX
NG would have no easy solution if you want to add content, for
instance, to what has already be defined in the
head
element. Of course, if
you’re interested only in the Structure Module and
want to add a foo
element after the
title
element, you can redefine
head.content
:
<include href="xhtml-struct-2.rng"> <define name="head.content"> <ref name="title"/> <element name="foo"> <empty/> </element> </define> </include>
However, this doesn’t take into account all the
content added by the other modules into the head
element.
3.143.25.144