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

<xs:schema xmlns:xs="https://www.w3.org/2001/XMLSchema"
    targetNamespace="https://www.doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd"
    xmlns:odm="https://www.doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd"
    elementFormDefault="qualified">

  <xs:annotation>
    <xs:documentation><![CDATA[
       This is the XML Schema for the object/document
       mapping file used by the Doctrine ODM.
     ]]></xs:documentation>
  </xs:annotation>

  <xs:element name="doctrine-mongo-mapping">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="document" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="embedded-document" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="mapped-superclass" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
        <xs:element name="query-result-document" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="embedded-document">
    <xs:attribute name="name" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="mapped-superclass">
    <xs:attribute name="name" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="query-result-document">
    <xs:attribute name="name" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="document">
    <xs:sequence>
      <xs:element name="field" type="odm:field" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="embed-one" type="odm:embed-one" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="embed-many" type="odm:embed-many" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="reference-one" type="odm:reference-one" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="reference-many" type="odm:reference-many" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="discriminator-field" type="odm:discriminator-field" minOccurs="0"/>
      <xs:element name="discriminator-map" type="odm:discriminator-map" minOccurs="0"/>
      <xs:element name="default-discriminator-value" type="odm:default-discriminator-value" minOccurs="0"/>
      <xs:element name="lifecycle-callbacks" type="odm:lifecycle-callbacks" minOccurs="0"/>
      <xs:element name="also-load-methods" type="odm:also-load-methods" minOccurs="0"/>
      <xs:element name="indexes" type="odm:indexes" minOccurs="0"/>
      <xs:element name="shard-key" type="odm:shard-key" minOccurs="0"/>
      <xs:element name="read-preference" type="odm:read-preference" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="db" type="xs:NMTOKEN" />
    <xs:attribute name="name" type="xs:string" />
    <xs:attribute name="writeConcern" type="xs:string" />
    <xs:attribute name="collection" type="xs:NMTOKEN" />
    <xs:attribute name="capped-collection" type="xs:boolean" />
    <xs:attribute name="capped-collection-size" type="xs:integer" />
    <xs:attribute name="capped-collection-max" type="xs:integer" />
    <xs:attribute name="repository-class" type="xs:string"/>
    <xs:attribute name="inheritance-type" type="odm:inheritance-type"/>
    <xs:attribute name="change-tracking-policy" type="odm:change-tracking-policy" />
    <xs:attribute name="read-only" type="xs:boolean" />
  </xs:complexType>

  <xs:complexType name="read-preference">
    <xs:sequence>
      <xs:element name="tag-set" type="odm:read-preference-tag-set" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="mode" type="odm:read-preference-values"/>
  </xs:complexType>

  <xs:complexType name="field">
    <xs:sequence>
      <xs:element name="id-generator-option" type="odm:id-generator-option" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="id" type="xs:boolean" default="false" />
    <xs:attribute name="name" type="xs:NMTOKEN" />
    <xs:attribute name="type" type="xs:NMTOKEN" />
    <xs:attribute name="strategy" type="xs:NMTOKEN" default="set" />
    <xs:attribute name="fieldName" type="xs:NMTOKEN" />
    <xs:attribute name="embed" type="xs:boolean" />
    <xs:attribute name="reference" type="xs:boolean" />
    <xs:attribute name="version" type="xs:boolean" />
    <xs:attribute name="lock" type="xs:boolean" />
    <xs:attribute name="not-saved" type="xs:boolean" />
    <xs:attribute name="nullable" type="xs:boolean" />
    <xs:attribute name="also-load" type="xs:NMTOKEN" />
    <!-- index options -->
    <xs:attribute name="background" type="xs:boolean" />
    <xs:attribute name="drop-dups" type="xs:boolean" />
    <xs:attribute name="index" type="xs:boolean" />
    <xs:attribute name="index-name" type="xs:NMTOKEN" />
    <xs:attribute name="order" type="xs:NMTOKEN" />
    <xs:attribute name="sparse" type="xs:boolean" />
    <xs:attribute name="unique" type="xs:boolean" />
  </xs:complexType>

  <xs:complexType name="id-generator-option">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="value" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:complexType name="embed-one">
    <xs:sequence>
      <xs:element name="discriminator-field" type="odm:discriminator-field" minOccurs="0"/>
      <xs:element name="discriminator-map" type="odm:discriminator-map" minOccurs="0"/>
      <xs:element name="default-discriminator-value" type="odm:default-discriminator-value" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="target-document" type="xs:string" />
    <xs:attribute name="field" type="xs:NMTOKEN" use="required" />
    <xs:attribute name="fieldName" type="xs:NMTOKEN" />
    <xs:attribute name="not-saved" type="xs:boolean" />
    <xs:attribute name="nullable" type="xs:boolean" />
    <xs:attribute name="also-load" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="embed-many">
    <xs:sequence>
      <xs:element name="discriminator-field" type="odm:discriminator-field" minOccurs="0"/>
      <xs:element name="discriminator-map" type="odm:discriminator-map" minOccurs="0"/>
      <xs:element name="default-discriminator-value" type="odm:default-discriminator-value" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="target-document" type="xs:string" />
    <xs:attribute name="collection-class" type="xs:string" />
    <xs:attribute name="field" type="xs:NMTOKEN" use="required" />
    <xs:attribute name="fieldName" type="xs:NMTOKEN" />
    <xs:attribute name="strategy" type="xs:NMTOKEN" default="pushAll" />
    <xs:attribute name="not-saved" type="xs:boolean" />
    <xs:attribute name="nullable" type="xs:boolean" />
    <xs:attribute name="also-load" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:simpleType name="reference-store-as">
    <xs:restriction base="xs:token">
      <xs:enumeration value="id"/>
      <xs:enumeration value="ref"/>
      <xs:enumeration value="dbRef"/>
      <xs:enumeration value="dbRefWithDb"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="reference-one">
    <xs:sequence>
      <xs:element name="cascade" type="odm:cascade-type" minOccurs="0" />
      <xs:element name="discriminator-field" type="odm:discriminator-field" minOccurs="0"/>
      <xs:element name="discriminator-map" type="odm:discriminator-map" minOccurs="0"/>
      <xs:element name="default-discriminator-value" type="odm:default-discriminator-value" minOccurs="0"/>
      <xs:element name="sort" type="odm:sort-map" minOccurs="0" />
      <xs:element name="criteria" type="odm:criteria-map" minOccurs="0" />
    </xs:sequence>
    <xs:attribute name="target-document" type="xs:string" />
    <xs:attribute name="field" type="xs:NMTOKEN" use="required" />
    <xs:attribute name="fieldName" type="xs:NMTOKEN" />
    <xs:attribute name="simple" type="xs:boolean" /><!-- deprecated -->
    <xs:attribute name="store-as" type="odm:reference-store-as" default="dbRefWithDb" />
    <xs:attribute name="inversed-by" type="xs:NMTOKEN" />
    <xs:attribute name="mapped-by" type="xs:NMTOKEN" />
    <xs:attribute name="repository-method" type="xs:NMTOKEN" />
    <xs:attribute name="orphan-removal" type="xs:boolean" />
    <xs:attribute name="not-saved" type="xs:boolean" />
    <xs:attribute name="nullable" type="xs:boolean" />
    <xs:attribute name="also-load" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="reference-many">
    <xs:sequence>
      <xs:element name="cascade" type="odm:cascade-type" minOccurs="0" />
      <xs:element name="discriminator-field" type="odm:discriminator-field" minOccurs="0"/>
      <xs:element name="discriminator-map" type="odm:discriminator-map" minOccurs="0"/>
      <xs:element name="default-discriminator-value" type="odm:default-discriminator-value" minOccurs="0"/>
      <xs:element name="sort" type="odm:sort-map" minOccurs="0" />
      <xs:element name="criteria" type="odm:criteria-map" minOccurs="0" />
      <xs:element name="prime" type="odm:primers" minOccurs="0" />
    </xs:sequence>
    <xs:attribute name="target-document" type="xs:string" />
    <xs:attribute name="collection-class" type="xs:string" />
    <xs:attribute name="field" type="xs:NMTOKEN" use="required" />
    <xs:attribute name="fieldName" type="xs:NMTOKEN" />
    <xs:attribute name="simple" type="xs:boolean" /><!-- deprecated -->
    <xs:attribute name="store-as" type="odm:reference-store-as" default="dbRefWithDb" />
    <xs:attribute name="strategy" type="xs:NMTOKEN" default="pushAll" />
    <xs:attribute name="inversed-by" type="xs:NMTOKEN" />
    <xs:attribute name="mapped-by" type="xs:NMTOKEN" />
    <xs:attribute name="repository-method" type="xs:NMTOKEN" />
    <xs:attribute name="limit" type="xs:integer" />
    <xs:attribute name="skip" type="xs:integer" />
    <xs:attribute name="orphan-removal" type="xs:boolean" />
    <xs:attribute name="not-saved" type="xs:boolean" />
    <xs:attribute name="nullable" type="xs:boolean" />
    <xs:attribute name="also-load" type="xs:NMTOKEN" />
  </xs:complexType>

  <xs:complexType name="sort-type">
    <xs:attribute name="field" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="order" type="xs:NMTOKEN" default="asc" />
  </xs:complexType>

  <xs:complexType name="sort-map">
    <xs:sequence>
      <xs:element name="sort" type="odm:sort-type" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="criteria-type">
    <xs:attribute name="field" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="value" type="xs:NMTOKEN" use="required" />
  </xs:complexType>

  <xs:complexType name="criteria-map">
    <xs:sequence>
      <xs:element name="criteria" type="odm:criteria-type" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="primers">
    <xs:sequence>
      <xs:element name="field" type="odm:primer-field" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="primer-field">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
  </xs:complexType>

  <xs:complexType name="emptyType"/>

  <xs:complexType name="cascade-type">
    <xs:sequence>
      <xs:element name="all" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
      <xs:element name="persist" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
      <xs:element name="merge" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
      <xs:element name="remove" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
      <xs:element name="refresh" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
      <xs:element name="detach" type="odm:emptyType" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="inheritance-type">
    <xs:restriction base="xs:token">
      <xs:enumeration value="SINGLE_COLLECTION"/>
      <xs:enumeration value="COLLECTION_PER_CLASS"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="change-tracking-policy">
    <xs:restriction base="xs:token">
      <xs:enumeration value="DEFERRED_IMPLICIT" />
      <xs:enumeration value="DEFERRED_EXPLICIT"/>
      <xs:enumeration value="NOTIFY"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="discriminator-mapping">
    <xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="class" type="xs:string" use="required"/>
  </xs:complexType>

  <xs:complexType name="discriminator-map">
    <xs:sequence>
      <xs:element name="discriminator-mapping" type="odm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="discriminator-field">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
  </xs:complexType>

  <xs:complexType name="default-discriminator-value">
    <xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
  </xs:complexType>

  <xs:simpleType name="lifecycle-callback-type">
    <xs:restriction base="xs:token">
      <xs:enumeration value="prePersist"/>
      <xs:enumeration value="postPersist"/>
      <xs:enumeration value="preUpdate"/>
      <xs:enumeration value="postUpdate"/>
      <xs:enumeration value="preRemove"/>
      <xs:enumeration value="postRemove"/>
      <xs:enumeration value="preLoad"/>
      <xs:enumeration value="postLoad"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="lifecycle-callback">
    <xs:attribute name="type" type="odm:lifecycle-callback-type" use="required"/>
    <xs:attribute name="method" type="xs:NMTOKEN" use="required"/>
  </xs:complexType>

  <xs:complexType name="lifecycle-callbacks">
    <xs:sequence>
      <xs:element name="lifecycle-callback" type="odm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="index-key">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="order" type="xs:NMTOKEN" default="asc" />
  </xs:complexType>

  <xs:complexType name="index-option">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="value" type="xs:NMTOKEN" use="required" />
  </xs:complexType>

  <xs:simpleType name="partial-filter-expression-operator">
    <xs:restriction base="xs:token">
      <xs:enumeration value="eq"/>
      <xs:enumeration value="exists"/>
      <xs:enumeration value="gt"/>
      <xs:enumeration value="gte"/>
      <xs:enumeration value="lt"/>
      <xs:enumeration value="lte"/>
      <xs:enumeration value="type"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="partial-filter-expression-field">
    <xs:sequence>
      <xs:element name="field" type="odm:partial-filter-expression-field" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="operator" type="odm:partial-filter-expression-operator" use="optional" />
    <xs:attribute name="value" type="xs:string" use="optional" />
  </xs:complexType>

  <xs:complexType name="partial-filter-expression-and">
    <xs:sequence>
      <xs:element name="field" type="odm:partial-filter-expression-field" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="partial-filter-expression">
    <xs:choice>
      <xs:element name="and" type="odm:partial-filter-expression-and" minOccurs="1" maxOccurs="unbounded" />
      <xs:element name="field" type="odm:partial-filter-expression-field" minOccurs="1" maxOccurs="unbounded" />
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="index">
    <xs:sequence>
      <xs:element name="key" type="odm:index-key" minOccurs="1" maxOccurs="unbounded"/>
      <xs:element name="option" type="odm:index-option" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element name="partial-filter-expression" type="odm:partial-filter-expression" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="name" type="xs:NMTOKEN"/>
    <xs:attribute name="drop-dups" type="xs:boolean"/>
    <xs:attribute name="background" type="xs:boolean"/>
    <xs:attribute name="unique" type="xs:boolean"/>
    <xs:attribute name="sparse" type="xs:boolean"/>
  </xs:complexType>

  <xs:complexType name="indexes">
    <xs:sequence>
      <xs:element name="index" type="odm:index" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="shard-key">
    <xs:sequence>
      <xs:element name="key" type="odm:shard-key-key" minOccurs="1" maxOccurs="unbounded"/>
      <xs:element name="option" type="odm:shard-key-option" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="unique" type="xs:boolean"/>
    <xs:attribute name="numInitialChunks" type="xs:integer"/>
  </xs:complexType>

  <xs:complexType name="shard-key-key">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="order" type="xs:NMTOKEN" default="asc" />
  </xs:complexType>

  <xs:complexType name="shard-key-option">
    <xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="value" type="xs:NMTOKEN" use="required" />
  </xs:complexType>

  <xs:complexType name="also-load-method">
    <xs:attribute name="method" type="xs:NMTOKEN" use="required"/>
    <xs:attribute name="field" type="xs:NMTOKEN" use="required"/>
  </xs:complexType>


  <xs:complexType name="also-load-methods">
    <xs:sequence>
      <xs:element name="also-load-method" type="odm:also-load-method" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="read-preference-values">
    <xs:restriction base="xs:string">
      <xs:enumeration value="primary" />
      <xs:enumeration value="primaryPreferred" />
      <xs:enumeration value="secondary" />
      <xs:enumeration value="secondaryPreferred" />
      <xs:enumeration value="nearest" />
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="read-preference-tag-set">
    <xs:sequence>
      <xs:element name="tag" type="read-preference-tag" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="read-preference-tag">
    <xs:attribute name="name" type="xs:string" use="required" />
    <xs:attribute name="value" type="xs:string" use="required" />
  </xs:complexType>

</xs:schema>
