Content Model issues in Modularization of XHTML PR

This comparison is against <http://www.w3.org/TR/2001/PR-xhtml-modularization-20010222>.

Best attempt with current DTD Module Implementations

The following table describes my best attempt at providing definitions for those entities in the DTD modules implementations, which are intended to be defined my a content module DTD.  It seems impossible to provide definitions which satisfy all the Abstract Modules.  The next section lists suggested redefinitions of parts of the DTD implementations, to make it possible to satisfy the Abstract Modules.  (The third column was compiled just to aid in cross-checking.)

Entity Definition Used By
Entities which maybe ought to be defined in the standard DTD module implementations
%Anchor.class; | %a.qname; %label.content;,
%pre.content;
%Table.class; | %table.qname; %BlkNoForm.mix;, in Forms but not in Basic Forms (probably should be in both)
Entities required to be defined by a content model DTD
%BlkPhras.class; | %address.qname; | %blockquote.qname; | %pre.qname; %Block.class;,
%BlkNoForm.mix;,
%BlkNoTable.class;
%BlkPres.class; | %hr.qname; %Block.class;,
%BlkNoForm.mix;,
%BlkNoTable.class;
%BlkStruct.class; %div.qname; | %p.qname; %Block.class;,
%BlkNoForm.mix;,
%BlkNoTable.class;
%Block.extra; [empty] %Block.class;,
%BlkNoForm.mix;,
%BlkNoTable.class;
%Block.mix; %Heading.class; | %List.class; | %Block.class; %Misc.class; Many content models, for "Heading | Block | List" and "PCDATA | Heading | Block | List" and "Heading | Block".  Unsurprisingly, this doesn't work, and there's no definition of %Block.mix; which will make it work.
%Flow.mix; %Heading.class; | %List.class; | %Block.class; | %Inline.class; %Misc.class; Many content models, for "Flow"
%FlowNoTable.mix; %Heading.class; | %List.class; | %BlkNoTable.class; | %Inline.class; %Misc.class; %label.content; and %button.content; in Basic Tables, for "Flow - table"
%HeadOpts.mix; ( %object.qname; | %meta.qname; | %script.qname; | %style.qname; | %link.qname; | %base.qname; )* %head.content;, for "elements added to the content model of 'head'"
%I18n.class; | %bdo.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content;,
%button.content;,
%pre.content;
%InlNoAnchor.mix; %InlNoAnchor.class; %Misc.class; %a.content;, for "Inline - a"
%InlPhras.class; | %abbr.qname; | %acronym.qname; | %cite.qname; | %code.qname; | %dfn.qname; | %em.qname; | %kbd.qname; | %q.qname; | %samp.qname; | %strong.qname; | %var.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content;,
%button.content;,
%pre.content;
%InlPres.class; | %b.qname; | %big.qname; | %i.qname; | %small.qname; | %sub.qname; | %sup.qname; | %tt.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content;,
%button.content;
%InlSpecial.class; | %applet.qname; | %del.qname; | %iframe.qname; | %img.qname; | %ins.qname; | %map.qname; | %object.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content;,
%button.content;
%InlStruct.class; %br.qname; | %span.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content;,
%button.content;,
%pre.content;
%Inline.extra; | %input.qname; | %select.qname; | %textarea.qname; | %label.qname; | %button.qname; %InlNoAnchor.class;,
%Inline.class;,
%label.content; (not in Basic Forms),
%button.content;,
%pre.content;
%Inline.mix; %Inline.class; %Misc.class; Many content models, for "Inline"
%List.class; %ul.qname; | %ol.qname; | %dl.qname; %BlkNoForm.mix;, for "List"
%Misc.class; | %script.qname; | %noscript.qname; %BlkNoForm.mix;,
%label.content;
Entities used only in constructing definitions for the above
%InlNoAnchor.class; %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %InlSpecial.class; %Inline.extra; %InlNoAnchor.mix;
%BlkSpecial.class; | %table.qname; | %form.qname; | %fieldset.qname; %Block.class;
%Block.class; %BlkStruct.class; %BlkPhras.class; %BlkPres.class; %BlkSpecial.class; %Block.extra; %Block.mix;,
%Flow.mix;
%Heading.class; %h1.qname; | %h2.qname; | %h3.qname; | %h4.qname; | %h5.qname; | %h6.qname; %Block.mix;,
%Flow.mix;,
%FlowNoTable.mix;
%Inline.class; %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %Anchor.class; %InlSpecial.class; %Inline.extra; %Flow.mix;,
%FlowNoTable.mix;,
%Inline.mix;
%BlkSpecialNoTable.class; | %form.qname; | %fieldset.qname; %BlkNoTable.class
%BlkNoTable.class; %BlkStruct.class; %BlkPhras.class; %BlkPres.class; %BlkSpecialNoTable.class; %Block.extra; %FlowNoTable.mix;

Alternative definitions

These alternative definitions of some of the above entities are provided to make it possible to provide correct DTD Implementations of some of the "%*.content;" entities, also redefined here.  (The third column was compiled just to aid in cross-checking.)

Entity Definition Used By
Entities required to be defined by a content model DTD
%Block.extra; [empty] %Block.class;,
%BlkNoForm.mix;,
%BlkNoTable.mix;
%InlPres.class; %InlPresSameSize.class; %InlPresDiffSize.class; %label.content;,
%button.content;
%InlSpecial.class; %Formctrl.class;
%InlSpecialReplaced.class; %InlSpecialNonReplaced.class;
%Inline.class;
%Inline.extra; [empty] %Inline.class;,
%label.content; (not Basic Forms?),
%button.content;
Entities used only in constructing definitions for the above
%InlPresSameSize.class; | %tt.qname; | %i.qname; | %b.qname; %InlPres.class;,
%pre.content;
%InlPresDiffSize.class; | %big.qname; | %small.qname; | %sub.qname; | %sup.qname; %InlPres.class;
%Formctrl.class; [Basic Forms] | %input.qname; | %select.qname; | %textarea.qname; | %label.qname; %InlSpecial.class;
%Formctrl.class; [Forms] | %input.qname; | %select.qname; | %textarea.qname; | %label.qname; | %button.qname; %InlSpecial.class;
%InlSpecialReplaced.class; | %applet.qname; | %img.qname; | %object.qname;  %InlSpecial.class;
%InlSpecialNonReplaced.class; | %del.qname; | %iframe.qname; | %ins.qname; | %map.qname; %InlSpecial.class;,
%pre.content;
%Inline.class; %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %Anchor.class; %InlSpecial.class; %Inline.extra; %Flow.mix;,
%FlowNoTable.mix;,
%Inline.mix; (as before)
%InlNoFormctrl.class; %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %Anchor.class; %InlSpecialReplaced.class; %InlineSpecialNonReplaced.class; %Inline.extra; %label.content;,
%button.content;
Entities defined in the XHTML DTD Module Implementations 
%label.content; [Basic Forms] ( #PCDATA %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %Anchor.class; | %input.qname; | %select.qname; | %textarea.qname; %InlSpecialReplaced.class; %InlSpecialNonReplaced.class; %Inline.extra; )* -
%label.content; [Forms] ( #PCDATA %InlStruct.class; %InlPhras.class; %InlPres.class; %I18n.class; %Anchor.class; | %input.qname; | %select.qname; | %textarea.qname; | %button.qname; %InlSpecialReplaced.class; %InlSpecialNonReplaced.class; %Inline.extra; )* -
%button.content; ( #PCDATA %BlkNoForm.mix; %InlNoFormctrl.class; )* -
%pre.content; ( #PCDATA %InlStruct.class; %InlPhras.class; %I18n.class; %Anchor.class; %InlPresSameSize.class; %InlSpecialNonReplaced.class; %Inline.extra; %Misc.class; )* -

Matching of abstract and implementation content models

This table lists whether or not each element's abstract content model is matched with its DTD Implementation, along with some other notes on oddities I discovered while checking this.

Element Content Model in Abstract Modules Content Model in Module Implementations Match?
Structure
body (Heading | Block | List)* ( %Block.mix; )+ N ["*" in abstract (which matches Strict and Transitional DTDs for XHTML 1.0, and the Transitional DTD for HTML 4.,01) but "+" in implementation (which matches the Strict DTD for HTML 4.01, if I'm interpreting the SGML element delcaration correctly).  Also, Block.mix cannot be defined to satisfy both this and "blockquote", "map": blockquote's content model includes PCDATA and map's excludes List]
head title "plus" meta, script, style, link and base [the abstract module descriptions don't describe the number of times these latter elements can occur, or their allowable positions with respect to each other and "title"] ( %HeadOpts.mix;, %title.qname;, %HeadOpts.mix; ) y [assuming the elements other than "title" are allowed to occur any number of times, in any order, which matches HTML 4.01]
html head, body [or (head, frameset) if frames are used] ( %head.qname;, %body.qname; ) [or ( %head.qname;, %frameset.qname; ) if frames are used] y
title PCDATA ( #PCDATA ) y
Text
abbr (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
acronym (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
address (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
blockquote (PCDATA | Heading | Block | List)* ( %Block.mix; )+ N ["*" in abstract (which matches Strict and Transitional DTDs for XHTML 1.0, and the Transitional DTD for HTML 4.,01) but "+" in implementation (which matches the Strict DTD for HTML 4.01, if I'm interpreting the SGML element delcaration correctly).  Also, Block.mix cannot be defined to satisfy both this and "body", "map", "noscript": all of their content models exclude PCDATA and map's excludes List]
br EMPTY EMPTY y
cite (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
code (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
dfn (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
div (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
em (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h1 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h2 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h3 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h4 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h5 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
h6 (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
kbd (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
p (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
pre (PCDATA | Inline)*

[Shouldn't this be

"(PCDATA | Inline - ( img | object | big | small | sub | sup ))*"

to match HTML 4.01 and XHTML 1.0 Strict or

"(PCDATA | Inline - ( img | object | applet | big | small | sub | sup | font | basefont ))*"

to match XHTML 1.0 Transitional (or is that difference an error in HTML 4.01 or XHTML 1.0?)?]
( #PCDATA
| %InlStruct.class;
%InlPhras.class;
| %tt.qname; | %i.qname; | %b.qname;
%I18n.class;
%Anchor.class;
| %script.qname; | %map.qname;
%Inline.extra; )*
N [Omits big, small, sub, sup, applet, del, ins, "Formctrl", img, object, noscript (unless some/all of those appear in "%Inline.extra;").  I suggest an alternative abstract definition to the left and a possible corresponding implementation in the preceding table.]
q (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
samp (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
span (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
strong (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
var (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
Hypertext
a (PCDATA | Inline - a)* ( #PCDATA | %InlNoAnchor.mix; )* y
List
dl (dt | dd)+ ( %dt.qname; | %dd.qname; )+ y
dt (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
dd (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
ol li+ ( %li.qname; )+ y
ul li+ ( %li.qname; )+ y
li (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
Applet
applet (PCDATA | Flow | param)* ( %param.qname; | %Flow.mix; | PCDATA )* y
param EMPTY EMPTY y
Presentation
b (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
big (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
hr EMPTY EMPTY y
i (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
small (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
sub (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
sup (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
tt (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
Edit
del (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
ins (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
Bi-Directional Text
bdo (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
Basic Forms
form (Heading | List | Block - form)+ ( %BlkNoForm.mix; )+
input EMPTY EMPTY y
select option+ ( %option.qname; )+ y
option PCDATA ( #PCDATA ) y
textarea PCDATA ( #PCDATA ) y
label (PCDATA | Inline - label)* ( #PCDATA
| %input.qname; | %select.qname; | %textarea.qname;
| %InlStruct.class;
%InlPhras.class;
%I18n.class;
%InlPres.class;
%InlSpecial.class;
%Misc.class; )*
??? ["y" if (a) InlSpecial.class and Misc.class are defined as above; and (b) %Anchor.class; is added to the implementation.  See alternative definition in preceding table.]
Forms
form (Heading | List | Block - form | fieldset)+ [fieldset seems superfluous here, as it's already part of Block] ( %BlkNoForm.mix; | %fieldset.qname; )+
input EMPTY EMPTY y
select (optgroup | option)+ ( %optgroup.qname; | %option.qname; )+ y
option PCDATA ( #PCDATA ) y
textarea PCDATA ( #PCDATA ) y
button (PCDATA | Heading | List | Block - form | Inline - Formctrl)* ( #PCDATA
| %BlkNoForm.mix;
| %InlStruct.class;
%InlPhras.class;
%InlPres.class;
%I18n.class;
%InlSpecial.class;
%Inline.extra; )*
??? [N, if (a) InlSpecial.class and Misc.class are defined as above; and (b) %Anchor.class; is added to the implementation; because there's still the problem that the "- Formctrl" isn't implemented correctly, because %Inline.extra; is Formctrl .  See the preceding table for an alternative implementation.]
fieldset (PCDATA | legend | Flow)* ( #PCDATA | %legend.qname; | %Flow.mix; )* y
label (PCDATA | Inline - label)* ( #PCDATA
| %input.qname; | %select.qname; | %textarea.qname; | %button.qname;
| %InlStruct.class;
%InlPhras.class;
%I18n.class;
%InlPres.class;
%Anchor.class;
%InlSpecial.class;
%Inline.extra;
%Misc.class; )*
y [Note that %Anchor.class; is already in the implementation, unlike "%button.content;" here or "%label.content;" in full Forms.  See also an alternative definition in preceding table, which makes it easier to provide a correct definition for %pre.content;.]
legend (PCDATA | Inline)+ ( #PCDATA | %Inline.mix; )* y
optgroup option+ ( %option.qname; )+ y
Basic Tables
caption (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
table caption?, tr+ ( %caption.qname;?, %tr.qname;+ ) y
td (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
th (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
tr (td | th)+ ( %th.qname; | %td.qname; )+ y
Tables
caption (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
table caption?, ( col* | colgroup* ), (( thead?, tfoot?, tbody+ ) | ( tr+ )) ( %caption.qname;?, ( %col.qname;* | %colgroup.qname;* ),
(( %thead.qname;?, %tfoot.qname;?, %tbody.qname;+ ) | ( %tr.qname;+ )))
y
td (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
th (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
tr (td | th)+ ( %th.qname; | %td.qname; )+ y
col EMPTY EMPTY y
colgroup col* ( %col.qname; )* y
tbody tr+ ( %tr.qname; )+ y
thead tr+ ( %tr.qname; )+ y
tfoot tr+ ( %tr.qname; )+ y
Image
img EMPTY EMPTY y
Client-side Image Map
area EMPTY EMPTY y
map ((Heading | Block) | area)+ [Why isn't this just "(Heading | Block | area)+"?] (( %Block.mix; ) | %area.qname; )+ N [Block.mix cannot be defined to satisfy both this and "body", "blockquote", "noscript".  I think the abstract module should add "List" to the content model of map, which would match HTML 4.01 (Strict and Transitional) and remove the clashes.  However, XHTML 1.0 (Strict and Transitional) uses "((%block; | form | %misc;)+ | area+)", which implies that "area" elements can't be mixed with block-level content; is this an erratum in XHTML 1.0?]
Server-side Image Map
n/a      
Object
object (PCDATA | Flow | param)* ( #PCDATA | %Flow.mix; | %param.qname; )* y
param EMPTY EMPTY y
Frames
frameset (frameset | frame)+, noframes? (( %frameset.qname; | %frame.qname; )+, %noframes.qname;? ) y
frame EMPTY EMPTY y
noframes body ( %body.qname; ) y
Target
n/a      
Iframe
iframe (PCDATA | Flow)* ( PCDATA | %Flow.mix; )* y
Intrinsic Events
n/a      
Metainformation
meta EMPTY EMPTY y
Scripting
noscript (Heading | List | Block)+ ( %Block.mix; )+ N [Block.mix cannot be defined to satisfy both this and "blockquote", "map": blockquote's content model includes PCDATA and map's excludes List.  Note also that "+" is used in the abstract and implementation, which matches the Strict DTD for HTML 4.01 (if I'm interpreting the SGML element delcaration correctly) but not the Strict and Transitional DTDs for XHTML 1.0 and the Transitional DTD for HTML 4.01, which use "*".]
script PCDATA ( #PCDATA ) y
Stylesheet
style PCDATA ( #PCDATA ) y
Style Attribute
n/a      
Link
link EMPTY EMPTY y
Base
base EMPTY EMPTY y
Name Identification
n/a      
Legacy
basefont EMPTY EMPTY y
center (PCDATA | Flow)* ( #PCDATA | %Flow.mix; )* y
dir (li)+ ( %li.qname; )+ y
font (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
isindex EMPTY EMPTY y
menu (li)+ ( %li.qname; )+ y
s (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
strike (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y
u (PCDATA | Inline)* ( #PCDATA | %Inline.mix; )* y