<?xml version="1.0" encoding="UTF-8"?>

<xs:schema
  targetNamespace="https://www.doclang.ai/ns/v0"
  xmlns:dl="https://www.doclang.ai/ns/v0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified"
  version="0.7.1"
>

  <!-- ============================================ -->
  <!-- CONTENT ELEMENT: String content with xml:space="preserve" for whitespace preservation -->
  <!-- ============================================ -->

  <xs:element name="content" xml:space="preserve" type="xs:string"/>

  <!-- ============================================ -->
  <!-- CONTENT_CAT: Raw text or CDATA, optionally wrapped in <content> -->
  <!-- ============================================ -->

  <xs:complexType name="content_cat" mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="dl:content"/>
    </xs:choice>
  </xs:complexType>

  <!-- ============================================ -->
  <!-- FORMATTING: bold, italic, strikethrough, superscript, subscript, rtl, handwriting (nestable) -->
  <!-- ============================================ -->

  <!-- ============================================ -->
  <!-- FORMATTING_GROUP: Reusable group for formatting elements -->
  <!-- Includes: bold, italic, strikethrough, underline, superscript, subscript, rtl, handwriting -->
  <!-- ============================================ -->

  <xs:group name="formatting_group">
    <xs:choice>
      <xs:element name="bold" type="dl:formatting_cat"/>
      <xs:element name="italic" type="dl:formatting_cat"/>
      <xs:element name="strikethrough" type="dl:formatting_cat"/>
      <xs:element name="underline" type="dl:formatting_cat"/>
      <xs:element name="superscript" type="dl:formatting_cat"/>
      <xs:element name="subscript" type="dl:formatting_cat"/>
      <xs:element name="rtl" type="dl:formatting_cat"/>
      <xs:element name="handwriting" type="dl:formatting_cat"/>
    </xs:choice>
  </xs:group>

  <xs:complexType name="formatting_cat" mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="dl:content"/>
      <xs:group ref="dl:formatting_group"/>
    </xs:choice>
  </xs:complexType>

  <!-- ============================================ -->
  <!-- MARKER ELEMENT: optional element_head + formatting or checkbox -->
  <!-- ============================================ -->

  <xs:element name="marker">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="dl:content"/>
          <xs:group ref="dl:formatting_group"/>
          <xs:element ref="dl:checkbox"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- HINT ELEMENT: contains an instance of formatting -->
  <!-- ============================================ -->

  <xs:element name="hint" type="dl:formatting_cat"/>

  <!-- ============================================ -->
  <!-- CHECKBOX ELEMENT: empty element with optional class attribute -->
  <!-- ============================================ -->

  <xs:element name="checkbox">
    <xs:complexType>
      <xs:attribute name="class" default="unselected">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="unselected"/>
            <xs:enumeration value="selected"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- PAGE_BREAK ELEMENT: empty element (page break marker) -->
  <!-- ============================================ -->

  <xs:element name="page_break">
    <xs:complexType/>
  </xs:element>

  <!-- ============================================ -->
  <!-- DEFAULT_RESOLUTION ELEMENT: document-level default width/height -->
  <!-- ============================================ -->

  <xs:element name="default_resolution">
    <xs:complexType>
      <xs:attribute name="width" type="xs:nonNegativeInteger" default="512"/>
      <xs:attribute name="height" type="xs:nonNegativeInteger" default="512"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- LOCATION ELEMENT: empty element with value and optional resolution attributes -->
  <!-- ============================================ -->

  <xs:element name="location">
    <xs:complexType>
      <xs:attribute name="value" type="xs:nonNegativeInteger" use="required"/>
      <xs:attribute name="resolution" type="xs:positiveInteger" use="optional"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- LOCATION_BLOCK: exactly 4 location elements -->
  <!-- ============================================ -->

  <xs:group name="location_block">
    <xs:sequence>
      <xs:element ref="dl:location" minOccurs="4" maxOccurs="4"/>
    </xs:sequence>
  </xs:group>

  <!-- ============================================ -->
  <!-- META ELEMENT: TODO: specify content (currently arbitrary) -->
  <!-- ============================================ -->

  <xs:element name="meta">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- CUSTOM ELEMENT: arbitrary metadata as elements only (no raw text) -->
  <!-- ============================================ -->

  <xs:element name="custom">
    <xs:complexType>
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- LABEL ELEMENT: empty element with optional value (property element / element head) -->
  <!-- ============================================ -->

  <xs:element name="label">
    <xs:complexType>
      <xs:attribute name="value" type="xs:string" default="undefined"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- THREAD ELEMENT: empty element with required thread_id (property element / element head) -->
  <!-- ============================================ -->

  <xs:element name="thread">
    <xs:complexType>
      <xs:attribute name="thread_id" type="xs:positiveInteger" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- XREF ELEMENT: empty element with required thread_id (property element / element head) -->
  <!-- Mutually exclusive with href (enforced by element_head choice) -->
  <!-- ============================================ -->

  <xs:element name="xref">
    <xs:complexType>
      <xs:attribute name="thread_id" type="xs:positiveInteger" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- HREF ELEMENT: empty element with required uri (property element / element head) -->
  <!-- Mutually exclusive with xref (enforced by element_head choice) -->
  <!-- ============================================ -->

  <xs:element name="href">
    <xs:complexType>
      <xs:attribute name="uri" type="xs:anyURI" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- LAYER ELEMENT: empty element with optional value (property element / element head) -->
  <!-- ============================================ -->

  <xs:element name="layer">
    <xs:complexType>
      <xs:attribute name="value" default="body">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="body"/>
            <xs:enumeration value="background"/>
            <xs:enumeration value="furniture"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- ELEMENT HEAD (element_head): optional label, thread, xref or href, layer, location_block, caption, description, summary, custom -->
  <!-- ============================================ -->

  <xs:group name="element_head">
    <xs:sequence>
      <xs:element ref="dl:label" minOccurs="0"/>
      <xs:element ref="dl:thread" minOccurs="0"/>
      <xs:choice minOccurs="0">
        <xs:element ref="dl:xref"/>
        <xs:element ref="dl:href"/>
      </xs:choice>
      <xs:element ref="dl:layer" minOccurs="0"/>
      <xs:group ref="dl:location_block" minOccurs="0"/>
      <xs:element ref="dl:caption" minOccurs="0"/>
      <xs:element ref="dl:description" minOccurs="0"/>
      <xs:element ref="dl:summary" minOccurs="0"/>
      <xs:element ref="dl:custom" minOccurs="0"/>
    </xs:sequence>
  </xs:group>

  <!-- ============================================ -->
  <!-- SRC ELEMENT: image source (child of picture) -->
  <!-- ============================================ -->

  <xs:element name="src">
    <xs:complexType>
      <xs:attribute name="uri" type="xs:anyURI" use="required"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- PICTURE ELEMENT: element_head + src + tabular (chart) + semantic body -->
  <!-- ============================================ -->

  <xs:complexType name="picture_type" mixed="true">
    <xs:sequence>
      <xs:group ref="dl:element_head"/>
      <xs:element ref="dl:src" minOccurs="0"/>
      <xs:element ref="dl:tabular" minOccurs="0"/>
      <xs:group ref="dl:virtual_text_content" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="class" use="optional" default="undefined">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="undefined"/>
          <xs:enumeration value="chart"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:element name="picture" type="dl:picture_type"/>

  <!-- ============================================ -->
  <!-- TABLE_SEP: empty elements for table separators -->
  <!-- ============================================ -->

  <xs:element name="fcel"><xs:complexType/></xs:element>
  <xs:element name="ecel"><xs:complexType/></xs:element>
  <xs:element name="ched"><xs:complexType/></xs:element>
  <xs:element name="rhed"><xs:complexType/></xs:element>
  <xs:element name="corn"><xs:complexType/></xs:element>
  <xs:element name="srow"><xs:complexType/></xs:element>
  <xs:element name="lcel"><xs:complexType/></xs:element>
  <xs:element name="ucel"><xs:complexType/></xs:element>
  <xs:element name="xcel"><xs:complexType/></xs:element>
  <xs:element name="nl"><xs:complexType/></xs:element>

  <xs:group name="table_sep">
    <xs:choice>
      <xs:element ref="dl:fcel"/>
      <xs:element ref="dl:ecel"/>
      <xs:element ref="dl:ched"/>
      <xs:element ref="dl:rhed"/>
      <xs:element ref="dl:corn"/>
      <xs:element ref="dl:srow"/>
      <xs:element ref="dl:lcel"/>
      <xs:element ref="dl:ucel"/>
      <xs:element ref="dl:xcel"/>
      <xs:element ref="dl:nl"/>
    </xs:choice>
  </xs:group>

  <!-- ============================================ -->
  <!-- HEADLESS_TXT: formatting, marker, hint, checkbox (no picture) -->
  <!-- Reuses formatting_group -->
  <!-- ============================================ -->

  <xs:group name="headless_txt">
    <xs:choice>
      <xs:group ref="dl:formatting_group"/>
      <xs:element ref="dl:marker"/>
      <xs:element ref="dl:hint"/>
      <xs:element ref="dl:checkbox"/>
    </xs:choice>
  </xs:group>

  <!-- ============================================ -->
  <!-- HEADLESS: headless_txt or picture -->
  <!-- ============================================ -->

  <xs:group name="headless">
    <xs:choice>
      <xs:group ref="dl:headless_txt"/>
      <xs:element ref="dl:code"/>
      <xs:element ref="dl:formula"/>
      <xs:element ref="dl:picture"/>
      <xs:element ref="dl:field_region"/>
      <xs:element ref="dl:field_heading"/>
      <xs:element ref="dl:field_item"/>
      <xs:element ref="dl:key"/>
      <xs:element ref="dl:value"/>
    </xs:choice>
  </xs:group>

  <!-- ============================================ -->
  <!-- HEADLESS_SEQ: sequence of headless instances (includes picture) -->
  <!-- Reuses headless group -->
  <!-- ============================================ -->

  <xs:complexType name="headless_seq" mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="dl:content"/>
      <xs:group ref="dl:headless"/>
    </xs:choice>
  </xs:complexType>

  <!-- ============================================ -->
  <!-- COMPONENT_WITH_HEADLESS_SEQ: Reusable base type for elements with element_head + headless_seq -->
  <!-- Reuses headless group -->
  <!-- ============================================ -->

  <xs:complexType name="component_with_headless_seq" mixed="true">
    <xs:sequence>
      <xs:group ref="dl:element_head"/>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="dl:content"/>
        <xs:group ref="dl:headless"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

  <!-- ============================================ -->
  <!-- TEXT ELEMENT: uses component_with_headless_seq -->
  <!-- ============================================ -->

  <xs:element name="text" type="dl:component_with_semantic_seq"/>

  <!-- ============================================ -->
  <!-- HEADING ELEMENT: extends component_with_headless_seq with level attribute -->
  <!-- ============================================ -->

  <xs:complexType name="heading_type">
    <xs:complexContent>
      <xs:extension base="dl:component_with_semantic_seq">
        <xs:attribute name="level" type="xs:positiveInteger" default="1"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:element name="heading" type="dl:heading_type"/>

  <!-- ============================================ -->
  <!-- CODE ELEMENT: uses component_with_headless_seq (language via label in element head) -->
  <!-- ============================================ -->

  <xs:element name="code" type="dl:component_with_headless_seq"/>

  <!-- ============================================ -->
  <!-- FORMULA ELEMENT: uses component_with_headless_seq -->
  <!-- ============================================ -->

  <xs:element name="formula" type="dl:component_with_headless_seq"/>

  <!-- ============================================ -->
  <!-- CAPTION ELEMENT: uses component_with_semantic_seq -->
  <!-- ============================================ -->

  <xs:element name="caption" type="dl:component_with_semantic_seq"/>

  <!-- ============================================ -->
  <!-- DESCRIPTION ELEMENT: raw text only (optionally wrapped in content) -->
  <!-- ============================================ -->

  <xs:element name="description" type="dl:content_cat"/>

  <!-- ============================================ -->
  <!-- SUMMARY ELEMENT: raw text only (optionally wrapped in content) -->
  <!-- ============================================ -->

  <xs:element name="summary" type="dl:content_cat"/>

  <!-- ============================================ -->
  <!-- PAGE_HEADER ELEMENT: uses component_with_semantic_seq -->
  <!-- ============================================ -->

  <xs:element name="page_header" type="dl:component_with_semantic_seq"/>

  <!-- ============================================ -->
  <!-- PAGE_FOOTER ELEMENT: uses component_with_semantic_seq -->
  <!-- ============================================ -->

  <xs:element name="page_footer" type="dl:component_with_semantic_seq"/>

  <!-- ============================================ -->
  <!-- FOOTNOTE ELEMENT: uses component_with_semantic_seq -->
  <!-- ============================================ -->

  <xs:element name="footnote" type="dl:component_with_semantic_seq"/>

  <!-- ============================================ -->
  <!-- LDIV ELEMENT: List divider, optionally contains a marker -->
  <!-- ============================================ -->

  <xs:element name="ldiv">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="dl:marker" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- GROUP ELEMENT: Container for encapsulating multiple semantic elements -->
  <!-- ============================================ -->

  <xs:element name="group">
    <xs:complexType>
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:group ref="dl:top_level_cat" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- TOP_LEVEL_CAT: reusable group for top-level document elements -->
  <!-- Includes: text, heading, code, formula, page_header, page_footer, footnote, list, field_region, field_heading, field_item, key, value, picture, table, index, group -->
  <!-- Note: caption, description, and summary appear only in the element head (element_head), not in body content -->
  <!-- ============================================ -->

  <xs:group name="top_level_cat">
    <xs:choice>
      <xs:element ref="dl:text"/>
      <xs:element ref="dl:heading"/>
      <xs:element ref="dl:code"/>
      <xs:element ref="dl:formula"/>
      <xs:element ref="dl:page_header"/>
      <xs:element ref="dl:page_footer"/>
      <xs:element ref="dl:footnote"/>
      <xs:element ref="dl:list"/>
      <xs:element ref="dl:group"/>
      <xs:element ref="dl:field_region"/>
      <xs:element ref="dl:field_heading"/>
      <xs:element ref="dl:field_item"/>
      <xs:element ref="dl:key"/>
      <xs:element ref="dl:value"/>
      <xs:element ref="dl:picture"/>
      <xs:element ref="dl:table"/>
      <xs:element ref="dl:index"/>
    </xs:choice>
  </xs:group>

  <!-- ============================================ -->
  <!-- VIRTUAL_TEXT_CONTENT: Content that can appear after ldiv in a list item -->
  <!-- Includes headless_txt (formatting, etc.) and top_level_cat (semantic elements) -->
  <!-- ============================================ -->

  <xs:complexType name="component_with_semantic_seq" mixed="true">
    <xs:sequence>
      <xs:group ref="dl:element_head"/>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="dl:content"/>
        <xs:group ref="dl:headless_txt"/>
        <xs:group ref="dl:top_level_cat"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

  <xs:group name="virtual_text_content">
    <xs:choice>
      <xs:element ref="dl:content"/>
      <xs:group ref="dl:headless_txt"/>
      <xs:group ref="dl:top_level_cat"/>
    </xs:choice>
  </xs:group>

  <!-- ============================================ -->
  <!-- LIST_ITEM: ldiv + optional element_head + virtual_text_content* -->
  <!-- Represents a single list item which can be:
       - Virtual text: ldiv + optional element_head + raw text/formatting/semantic elements
       - Wrapped semantic: ldiv + semantic element(s) -->
  <!-- ============================================ -->

  <xs:group name="list_item">
    <xs:sequence>
      <xs:element ref="dl:ldiv"/>
      <xs:group ref="dl:element_head" minOccurs="0"/>
      <xs:group ref="dl:virtual_text_content" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:group>

  <!-- ============================================ -->
  <!-- LIST ELEMENT: optional element_head + list_item* -->
  <!-- Semantic element: may optionally begin with element_head (per spec.md) -->
  <!-- Element head order enforced by XSD element_head group (sequence) -->
  <!-- Each list item starts with ldiv, followed by optional element_head for virtual text -->
  <!-- Schematron enforces: must start with ldiv (after optional list-level element head) -->
  <!-- ============================================ -->

  <xs:element name="list">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:group ref="dl:list_item" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="class" use="optional" default="unordered">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="ordered"/>
            <xs:enumeration value="unordered"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- TABLE_CELL: cell token + optional element_head + virtual_text_content* -->
  <!-- Represents a single table cell which can be:
       - Virtual text: cell token + optional element_head + raw text/formatting/semantic elements
       - Wrapped semantic: cell token + semantic element(s) -->
  <!-- ============================================ -->

  <xs:group name="table_cell">
    <xs:sequence>
      <xs:group ref="dl:table_sep"/>
      <xs:group ref="dl:element_head" minOccurs="0"/>
      <xs:group ref="dl:virtual_text_content" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:group>

  <!-- ============================================ -->
  <!-- TABLE ELEMENT: optional element_head + table_cell* -->
  <!-- Semantic element: may optionally begin with element_head (per spec.md) -->
  <!-- Element head order enforced by XSD element_head group (sequence) -->
  <!-- Each table cell starts with cell token, followed by optional element_head for virtual text -->
  <!-- Schematron enforces: must start with cell token (after optional table-level element head) -->
  <!-- ============================================ -->

  <xs:element name="table">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:group ref="dl:table_cell" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- TABULAR ELEMENT: structured tabular data payload (child of picture) -->
  <!-- ============================================ -->

  <xs:element name="tabular">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:table_cell" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- INDEX ELEMENT: OTSL-based index (same cell model as table, no class attribute) -->
  <!-- ============================================ -->

  <xs:element name="index">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:group ref="dl:table_cell" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- FIELD_REGION ELEMENT: sequence of top_level_cat (no class attribute) -->
  <!-- ============================================ -->

  <xs:element name="field_region">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:group ref="dl:headless_txt"/>
          <xs:group ref="dl:top_level_cat"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- FIELD_HEADING ELEMENT: like field_region with optional level attribute -->
  <!-- ============================================ -->

  <xs:element name="field_heading">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:group ref="dl:headless_txt"/>
          <xs:group ref="dl:top_level_cat"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="level" type="xs:positiveInteger" default="1"/>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- FIELD_ITEM ELEMENT: like field_region -->
  <!-- ============================================ -->

  <xs:element name="field_item">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:group ref="dl:headless_txt"/>
          <xs:group ref="dl:top_level_cat"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- KEY ELEMENT: like field_region -->
  <!-- ============================================ -->

  <xs:element name="key">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="dl:content"/>
          <xs:group ref="dl:headless_txt"/>
          <xs:group ref="dl:top_level_cat"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- VALUE ELEMENT: like key -->
  <!-- ============================================ -->

  <xs:element name="value">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:group ref="dl:element_head"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="dl:content"/>
          <xs:group ref="dl:headless_txt"/>
          <xs:group ref="dl:top_level_cat"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="class" default="read_only">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="read_only"/>
            <xs:enumeration value="fillable"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- ROOT DOCLANG: sequence of top_level_cat -->
  <!-- ============================================ -->

  <!-- ============================================ -->
  <!-- HEAD ELEMENT: document-level metadata; TODO: specify content (currently arbitrary) -->
  <!-- ============================================ -->

  <xs:element name="head">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- ============================================ -->
  <!-- DOCLANG ROOT ELEMENT: optionally begins with head, followed by top_level_cat elements -->
  <!-- ============================================ -->

  <xs:element name="doclang">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="dl:head" minOccurs="0"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:group ref="dl:top_level_cat"/>
          <xs:element ref="dl:page_break"/>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name="version" use="optional" default="0.7">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <!-- enumeration set up for v1 and above, where all individual minor versions
             within major (up to and including current, i.e. `default` above)
             will have to be listed for backwards compatibility. -->
            <xs:enumeration value="0.7"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

</xs:schema>
