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

<!--
Omeka XML Schema, Version 2.2, 2009-09-21

Changelog from v2.1:
  * Replaces @uri attributes with UriAttributeGroup
  * Replaces UriPatternType (tag URI) with xsd:anyURI in UriAttributeGroup
  * Adds @accessDate with xsd:dateTime type to UriAttributeGroup
-->

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

<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.
        
        This schema allows XML authors to extend container elements with any 
        data deemed necessary for the particular context, e.g., pagination data.
    </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:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="ItemContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="FileContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="file" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="CollectionContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="collection" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="ItemTypeContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="itemType" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="ElementSetContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="elementSet" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="ElementContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="ElementTextContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="elementText" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="TagContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

<xsd:complexType name="EntityContainerType">
    <xsd:sequence>
        <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attributeGroup ref="UriAttributeGroup"/>
</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:attributeGroup ref="UriAttributeGroup"/>
</xsd:complexType>

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

<xsd:attributeGroup name="UriAttributeGroup">
    <xsd:annotation>
        <xsd:documentation>
            These attributes intended to contextualize and/or uniquely identify 
            root elements. When an XML instance derives from a HTTP request, use 
            a combination of @uri and @accessDate, where @uri is the absolute 
            URL of the request (including the query string) and @accessDate is 
            the current ISO 8601 date. When an XML instance derives from other 
            sources, such as a script outside the Web context, use a tag URI: 
            http://taguri.org/
        </xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="uri"        type="xsd:anyURI"/>
    <xsd:attribute name="accessDate" type="xsd:dateTime"/>
</xsd:attributeGroup>

</xsd:schema>
