This is the (more) formal spec as parts of a Relax-NG schema.
<!-- = Document Structure -->
<!-- == Document Root -->
<start>
<element name="page:page">
<zeroOrMore>
<ref name="page-h"/>
<ref name="page-p"/>
<ref name="page-list"/>
<ref name="page-table"/>
</zeroOrMore>
</element>
</start>
<!-- = Text Content -->
<!-- == Headings -->
<define name="page-h">
<element name="page:h">
<ref name="heading-attrs"/>
<ref name="paragraph-attrs"/>
<zeroOrMore>
<ref name="paragraph-content"/>
</zeroOrMore>
</element>
</define>
<!-- === Heading level -->
<define name="heading-attrs" combine="interleave">
<attribute name="page:outline-level">
<ref name="positiveInteger"/>
</attribute>
</define>
<!-- == Paragraphs -->
<define name="page-p">
<element name="page:p">
<ref name="paragraph-attrs"/>
<zeroOrMore>
<ref name="paragraph-content"/>
</zeroOrMore>
</element>
</define>
<!-- = Paragraph Elements Content -->
<!-- == Basic Text Content -->
<!-- === Line Breaks -->
<define name="paragraph-content" combine="choice">
<element name="page:line-break">
<empty/>
</element>
</define>
<!-- === Attributed Text -->
<define name="paragraph-content" combine="choice">
<element name="page:span">
<zeroOrMore>
<ref name="paragraph-content"/>
</zeroOrMore>
</element>
</define>
<!-- === Hyperlinks -->
<define name="paragraph-content" combine="choice">
<element name="page:a">
<ref name="page-a-attlist"/>
<zeroOrMore>
<ref name="paragraph-content"/>
</zeroOrMore>
</element>
</define>
<!-- ==== Link Location -->
<define name="page-a-attlist" combine="interleave">
<attribute name="xlink:href">
<ref name="anyIRI"/>
</attribute>
</define>
<!-- == Notes -->
<define name="paragraph-content" combine="choice">
<element name="page:note">
<ref name="text-note-class"/>
<element name="page:note-body">
<zeroOrMore>
<ref name="content"/>
</zeroOrMore>
</element>
</element>
</define>
<!-- === Note Class -->
<define name="page-note-class">
<attribute name="page:note-class">
<choice>
<value>footnote</value>
<value>endnote</value>
</choice>
</attribute>
</define>
<!-- == Lists -->
<define name="page-list">
<element name="page:list>
<zeroOrMore>
<element name="page:list-item>
<element name="page:list-item-label>
</element>
<element name="page:list-item-body>
</element>
</element>
</zeroOrMore>
</element>
</define>
<!-- = Tables -->
<define name="page-table">
<element name="page:table">
<zeroOrMore>
<ref name="page-table-row"/>
</zeroOrMore>
</element>
</define>
<!-- == Table header -->
<define name="page-table-header">
<element name="page:table-header">
<optional>
<ref name="page-table-header"/>
</optional>
<optional>
<ref name="page-table-footer"/>
</optional>
<ref name="page-table-body"/>
</element>
</define>
<!-- == Table footer -->
<define name="page-table-footer">
<element name="page:table-footer">
<zeroOrMore>
<ref name="page-table-row"/>
</zeroOrMore>
</element>
</define>
<!-- == Table body -->
<define name="page-table-body">
<element name="page:table-body">
<zeroOrMore>
<ref name="page-table-row"/>
</zeroOrMore>
</element>
</define>
<!-- == Table row -->
<define name="page-table-row">
<element name="page:table-row>
<oneOrMore>
<ref name="page-table-cell"/>
</oneOrMore>
</element>
</define>
<!-- == Table cell -->
<define name="page-table-cell">
<element name="page:table-cell>
<zeroOrMore>
<ref name="text-content"/>
</zeroOrMore>
</element>
</define>