<xs:schema targetNamespace="http://amf.openlib.org"
           xmlns="http://amf.openlib.org"
           xmlns:x="http://www.w3.org/XML/1998/namespace"
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">

 <xs:annotation>
  <xs:documentation>
   Schema for AMF records
   Overall description: http://openlib.org/2001/doc/ebisu.html
   Thomas Krichel (krichel@openlib.org), 2002-10-24
   Simeon Warner (simeon@cs.cornell.edu), 2002-08-05
   Comments welcome!
  </xs:documentation>
 </xs:annotation>

 <xs:import namespace="http://www.w3.org/XML/1998/namespace"
            schemaLocation="http://www.w3.org/2001/xml.xsd" /> 

 <!-- supported schemas, all derived types of SimpleLitteral --> 
 <xs:include schemaLocation="http://amf.openlib.org/2001/mime-types.xsd"/>
 <xs:include schemaLocation="http://amf.openlib.org/2001/jel1991.xsd"/>

 <xs:complexType name="SimpleLiteral">
  <xs:annotation>
   <xs:documentation xml:lang="en"> This type has been composed for
    the DCMES 1.1 XML Schema XML Schema effort at 
    http://www.ukoln.ac.uk/metadata/dcmi/xmlschema/dc.xsd, see 
    this URL for author information. It is default type for the DC
    elements, and it is also the default type for all 
    attributes in AMF. It permits text content only with optional
    xml:lang attribute. Text is allowed because mixed="true", but
    sub-elements are disallowed because minOccurs="0" and maxOccurs="0"
    are on the xs:any tag. This complexType allows for restriction
    or extension permitting child elements.
   </xs:documentation>
  </xs:annotation>
  <xs:complexContent mixed="true">
   <xs:restriction base="xs:anyType">
    <xs:sequence>
     <xs:any processContents="lax" minOccurs="0" maxOccurs="0" /> 
    </xs:sequence>
    <xs:attribute ref="x:lang" use="optional" /> 
   </xs:restriction>
  </xs:complexContent>
 </xs:complexType>

 <!-- root element of AMF record-->
 <xs:element name="amf" type="nounWithAttributeListType"/>

 <!-- nounList: one or more nouns in any sequence --> 
 <xs:complexType name="nounWithAttributeListType">
  <xs:choice minOccurs="1" maxOccurs="unbounded">
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="person"         type="poTypeWithAttributes"/>
   <xs:element name="organization"   type="poTypeWithAttributes"/>
   <xs:element name="text"           type="textTypeWithAttributes"/> 		
   <xs:element name="collection"     type="collectionTypeWithAttributes"/>	
  </xs:choice>
 </xs:complexType>

 <!-- ideally, we would like to say that the nouns can be empty, 
  in which case they have the "ref" attribute, or that they can be
  non-empty and have the "ref" attribute, or they can be non-empty
  and have the "id" attribute. Unfortunately, the current version
  of XML Schema does not allow for that, as far as Thomas Krichel
  is aware. Nevertheless, we will first define the noun elemnets 
  without attributes, and later attach attributes to them. One
  day that might be useful, if we can add other constraints. -->
    
 <!-- attach attributes to nouns -->
 <xs:complexType name="poTypeWithAttributes">
  <xs:complexContent>
   <xs:extension base="poTypeWithoutAttributes"> 
    <xs:attributeGroup ref="nounAttributes"/>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>

 <xs:complexType name="textTypeWithAttributes">
  <xs:complexContent>
   <xs:extension base="textTypeWithoutAttributes"> 
    <xs:attributeGroup ref="nounAttributes"/>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>

 <xs:complexType name="collectionTypeWithAttributes">
  <xs:complexContent>
   <xs:extension base="collectionTypeWithoutAttributes"> 
    <xs:attributeGroup ref="nounAttributes"/>
   </xs:extension>
  </xs:complexContent>
 </xs:complexType>

 <!-- po noun content type -->
 <xs:complexType name="poTypeWithoutAttributes">
  <xs:choice minOccurs="0" maxOccurs="unbounded">
   <!--adjectives-->
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="name"           type="SimpleLiteral"/> <!--vCard:FN-->  
   <xs:element name="shortname"      type="SimpleLiteral"/> <!--vCard:N;NickName-->
   <xs:element name="familyname"     type="SimpleLiteral"/> <!--vCard:N;FamilyName-->
   <xs:element name="givenname"      type="SimpleLiteral"/> <!--vCard:N;GivenName-->
   <xs:element name="additionalname" type="SimpleLiteral"/> <!--vCard:N;AdditionalName-->
   <xs:element name="nameprefix"     type="SimpleLiteral"/> <!--vCard:N;HonoraryPrefix-->
   <xs:element name="namesuffix"     type="SimpleLiteral"/> <!--vCard:N;HonorarySuffix-->
   <xs:element name="date"           type="simpleW3CDateTime"/>	 <!--dc:date-->
   <xs:element name="homepage"       type="urlType"/>
   <xs:element name="postal"         type="SimpleLiteral"/> <!--vCard:LABEL-->
   <xs:element name="phone"          type="SimpleLiteral"/> <!--vCard:TEL;TYPE=pref,voice-->
   <xs:element name="fax"            type="SimpleLiteral"/> <!--vCard:TEL;TYPE=pref,fax-->
   <xs:element name="email"          type="SimpleLiteral"/> <!--vCard:EMAIL;TYPE=internet,pref-->
   <xs:element name="identifier"     type="xs:anyURI"/>
   <!--po to po verbs-->
   <xs:element name="isreplacedby"   type="toPOVerb"/>
   <xs:element name="replaces"       type="toPOVerb"/>
   <xs:element name="ismemberof"     type="toPOVerb"/>
   <xs:element name="hasmember"      type="toPOVerb"/>
   <!--po to text verbs-->
   <xs:element name="iseditorof"     type="toTextOrCollectionVerb"/>
   <xs:element name="ispublisherof"  type="toTextOrCollectionVerb"/>
   <xs:element name="ismaintainerof" type="toTextOrCollectionVerb"/>
   <!--po to text/collection verbs-->
   <xs:element name="isauthorof"     type="toTextVerb"/> 
   <xs:element name="istranslatorof" type="toTextVerb"/>
  </xs:choice>
 </xs:complexType>

 <!-- text noun content type -->
 <xs:complexType name="textTypeWithoutAttributes">
  <xs:choice minOccurs="0" maxOccurs="unbounded">
   <!--adjectives-->
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="title"          type="SimpleLiteral"/> <!--dc:title-->
   <xs:element name="abstract"       type="SimpleLiteral"/> <!--dc:description-->
   <xs:element name="keywords"       type="SimpleLiteral"/> <!--dc:description-->
   <xs:element name="classification" type="xs:string"/> <!--dc:description-->
   <xs:element name="copyright"      type="SimpleLiteral"/> <!--dc:rights-->
   <xs:element name="status"         type="SimpleLiteral"/>
   <xs:element name="comment"        type="SimpleLiteral"/>
   <xs:element name="email"          type="SimpleLiteral"/>
   <xs:element name="date"           type="complexW3CDateTime"/>
   <xs:element name="displaypage"    type="urlType"/>
   <xs:element name="citation"       type="SimpleLiteral"/>
   <xs:element name="serial">
    <xs:complexType>
     <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:any namespace="##other" processContents="strict"/>
      <xs:element name="journaltitle"            type="SimpleLiteral"/> <!--OpenURL:title FIXME-name-->
      <xs:element name="journalabbreviatedtitle" type="SimpleLiteral"/> <!--OpenURL:stitle FIXME-name-->
      <xs:element name="issuedate"         type="simpleW3CDateTime"/> <!--OpenURL:date FIXME-name-->
      <xs:element name="volume"            type="SimpleLiteral"/> <!--OpenURL:volume-->
      <xs:element name="part"              type="SimpleLiteral"/> <!--OpenURL:part-->
      <xs:element name="issue"             type="SimpleLiteral"/> <!--OpenURL:issue-->
      <xs:element name="season"            type="SimpleLiteral"/> <!--OpenURL:ssn  FIXME-type,name-->
      <xs:element name="quarter"           type="SimpleLiteral"/> <!--OpenURL:quarter FIXME-type-->
      <xs:element name="startpage"         type="SimpleLiteral"/> <!--OpenURL:spage FIXME-name,type-->
      <xs:element name="endpage"           type="SimpleLiteral"/> <!--OpenURL:epage FIXME-name,type-->
      <xs:element name="articlenumber"     type="SimpleLiteral"/> <!--OpenURL:artnum FIXME-name,type-->
     </xs:choice>
    </xs:complexType>
   </xs:element>
   <xs:element name="file">
    <xs:complexType>
     <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:any namespace="##other" processContents="strict"/>
      <xs:element name="url"         type="urlType"/>
      <xs:element name="function"    type="SimpleLiteral"/>
      <xs:element name="format"      type="mimeType"/>	 <!--dc:format-->
      <xs:element name="restriction" type="SimpleLiteral"/> <!--dc:rights-->	
     </xs:choice>
    </xs:complexType>
   </xs:element>
   <xs:element name="reference">
    <xs:complexType>
     <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:any namespace="##other" processContents="strict"/>
      <xs:element name="literal" type="SimpleLiteral"/>
      <xs:element name="context" type="SimpleLiteral"/>
     </xs:choice>
    </xs:complexType>
   </xs:element>
   <xs:element name="type">  <!--dc:type-->
    <xs:simpleType>
     <xs:restriction base="xs:string">
      <xs:enumeration value="book"/>
      <xs:enumeration value="conferencepaper"/>
      <xs:enumeration value="bookitem"/>
      <xs:enumeration value="article"/>
      <xs:enumeration value="preprint"/>
     </xs:restriction>   
    </xs:simpleType>
   </xs:element>
   <xs:element name="identifier"      type="xs:anyURI"/> <!--dc:identifier-->
   <!--text to text verbs-->
   <xs:element name="iserratumof"     type="toTextVerb"/>
   <xs:element name="haserratum"      type="toTextVerb"/>
   <xs:element name="isaddendumof"    type="toTextVerb"/>
   <xs:element name="hasaddendum"     type="toTextVerb"/>
   <xs:element name="isreviewof"      type="toTextVerb"/>
   <xs:element name="hasreview"       type="toTextVerb"/>
   <xs:element name="iscommenton"     type="toTextVerb"/>
   <xs:element name="hascomment"      type="toTextVerb"/>
   <xs:element name="istranslationof" type="toTextVerb"/>
   <xs:element name="hastranslation"  type="toTextVerb"/>
   <xs:element name="isreplacedby"    type="toTextVerb"/>
   <xs:element name="replaces"        type="toTextVerb"/>
   <xs:element name="haspart"         type="toTextVerb"/>
   <xs:element name="isreferencedby"  type="toTextVerb"/> <!--dcq:isReferencedBy-->
   <xs:element name="references"      type="toTextVerb"/> <!--dcq:references-->
   <xs:element name="isversionof"     type="toTextVerb"/> <!--dcq:isVersionOf-->
   <xs:element name="hasversion"      type="toTextVerb"/> <!--dcq:hasVersion-->
   <xs:element name="isformatof"      type="toTextVerb"/> <!--dcq:isFormatOf-->
   <xs:element name="hasformat"       type="toTextVerb"/> <!--dcq:hasFormat-->
   <!--text to po verbs-->
   <xs:element name="hasauthor"     type="toPOVerb"/> <!--dc:creator-->
   <xs:element name="haseditor"     type="toPOVerb"/>
   <xs:element name="haspublisher"  type="toPOVerb"/> <!--dc:publisher-->
   <xs:element name="hassupervisor" type="toPOVerb"/>
   <xs:element name="hastranslator" type="toPOVerb"/>
   <xs:element name="hasmaintainer" type="toPOVerb"/>
   <!--text to text or collection verbs-->
   <xs:element name="ispartof"      type="toTextOrCollectionVerb"/> <!--dcq:isPartOf-->
  </xs:choice>
 </xs:complexType>

 <!-- collection noun content type -->
 <xs:complexType name="collectionTypeWithoutAttributes">
  <xs:choice minOccurs="0" maxOccurs="unbounded">
   <!--adjectives-->
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="title"       type="SimpleLiteral"/>
   <xs:element name="description" type="SimpleLiteral"/> <!--dc:description-->
   <xs:element name="shortitle"   type="SimpleLiteral"/> <!-- stitle to match OpenURL?-->
   <xs:element name="homepage"    type="urlType"/>
   <xs:element name="type">
    <xs:simpleType>
     <xs:restriction base="xs:string">
      <xs:enumeration value="book"/>
      <xs:enumeration value="proceedings"/>
      <xs:enumeration value="journal"/>
      <xs:enumeration value="classification"/>
      <xs:enumeration value="series"/>
      <xs:enumeration value="archive"/>
     </xs:restriction>   
    </xs:simpleType>
   </xs:element>
   <xs:element name="identifier"    type="xs:anyURI"/> <!--dc:identifier-->
   <!--collection to po verbs-->
   <xs:element name="haseditor"     type="toPOVerb"/>
   <xs:element name="haspublisher"  type="toPOVerb"/> <!--dc:publisher-->
   <xs:element name="hasmaintainer" type="toPOVerb"/>
   <!--collection to collection verbs-->
   <xs:element name="isreplacedby" type="toCollectionVerb"/> <!--dcq:isReplacedBy-->
   <xs:element name="replaces"     type="toCollectionVerb"/> <!--dcq:replaces-->
   <xs:element name="ispartof"     type="toCollectionVerb"/> <!--dcq:isPartOf-->
   <!--collection to text or collection verbs-->
   <xs:element name="haspart" type="toTextOrCollectionVerb"/>	<!--dcq:hasPart-->
  </xs:choice>
 </xs:complexType>

 <!-- content and attribute types for verbs which admit one
  or more noun elements and have verbAttributes -->

 <!-- verb that admits a text as object -->
 <xs:complexType name="toTextVerb">
  <xs:choice minOccurs="1" maxOccurs="unbounded" >
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="text"          type="textTypeWithAttributes"/>
  </xs:choice>
  <xs:attributeGroup ref="verbAttributes"/>
 </xs:complexType>

 <!-- verb that admits a po as objects -->
 <xs:complexType name="toPOVerb">
  <xs:choice minOccurs="1" maxOccurs="unbounded" >
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="person"       type="poTypeWithAttributes"/>
   <xs:element name="organization" type="poTypeWithAttributes"/>
  </xs:choice>
  <xs:attributeGroup ref="verbAttributes"/>
 </xs:complexType>

 <!-- verb that admits a text or collection as objects -->
 <xs:complexType name="toTextOrCollectionVerb">
  <xs:choice minOccurs="1" maxOccurs="unbounded">
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="text"          type="textTypeWithAttributes"/>
   <xs:element name="collection"    type="collectionTypeWithAttributes"/>
  </xs:choice>
  <xs:attributeGroup ref="verbAttributes"/>
 </xs:complexType>

 <!-- verb that admits a collection as object -->
 <xs:complexType name="toCollectionVerb">
  <xs:choice minOccurs="1" maxOccurs="unbounded" >
   <xs:any namespace="##other" processContents="strict"/>
   <xs:element name="collection" type="collectionTypeWithAttributes"/>
  </xs:choice>
  <xs:attributeGroup ref="verbAttributes"/>
 </xs:complexType>

 <!-- types that are used in more than one instance above -->
 <!-- attributes that apply to all nouns. recall that
  we would like have restrictions here that 
  we can not implement --> 
 <xs:attributeGroup name="nounAttributes">
  <xs:attribute name="id"  type="xs:anyURI"/> 
  <xs:attribute name="ref" type="xs:anyURI"/>
 </xs:attributeGroup> 

 <!-- verb attributes --> 
 <xs:attributeGroup name="verbAttributes">
   <xs:attribute name="from"  use="optional" type="simpleW3CDateTime"/>
   <xs:attribute name="until" use="optional" type="simpleW3CDateTime"/>
 </xs:attributeGroup> 

 <!-- URL is a restriction on URI so we should implement this, must look up pattern-->
 <xs:simpleType name="urlType">
  <xs:restriction base="xs:anyURI">
  </xs:restriction>
 </xs:simpleType>
  
 <!-- sloppy date is either a date, a month, or a year -->
 <xs:simpleType name="simpleW3CDateTime">
  <xs:union memberTypes="xs:gYear xs:gYearMonth xs:date xs:dateTime"/>
 </xs:simpleType>

 <!-- sloppy date is either a date, a month, or a year -->
 <xs:complexType name="complexW3CDateTime">
  <xs:simpleContent>
   <xs:extension base="simpleW3CDateTime">
    <xs:attribute name="event">
     <xs:simpleType>
      <xs:restriction base="xs:string">
       <xs:enumeration value="created"/>
       <xs:enumeration value="modified"/>
       <xs:enumeration value="available"/>
       <xs:enumeration value="issued"/>
      </xs:restriction>   
     </xs:simpleType>
    </xs:attribute>
   </xs:extension>
  </xs:simpleContent>
 </xs:complexType>

 <xs:simpleType name="emailType">
  <xs:restriction base="xs:string">
   <xs:pattern value="[\p{L}_]+(\.[\p{L}_]+)*@[\p{L}_]+(\.[\p{L}_]+)+"/>
  </xs:restriction>
 </xs:simpleType>

</xs:schema>




