SGML

Model Group Exception Examples

exceptions/test1.sgm
basic inclusion example
exceptions/test2.sgm
basic rejected exclusion example
exceptions/test3.sgm
basic accepted exclusion example
exceptions/test4.sgm
example where a required element is excluded; SP will say "document type doesn't allow element a here"
exceptions/test5.sgm
example where an element is both excluded and included at the same level; SP will say "element c is both excluded and included"
exceptions/test6.sgm
rejected example with multiple in-/exclusions
exceptions/test7.sgm
accepted example with multiple in-/exclusions
exceptions/test8.sgm
example demonstrating that exclusions can't be overridden at lower levels
exceptions/test9.sgm
example demonstrating cascaded inclusion
exceptions/test10.sgm
rejected example demonstrating included elements excluded at a lower level
exceptions/test11.sgm exceptions/test11a.sgm exceptions/test11b.sgm exceptions/test11c.sgm

demonstrates that an included element can trigger omitted start-tag inference like a proper modelgroup element (test11a.sgm uses a proper subelement while test11.sgm uses an included element to open an omitted b start-element tag). However, it can be argued that SP's behaviour to close b upon seeing c is speculative, since b is not finished; it would require a full scan of any allowed child elements of b to conclude that b should be closed here, and this, in turn, would open another discussion as to what criterion to use here (checking c against the set of all child elements, or checking c against b's content model or included elements, etc.). file:test11b.sgm demonstrates that by changing b's content model to #PCDATA, and inserting a single blank so that #PCDATA is satisfied and b's model is seen as "begun", this makes test11b.sgm accepted by current impl; this is inconsequential, so have to remove condition on close-phase such that it is also executed on modelgroups in initial state (test11c.sgm)

exceptions/test12.sgm
demonstrates that, like with proper content model elements, an omitted end tag is inferred before an included subelement
exceptions/test13.sgm
is rejected and demonstrates that included elements can't be omitted in the same way as proper declared elements (ie. element y doesn't trigger inference of x) so we only look after directly included elements, rather than elements that might be transitively included from those when checking exceptions
exceptions/test14.sgm exceptions/test14a.sgm
demonstrates "typical" use of included subelement in #PCDATA; test13a.sgm is accepted while test13.sgm is not, because of a footnote where it isn't allowed

SP apparently accepts the SEQ connector in place of the OR connector (pipe); SGML syntax allows all connectors, though only the OR connector has a defined meaning.

exceptions/test1.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b) +(c)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
]>
<test><a></a><c></c><b></b></test>

exceptions/test2.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b?, c) -(b)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
]>
<test><a></a><b></b><c></c></test>

exceptions/test3.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b?, c) -(b)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
]>
<test><a></a><c></c></test>

exceptions/test4.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b) -(a)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
]>
<test><a></a><b></b></test>

exceptions/test5.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b) -(c) +(c)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
]>
<test><a></a><c></c><b></b></test>

exceptions/test6.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b*, c?) -(b|c) +(d|e)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
]>
<test><a></a><c></c></test>

exceptions/test7.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b*, c?) -(b|c) +(d|e)>
	<!ELEMENT a - - (#PCDATA)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
]>
<test><a></a><e></e></test>

exceptions/test8.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b*, c?) -(b|c) +(d|e)>
	<!ELEMENT a - - (b|c|#PCDATA) +(c)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
]>
<test><a><c></c></a><e></e></test>

exceptions/test9.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b*, c?) -(b) +(d|e)>
	<!ELEMENT a - - (b|c|#PCDATA) +(f)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
]>
<test><a><c></c><d></d></a><e></e></test>

exceptions/test10.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b*, c?) +(d|e)>
	<!ELEMENT a - - (b|c|#PCDATA) -(d)>
	<!ELEMENT b - - (#PCDATA)>
	<!ELEMENT c - - (#PCDATA)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
]>
<test><a><c></c><d></d></a><e></e></test>

exceptions/test11.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - - (d)>
	<!ELEMENT b O O (e*) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x - - (#PCDATA)>
]>
<test><a><d></d></a><x></x><c><f></f></c></test>

exceptions/test11a.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - - (d)>
	<!ELEMENT b O O (e) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x - - (#PCDATA)>
]>
<test><a><d></d></a><e></e><c><f></f></c></test>

exceptions/test11b.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - - (d)>
	<!ELEMENT b O O (#PCDATA) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x - - (#PCDATA)>
]>
<test><a><d></d></a><x></x> <c><f></f></c></test>

exceptions/test11c.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - - (d)>
	<!ELEMENT b O O (#PCDATA) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x - - (#PCDATA)>
]>
<test><a><d></d></a><x></x><c><f></f></c></test>

exceptions/test12.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - O (d)>
	<!ELEMENT b O O (e*) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x - - (#PCDATA)>
]>
<test><a><d></d><x></x><c><f></f></c></test>

exceptions/test13.sgm

<!DOCTYPE test [
	<!ELEMENT test - - (a, b, c)>
	<!ELEMENT a - - (d)>
	<!ELEMENT b O O (e*) +(x)>
	<!ELEMENT c - - (f)>
	<!ELEMENT d - - (#PCDATA)>
	<!ELEMENT e - - (#PCDATA)>
	<!ELEMENT f - - (#PCDATA)>
	<!ELEMENT x O O (y)>
	<!ELEMENT y - - (#PCDATA)>
]>
<test><a><d></d></a><y></y><c><f></f></c></test>

exceptions/test14.sgm

<!DOCTYPE doc [
	<!ELEMENT doc - - (head, chapter+) +(footnote)>
	<!ELEMENT head O O (title) -(footnote)>
	<!ELEMENT title - - (#PCDATA)>
	<!ELEMENT chapter - - (#PCDATA)>
	<!ELEMENT footnote - - (#PCDATA) -(footnote)>
]>
<doc><title>Header Title</title><chapter>Chapter <footnote>Footnote<footnote>Invalid Nested Footnote Text</footnote> Text</footnote>Text</chapter></doc>

exceptions/test14a.sgm

<!DOCTYPE doc [
	<!ELEMENT doc - - (head, chapter+) +(footnote)>
	<!ELEMENT head O O (title) -(footnote)>
	<!ELEMENT title - - (#PCDATA)>
	<!ELEMENT chapter - - (#PCDATA)>
	<!ELEMENT footnote - - (#PCDATA) -(footnote)>
]>
<doc><title>Header Title</title><chapter>Chapter <footnote>Footnote Text</footnote>Text</chapter></doc>

SP apparently accepts the SEQ connector in place of the OR connector (pipe); SGML syntax allows all connectors, though only the OR connector has a defined meaning.