<?xml version="1.0" encoding="UTF-8"?>
<!--
    NamesforLife Common XML Schema
    
    Copyright (c) 2024, The Regents of the University of California, through
    Lawrence Berkeley National Laboratory (subject to receipt of any required
    approvals from the U.S. Dept. of Energy). All rights reserved.

    CLOCKSS system has permission to ingest, preserve, and serve this Archival Unit.
    LOCKSS system has permission to collect, preserve, and serve this Archival Unit.

    This content is licensed under a Creative Commons Attribution 3.0 International license.
    https://creativecommons.org/licenses/by/3.0/
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://namesforlife.com/ns/common" targetNamespace="http://namesforlife.com/ns/common" elementFormDefault="qualified">

    <xs:group name="styleGroup">
        <xs:choice>
            <xs:element name="b" type="boldType" />
            <xs:element name="i" type="italicType" />
        </xs:choice>
    </xs:group>

    <xs:group name="phraseGroup">
        <xs:choice>
            <xs:element name="em" type="emphasisType" />
            <xs:element name="sub" type="subscriptType" />
            <xs:element name="sup" type="superscriptType" />
        </xs:choice>
    </xs:group>

    <xs:group name="inlineType">
        <xs:choice>
            <xs:group ref="styleGroup" />
            <xs:group ref="phraseGroup" />
        </xs:choice>
    </xs:group>

    <xs:complexType name="inlineContentType" mixed="true">
        <xs:annotation>
            <xs:documentation>
                "Inline" covers inline or "text-level" elements
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:group ref="inlineType" />
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="boldType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="emphasisType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="italicType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="subscriptType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="superscriptType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType" />
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="sentenceType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType">
                <xs:attribute name="class" type="xs:string" use="optional" />
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="paragraphType">
        <xs:sequence>
            <xs:element name="s" type="sentenceType" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="class" type="xs:string" use="optional" />
    </xs:complexType>

    <!-- Enumeration of supported taxonomic categories (ranks). -->
    <xs:simpleType name="rankEnumType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="root" />
            <xs:enumeration value="unspecified" />
            <xs:enumeration value="superkingdom" />
            <xs:enumeration value="domain" />
            <xs:enumeration value="phylum" />
            <xs:enumeration value="class" />
            <xs:enumeration value="subclass" />
            <xs:enumeration value="order" />
            <xs:enumeration value="suborder" />
            <xs:enumeration value="family" />
            <xs:enumeration value="subfamily" />
            <xs:enumeration value="genus" />
            <xs:enumeration value="subgenus" />
            <xs:enumeration value="species" />
            <xs:enumeration value="subspecies" />
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="contentType">
        <xs:sequence>
            <xs:element name="p" type="paragraphType" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <!-- DOI type: 10.###/xyz#### -->
    <xs:simpleType name="doiType">
        <xs:restriction base="xs:string">
            <xs:pattern value="10(\.\d+)+/[A-Za-z0-9\-\.\d]+" />
        </xs:restriction>
    </xs:simpleType>

    <!-- Maps a name/rank to a DOI. Common to all names. -->
    <xs:complexType name="nameIdentifierType" mixed="true">
        <xs:complexContent>
            <xs:extension base="inlineContentType">
                <xs:attribute name="doi" type="doiType" use="required" /> <!-- this is the Name DOI -->
                <xs:attribute name="rank" type="rankEnumType" use="required" /> <!-- bare names are not allowed, and every taxon must have a rank assigned -->
                <xs:attribute name="taxon-doi" type="doiType" use="required" /> <!-- bare names are not allowed, so every name must have a taxon -->
                <xs:attribute name="nomenclatural-type" type="doiType" use="optional" /> <!-- Note: This is redundant with taxon/nomenclatural-type/@nomenclatural-type but that element is not available in exemplar XML. -->
                <xs:attribute name="nomenclatural-type-exemplar" type="doiType" use="optional" /> <!-- Note: This is redundant with taxon/nomenclatural-type/@nomenclatural-type-exemplar but that element is not available in exemplar XML. -->
           </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="organism" type="nameIdentifierType" />

    <xs:element name="content" type="contentType" />

    <xs:element name="annotation" type="annotationType" />
    
    <xs:element name="nomenclature" type="nomenclatureType" />

    <xs:complexType name="nomenclaturalTypeType">
        <xs:complexContent>
            <xs:extension base="nomenclatureType">
                <xs:attribute name="nomenclatural-type" type="doiType" use="optional" /> <!-- some illegitimate and higher taxa do not have a nomenclatural type assigned -->
                <xs:attribute name="nomenclatural-type-exemplar" type="doiType" use="optional" /> <!-- some illegitimate and higher taxa do not have a nomenclatural type assigned -->
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="nomenclatural-type" type="nomenclaturalTypeType" />

    <xs:complexType name="informationObjectType">
        <xs:attribute name="doi" type="doiType" use="required" />
    </xs:complexType>

    <xs:complexType name="nomenclatureType">
        <xs:sequence>
            <xs:element ref="name-status-group" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:element name="name-status-group" type="nameStatusGroupType" />

    <xs:complexType name="nameStatusGroupType">
        <xs:group ref="nameStatusGroup" minOccurs="1" maxOccurs="1" />
    </xs:complexType>

    <xs:group name="nameStatusGroup">
        <xs:sequence>
            <xs:element name="identifier" type="nameIdentifierType" />
            <xs:element name="authority" type="xs:string" />
            <xs:element name="status">
                <xs:complexType>
                    <xs:attribute name="status-code" type="validationEnumType" use="required" />
                    <xs:attribute name="current-name" type="xs:string" use="required" />
                    <xs:attribute name="current-name-doi" type="doiType" use="required" />
                    <xs:attribute name="is-current" type="xs:boolean" use="required" />
                    <xs:attribute name="candidatus" type="xs:boolean" use="optional" />
                    <xs:attribute name="conserved" type="xs:boolean" use="optional" />
                    <xs:attribute name="rejected" type="xs:boolean" use="optional" />
                    <xs:attribute name="illegitimate" type="xs:boolean" use="optional" />
                    <xs:attribute name="revived" type="xs:boolean" use="optional" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:group>

    <xs:complexType name="annotationType">
        <xs:sequence>
            <xs:element name="snapshot" type="updateType" minOccurs="1" maxOccurs="1" />
            <xs:element name="modified" type="updateType" minOccurs="0" maxOccurs="1" />
            <xs:element name="created" type="updateType" minOccurs="0" maxOccurs="1" />
            <xs:element name="curatorial-note" type="xs:string" minOccurs="0" maxOccurs="1" />
            <xs:element name="public-note" type="xs:string" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="updateType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="date" type="xs:date" use="required" />
                <xs:attribute name="time" type="xs:time" use="required" />
                <xs:attribute name="date-formatted" type="xs:string" use="optional" />
                <xs:attribute name="time-formatted" type="xs:string" use="optional" />
                <xs:attribute name="curator" type="xs:token" use="optional" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <!-- Enumeration of supported validation types. -->
    <xs:simpleType name="validationEnumType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="AL" /> <!-- Approved Lists -->
            <xs:enumeration value="VP" /> <!-- Validly Published -->
            <xs:enumeration value="VL" /> <!-- Validation List -->
            <xs:enumeration value="NVP" /> <!-- Not Validly Published -->
            <xs:enumeration value="CA" /> <!-- Candidatus -->
            <xs:enumeration value="X" /> <!-- Not Curated -->
        </xs:restriction>
    </xs:simpleType>

</xs:schema>