<xs:schema targetNamespace="http://amf.openlib.org"
           xmlns="http://amf.openlib.org"
           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-08-20
   Simeon Warner (simeon@cs.cornell.edu) - 2002-08-05
   Comment welcome!
  </xs:documentation>
 </xs:annotation>


  <xs:include schemaLocation="http://amf.openlib.org/2001/mime-types.xsd"/>
  <xs:include schemaLocation="http://amf.openlib.org/2001/1991jel.xsd"/>

 <!-- 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="stringType"/> <!--vCard:FN-->  
   <xs:element name="shortname"      type="stringType"/> <!--vCard:N;NickName-->
   <xs:element name="familyname"     type="stringType"/> <!--vCard:N;FamilyName-->
   <xs:element name="givenname"      type="stringType"/> <!--vCard:N;GivenName-->
   <xs:element name="additionalname" type="stringType"/> <!--vCard:N;AdditionalName-->
   <xs:element name="nameprefix"     type="stringType"/> <!--vCard:N;HonoraryPrefix-->
   <xs:element name="namesuffix"     type="stringType"/> <!--vCard:N;HonorarySuffix-->
   <xs:element name="date"           type="complexSloppyDateType"/>	 <!--dc:date-->
   <xs:element name="homepage"       type="urlType"/>
   <xs:element name="postal"         type="stringType"/> <!--vCard:LABEL-->
   <xs:element name="phone"          type="stringType"/> <!--vCard:TEL;TYPE=pref,voice-->
   <xs:element name="fax"            type="stringType"/> <!--vCard:TEL;TYPE=pref,fax-->
   <xs:element name="email"          type="stringType"/> <!--vCard:EMAIL;TYPE=internet,pref-->
   <xs:element name="identifier"     type="identifierType"/>
   <!--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="stringType"/> <!--dc:title-->
   <xs:element name="abstract"       type="stringType"/> <!--dc:description-->
   <xs:element name="keywords"       type="schemedType"/> <!--dc:description-->
   <xs:element name="classification" type="xs:string"/> <!--dc:description-->
   <xs:element name="copyright"      type="stringType"/> <!--dc:rights-->
   <xs:element name="status"         type="stringType"/>
   <xs:element name="comment"        type="stringType"/>
   <xs:element name="email"          type="stringType"/>
   <xs:element name="date"           type="complexSloppyDateType"/>
   <xs:element name="displaypage"    type="urlType"/>
   <xs:element name="citation"       type="stringType"/>
   <xs:element name="serial">
    <xs:complexType>
     <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:any namespace="##other" processContents="strict"/>
      <xs:element name="journaltitle"            type="stringType"/> <!--OpenURL:title FIXME-name-->
      <xs:element name="journalabbreviatedtitle" type="stringType"/> <!--OpenURL:stitle FIXME-name-->
      <xs:element name="issuedate"         type="simpleSloppyDateType"/> <!--OpenURL:date FIXME-name-->
      <xs:element name="volume"            type="stringType"/> <!--OpenURL:volume-->
      <xs:element name="part"              type="stringType"/> <!--OpenURL:part-->
      <xs:element name="issue"             type="stringType"/> <!--OpenURL:issue-->
      <xs:element name="season"            type="stringType"/> <!--OpenURL:ssn  FIXME-type,name-->
      <xs:element name="quarter"           type="stringType"/> <!--OpenURL:quarter FIXME-type-->
      <xs:element name="startpage"         type="stringType"/> <!--OpenURL:spage FIXME-name,type-->
      <xs:element name="endpage"           type="stringType"/> <!--OpenURL:epage FIXME-name,type-->
      <xs:element name="articlenumber"     type="stringType"/> <!--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="stringType"/>
      <xs:element name="format"      type="mimeType"/>	 <!--dc:format-->
      <xs:element name="restriction" type="stringType"/> <!--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="stringType"/>
      <xs:element name="context" type="stringType"/>
     </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="identifierType"/> <!--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="stringType"/>
   <xs:element name="description" type="stringType"/> <!--dc:description-->
   <xs:element name="shortitle"   type="stringType"/> <!-- 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="identifierType"/> <!--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> 

 <!-- simply stringType extended with attributes available for all selements-->
 <xs:complexType name="stringType">
  <xs:simpleContent>
   <xs:extension base="xs:string">
   <xs:attribute name="lang" use="optional" type="xs:language"/>
   </xs:extension>
  </xs:simpleContent>
 </xs:complexType>

 <!-- verb attributes --> 
 <xs:attributeGroup name="verbAttributes">
   <xs:attribute name="from"  use="optional" type="simpleSloppyDateType"/>
   <xs:attribute name="until" use="optional" type="simpleSloppyDateType"/>
 </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="simpleSloppyDateType">
  <xs:union memberTypes="xs:date xs:gYear xs:gYearMonth"/>
 </xs:simpleType>

 <!-- sloppy date is either a date, a month, or a year -->
 <xs:complexType name="complexSloppyDateType">
  <xs:simpleContent>
   <xs:extension base="simpleSloppyDateType">
    <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:simpleType name="classType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="jel1991"/>
  </xs:restriction>
 </xs:simpleType>

 <xs:complexType name="identifierType">
  <xs:simpleContent>
   <xs:extension base="xs:anyURI">
    <xs:attribute name="scheme"/>
   </xs:extension>
  </xs:simpleContent>
 </xs:complexType>

 <xs:complexType name="schemedType">
  <xs:simpleContent>
   <xs:extension base="xs:string">
    <xs:attribute name="scheme"/>
   </xs:extension>
  </xs:simpleContent>
 </xs:complexType>

 
</xs:schema>




