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

<!--
Omeka XML Schema, Version 1.1, 2009-08-26

Changelog from v1.0:
  * Adds <entity> to global scope, defines EntityType
  * Adds <entityContainer> to global scope, defines EntityContainerType
  * Adds <collectorContainer> to CollectionType, maps to EntityContainerType
  * Adds <entityContainer> to RepositoryType
  * Switches out @name and @type for @ref attributes where appropriate.
-->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns="http://omeka.org/schemas/omeka-xml/v1" 
            targetNamespace="http://omeka.org/schemas/omeka-xml/v1" 
            elementFormDefault="qualified" 
            attributeFormDefault="unqualified" 
            version="1.1">

<xsd:annotation>
    <xsd:documentation>
        This schema provides a fluent template for building non-web-centric 
        Omeka XML instances, while minimizing Omeka-specific metadata. The root 
        element can be most any derivation of Omeka, from multiple Omeka 
        repositories to an individual item, file, or elementText.
        
        This schema avoids redundancy with a liberal use of @minOccurs="0", 
        which, if used properly, will prevent unnecessary recursion (e.g. an 
        item refs a collection, which refs an itemContainer, which contains the 
        original item, etc.). It is up to the XML author to include only the 
        data needed for a particular XML instance.
    </xsd:documentation>
</xsd:annotation>

<!-- Global atomic elements -->
<xsd:element name="repository"  type="RepositoryType"/>
<xsd:element name="item"        type="ItemType"/>
<xsd:element name="file"        type="FileType"/>
<xsd:element name="collection"  type="CollectionType"/>
<xsd:element name="itemType"    type="ItemTypeType"/>
<xsd:element name="elementSet"  type="ElementSetType"/>
<xsd:element name="element"     type="ElementType"/>
<xsd:element name="elementText" type="ElementTextType"/>
<xsd:element name="tag"         type="TagType"/>
<xsd:element name="entity"      type="EntityType"/>

<!-- Global container elements -->
<xsd:element name="repositoryContainer"  type="RepositoryContainerType"/>
<xsd:element name="itemContainer"        type="ItemContainerType"/>
<xsd:element name="fileContainer"        type="FileContainerType"/>
<xsd:element name="collectionContainer"  type="CollectionContainerType"/>
<xsd:element name="itemTypeContainer"    type="ItemTypeContainerType"/>
<xsd:element name="elementSetContainer"  type="ElementSetContainerType"/>
<xsd:element name="elementContainer"     type="ElementContainerType"/>
<xsd:element name="elementTextContainer" type="ElementTextContainerType"/>
<xsd:element name="tagContainer"         type="TagContainerType"/>
<xsd:element name="entityContainer"      type="EntityContainerType"/>

<xsd:complexType name="RepositoryContainerType">
    <xsd:sequence>
        <xsd:element ref="repository" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="RepositoryType">
    <xsd:sequence>
        <xsd:element name="title"       type="xsd:string" minOccurs="0"/>
        <xsd:element name="copyright"   type="xsd:string" minOccurs="0"/>
        <xsd:element name="author"      type="xsd:string" minOccurs="0"/>
        <xsd:element name="description" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="itemContainer"   minOccurs="0"/>
        <xsd:element ref="entityContainer" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="repositoryId" type="RepositoryIdPatternType" use="required"/>
</xsd:complexType>

<xsd:complexType name="ItemContainerType">
    <xsd:sequence>
        <xsd:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ItemType">
    <xsd:sequence>
        <xsd:element ref="fileContainer"       minOccurs="0"/>
        <xsd:element ref="collection"          minOccurs="0"/>
        <xsd:element ref="itemType"            minOccurs="0"/>
        <xsd:element ref="elementSetContainer" minOccurs="0"/>
        <xsd:element ref="tagContainer"        minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="itemId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="FileContainerType">
    <xsd:sequence>
        <xsd:element ref="file" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="FileType">
    <xsd:sequence>
        <xsd:element name="src"            type="xsd:anyURI" minOccurs="0"/>
        <xsd:element name="authentication" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="elementSetContainer" minOccurs="0"/>
        <xsd:element ref="item"                minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="fileId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="CollectionContainerType">
    <xsd:sequence>
        <xsd:element ref="collection" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="CollectionType">
    <xsd:sequence>
        <xsd:element name="name"               type="xsd:string"          minOccurs="0"/>
        <xsd:element name="description"        type="xsd:string"          minOccurs="0"/>
        <xsd:element name="collectorContainer" type="EntityContainerType" minOccurs="0"/>
        <xsd:element ref="itemContainer" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="collectionId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="ItemTypeContainerType">
    <xsd:sequence>
        <xsd:element ref="itemType" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ItemTypeType">
    <xsd:sequence>
        <xsd:element name="name"        type="xsd:string" minOccurs="0"/>
        <xsd:element name="description" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="elementContainer" minOccurs="0"/>
        <xsd:element ref="itemContainer"    minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="itemTypeId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="ElementSetContainerType">
    <xsd:sequence>
        <xsd:element ref="elementSet" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ElementSetType">
    <xsd:annotation>
        <xsd:documentation>
            An elementSet may contain an elementContainer OR any other XML 
            format that accurately represents the element set. For example, an 
            element set may contain the Dublin Core elements OR a dcmes-xml 
            Dublin Core RDF format defined here:
            http://dublincore.org/documents/dcmes-xml/
        </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element name="name"        type="xsd:string" minOccurs="0"/>
        <xsd:element name="description" type="xsd:string" minOccurs="0"/>
        <xsd:choice>
            <xsd:element ref="elementContainer" minOccurs="0"/>
            <xsd:element name="metadata" type="MetadataType" minOccurs="0"/>
        </xsd:choice>
    </xsd:sequence>
    <xsd:attribute name="elementSetId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="ElementContainerType">
    <xsd:sequence>
        <xsd:element ref="element" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ElementType">
    <xsd:sequence>
        <xsd:element name="name"        type="xsd:string" minOccurs="0"/>
        <xsd:element name="description" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="elementSet"           minOccurs="0"/>
        <xsd:element ref="elementTextContainer" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="elementId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="ElementTextContainerType">
    <xsd:sequence>
        <xsd:element ref="elementText" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ElementTextType">
    <xsd:sequence>
        <xsd:element name="text" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="element" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="elementTextId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="TagContainerType">
    <xsd:sequence>
        <xsd:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="TagType">
    <xsd:sequence>
        <xsd:element name="name" type="xsd:string" minOccurs="0"/>
        <xsd:element ref="itemContainer" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="tagId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="EntityContainerType">
    <xsd:sequence>
        <xsd:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="EntityType">
    <xsd:sequence>
        <xsd:element name="firstName"   type="xsd:string" minOccurs="0"/>
        <xsd:element name="middleName"  type="xsd:string" minOccurs="0"/>
        <xsd:element name="lastName"    type="xsd:string" minOccurs="0"/>
        <xsd:element name="email"       type="xsd:string" minOccurs="0"/>
        <xsd:element name="institution" type="xsd:string" minOccurs="0"/>
    </xsd:sequence>
    <xsd:attribute name="entityId" type="xsd:positiveInteger" use="required"/>
</xsd:complexType>

<xsd:complexType name="MetadataType">
    <xsd:sequence>
        <xsd:any namespace="##other" processContents="lax"/>
    </xsd:sequence>
</xsd:complexType>

<xsd:simpleType name="RepositoryIdPatternType">
    <xsd:annotation>
        <xsd:documentation>
            This type must conform to the following tag URI format:
            "tag:" DNSname "," yyyy "-" mm "-" dd ":repository"
            See here: http://taguri.org/
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
        <xsd:pattern value="tag:.+,[0-9]{4}-[0-9]{2}-[0-9]{2}:repository"/>
    </xsd:restriction>
</xsd:simpleType>

</xsd:schema>
