From 2dfca455423a7c72a024e1f94c586397d07a792d Mon Sep 17 00:00:00 2001
From: pbarroca <pbarroca@git-test.afi-sa.fr>
Date: Mon, 7 May 2012 13:28:54 +0000
Subject: [PATCH] =?UTF-8?q?Validation=20des=20r=C3=A9ponses=20OAI=20avec?=
 =?UTF-8?q?=20leur=20XSD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitattributes                                |   3 +
 .../opac/views/scripts/oai/identify.xml.phtml |   4 +-
 library/Class/Xml/Oai/DublinCoreBuilder.php   |   6 +-
 .../modules/opac/controllers/OAI-PMH.xsd      | 317 ++++++++++++++++++
 .../controllers/OAIControllerIdentifyTest.php |   8 +
 .../OAIControllerListIdentifiersTest.php      |   8 +
 .../OAIControllerListMetadataFormatsTest.php  |   8 +
 .../controllers/OAIControllerListSetsTest.php |   1 +
 .../Class/Notice/DublinCoreVisitorTest.php    |   8 +
 tests/library/Class/Notice/oai_dc.xsd         |  42 +++
 .../library/Class/Notice/simpledc20021212.xsd |  78 +++++
 11 files changed, 479 insertions(+), 4 deletions(-)
 create mode 100644 tests/application/modules/opac/controllers/OAI-PMH.xsd
 create mode 100644 tests/library/Class/Notice/oai_dc.xsd
 create mode 100644 tests/library/Class/Notice/simpledc20021212.xsd

diff --git a/.gitattributes b/.gitattributes
index 560bcd7d890..e3521e58c11 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3437,6 +3437,7 @@ tests/application/modules/opac/controllers/CmsControllerTest.php -text
 tests/application/modules/opac/controllers/FormulaireContactTest.php -text
 tests/application/modules/opac/controllers/IndexControllerTranslationTest.php -text
 tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php -text
+tests/application/modules/opac/controllers/OAI-PMH.xsd -text
 tests/application/modules/opac/controllers/OAIControllerGetRecordTest.php -text
 tests/application/modules/opac/controllers/OAIControllerIdentifyTest.php -text
 tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php -text
@@ -3499,6 +3500,8 @@ tests/library/Class/NewsletterMailingTest.php -text
 tests/library/Class/NewsletterSubscriptionTest.php -text
 tests/library/Class/NewsletterTest.php -text
 tests/library/Class/Notice/DublinCoreVisitorTest.php -text
+tests/library/Class/Notice/oai_dc.xsd -text
+tests/library/Class/Notice/simpledc20021212.xsd -text
 tests/library/Class/NoticeHtmlTest.php -text
 tests/library/Class/NoticeOAITest.php -text
 tests/library/Class/NoticeTest.php -text
diff --git a/application/modules/opac/views/scripts/oai/identify.xml.phtml b/application/modules/opac/views/scripts/oai/identify.xml.phtml
index 4978c923ce2..1182c0f5a52 100644
--- a/application/modules/opac/views/scripts/oai/identify.xml.phtml
+++ b/application/modules/opac/views/scripts/oai/identify.xml.phtml
@@ -8,9 +8,9 @@
 		<repositoryName><![CDATA[<?php echo $this->repositoryName;?>]]></repositoryName>
 		<baseURL><?php echo $this->baseUrl; ?></baseURL>
 		<protocolVersion>2.0</protocolVersion>
+    <adminEmail><![CDATA[<?php echo $this->adminEmail;?>]]></adminEmail>
 		<earliestDatestamp><?php echo $this->earliestDatestamp; ?></earliestDatestamp>
-    <granularity>YYYY-MM-DD</granularity>
     <deletedRecord>no</deletedRecord>
-    <adminEmail><![CDATA[<?php echo $this->adminEmail;?>]]></adminEmail>
+    <granularity>YYYY-MM-DD</granularity>
 	</Identify>
 </OAI-PMH>
\ No newline at end of file
diff --git a/library/Class/Xml/Oai/DublinCoreBuilder.php b/library/Class/Xml/Oai/DublinCoreBuilder.php
index 0665eacba5b..3ad1b837ddf 100644
--- a/library/Class/Xml/Oai/DublinCoreBuilder.php
+++ b/library/Class/Xml/Oai/DublinCoreBuilder.php
@@ -23,8 +23,10 @@ class Class_Xml_Oai_DublinCoreBuilder extends Class_Xml_Builder {
 	public function oai_dc($content) {
 		return parent::_xmlString('oai_dc:dc', 
 															$content, 
-															$this->attributesToString(array('xmlns:oai_dc' => 'http://www.openarchives.org/OAI/2.0/oai_dc/',
-																															'xmlns:dc' => 'http://purl.org/dc/elements/1.1')));
+															$this->attributesToString(array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/',
+																															'xmlns:oai_dc' => 'http://www.openarchives.org/OAI/2.0/oai_dc/',
+																															'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+																															'xsi:schemaLocation' => 'http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd')));
 	}
 
 
diff --git a/tests/application/modules/opac/controllers/OAI-PMH.xsd b/tests/application/modules/opac/controllers/OAI-PMH.xsd
new file mode 100644
index 00000000000..3fce3b59db4
--- /dev/null
+++ b/tests/application/modules/opac/controllers/OAI-PMH.xsd
@@ -0,0 +1,317 @@
+<schema targetNamespace="http://www.openarchives.org/OAI/2.0/"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        xmlns:oai="http://www.openarchives.org/OAI/2.0/"
+        elementFormDefault="qualified"
+        attributeFormDefault="unqualified">
+
+  <annotation>
+    <documentation>
+    XML Schema which can be used to validate replies to all OAI-PMH 
+    v2.0 requests. Herbert Van de Sompel, 2002-05-13.
+    Validated with XML Spy v.4.3 on 2002-05-13.
+    Validated with XSV 1.203.2.45/1.106.2.22 on 2002-05-13.
+    Added definition of protocolVersionType instead of using anonymous 
+    type. No change of function. Simeon Warner, 2004-03-29.
+    Tightened definition of UTCdatetimeType to enforce the restriction 
+    to UTC Z notation. Simeon Warner, 2004-09-14.
+    Corrected pattern matches for setSpecType and metadataPrefixType
+    to agree with protocol specification. Simeon Warner, 2004-10-12.
+    Spelling correction. Simeon Warner, 2008-12-07.
+    $Date: 2004/10/12 15:20:29 $
+    </documentation>
+  </annotation>
+
+  <element name="OAI-PMH" type="oai:OAI-PMHtype"/>
+
+  <complexType name="OAI-PMHtype">
+    <sequence>
+      <element name="responseDate" type="dateTime"/>
+      <element name="request" type="oai:requestType"/>
+      <choice>
+        <element name="error" type="oai:OAI-PMHerrorType" maxOccurs="unbounded"/>
+        <element name="Identify" type="oai:IdentifyType"/>
+        <element name="ListMetadataFormats" type="oai:ListMetadataFormatsType"/>
+        <element name="ListSets" type="oai:ListSetsType"/>
+        <element name="GetRecord" type="oai:GetRecordType"/>
+        <element name="ListIdentifiers" type="oai:ListIdentifiersType"/>
+        <element name="ListRecords" type="oai:ListRecordsType"/>
+      </choice>
+    </sequence>
+  </complexType>
+
+  <complexType name="requestType">
+    <annotation>
+      <documentation>Define requestType, indicating the protocol request that 
+      led to the response. Element content is BASE-URL, attributes are arguments 
+      of protocol request, attribute-values are values of arguments of protocol 
+      request</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="anyURI">
+        <attribute name="verb" type="oai:verbType" use="optional"/>
+        <attribute name="identifier" type="oai:identifierType" use="optional"/>
+        <attribute name="metadataPrefix" type="oai:metadataPrefixType" use="optional"/>
+        <attribute name="from" type="oai:UTCdatetimeType" use="optional"/>
+        <attribute name="until" type="oai:UTCdatetimeType" use="optional"/>
+        <attribute name="set" type="oai:setSpecType" use="optional"/>
+        <attribute name="resumptionToken" type="string" use="optional"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+
+  <simpleType name="verbType">
+    <restriction base="string">
+      <enumeration value="Identify"/>
+      <enumeration value="ListMetadataFormats"/>
+      <enumeration value="ListSets"/>
+      <enumeration value="GetRecord"/>
+      <enumeration value="ListIdentifiers"/>
+      <enumeration value="ListRecords"/>
+    </restriction>
+  </simpleType>
+
+  <!-- define OAI-PMH error conditions -->
+  <!-- =============================== -->
+
+  <complexType name="OAI-PMHerrorType">
+    <simpleContent>
+      <extension base="string">
+        <attribute name="code" type="oai:OAI-PMHerrorcodeType" use="required"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+
+  <simpleType name="OAI-PMHerrorcodeType">
+    <restriction base="string">
+      <enumeration value="cannotDisseminateFormat"/>
+      <enumeration value="idDoesNotExist"/>
+      <enumeration value="badArgument"/>
+      <enumeration value="badVerb"/>
+      <enumeration value="noMetadataFormats"/>
+      <enumeration value="noRecordsMatch"/>
+      <enumeration value="badResumptionToken"/>
+      <enumeration value="noSetHierarchy"/>
+    </restriction>
+  </simpleType>
+
+  <!-- define OAI-PMH verb containers -->
+  <!-- ============================== -->
+
+  <complexType name="IdentifyType">
+    <sequence>
+      <element name="repositoryName" type="string"/>
+      <element name="baseURL" type="anyURI"/>
+      <element name="protocolVersion" type="oai:protocolVersionType"/>
+      <element name="adminEmail" type="oai:emailType" maxOccurs="unbounded"/>
+      <element name="earliestDatestamp" type="oai:UTCdatetimeType"/>
+      <element name="deletedRecord" type="oai:deletedRecordType"/>
+      <element name="granularity" type="oai:granularityType"/>
+      <element name="compression" type="string" minOccurs="0" maxOccurs="unbounded"/>
+      <element name="description" type="oai:descriptionType" 
+               minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="ListMetadataFormatsType">
+    <sequence>
+      <element name="metadataFormat" type="oai:metadataFormatType" maxOccurs="unbounded"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="ListSetsType">
+    <sequence>
+      <element name="set" type="oai:setType" maxOccurs="unbounded"/>
+      <element name="resumptionToken" type="oai:resumptionTokenType" minOccurs="0"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="GetRecordType">
+    <sequence>
+      <element name="record" type="oai:recordType"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="ListRecordsType">
+    <sequence>
+      <element name="record" type="oai:recordType" maxOccurs="unbounded"/>
+      <element name="resumptionToken" type="oai:resumptionTokenType" minOccurs="0"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="ListIdentifiersType">
+    <sequence>
+      <element name="header" type="oai:headerType" maxOccurs="unbounded"/>
+      <element name="resumptionToken" type="oai:resumptionTokenType" minOccurs="0"/>
+    </sequence>
+  </complexType>
+
+  <!-- define basic types used in replies to 
+       GetRecord, ListRecords, ListIdentifiers -->
+  <!-- ======================================= -->
+
+  <complexType name="recordType">
+    <annotation>
+      <documentation>A record has a header, a metadata part, and
+        an optional about container</documentation>
+    </annotation>
+    <sequence>
+      <element name="header" type="oai:headerType"/>
+      <element name="metadata" type="oai:metadataType" minOccurs="0"/>
+      <element name="about" type="oai:aboutType" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="headerType">
+    <annotation>
+      <documentation>A header has a unique identifier, a datestamp,
+        and setSpec(s) in case the item from which
+        the record is disseminated belongs to set(s).
+        the header can carry a deleted status indicating
+        that the record is deleted.</documentation>
+    </annotation>
+    <sequence>
+      <element name="identifier" type="oai:identifierType"/>
+      <element name="datestamp" type="oai:UTCdatetimeType"/>
+      <element name="setSpec" type="oai:setSpecType" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="status" type="oai:statusType" use="optional"/>
+  </complexType>
+
+  <simpleType name="identifierType">
+    <restriction base="anyURI"/>
+  </simpleType>
+
+  <simpleType name="statusType">
+    <restriction base="string">
+      <enumeration value="deleted"/>
+    </restriction>
+  </simpleType>
+
+  <complexType name="metadataType">
+    <annotation>
+      <documentation>Metadata must be expressed in XML that complies
+       with another XML Schema (namespace=#other). Metadata must be 
+       explicitly qualified in the response.</documentation>
+    </annotation>
+    <sequence>
+      <any namespace="##other" processContents="strict"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="aboutType">
+    <annotation>
+      <documentation>Data "about" the record must be expressed in XML
+      that is compliant with an XML Schema defined by a community.</documentation>
+    </annotation>
+    <sequence>
+      <any namespace="##other" processContents="strict"/>
+    </sequence>
+  </complexType>
+
+  <complexType name="resumptionTokenType">
+    <annotation>
+      <documentation>A resumptionToken may have 3 optional attributes
+       and can be used in ListSets, ListIdentifiers, ListRecords
+       responses.</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="string">
+        <attribute name="expirationDate" type="dateTime" use="optional"/>
+        <attribute name="completeListSize" type="positiveInteger" use="optional"/>
+        <attribute name="cursor" type="nonNegativeInteger" use="optional"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+
+  <complexType name="descriptionType">
+    <annotation>
+      <documentation>The descriptionType is used for the description
+      element in Identify and for setDescription element in ListSets.
+      Content must be compliant with an XML Schema defined by a 
+      community.</documentation>
+    </annotation>
+    <sequence>
+      <any namespace="##other" processContents="strict"/>
+    </sequence>
+  </complexType>
+
+  <simpleType name="UTCdatetimeType">
+    <annotation>
+      <documentation>Datestamps are to either day (type date)
+      or to seconds granularity (type oai:UTCdateTimeZType)</documentation>
+    </annotation>
+    <union memberTypes="date oai:UTCdateTimeZType"/>
+  </simpleType>
+
+  <simpleType name="UTCdateTimeZType">
+    <restriction base="dateTime">
+      <pattern value=".*Z"/>
+    </restriction>
+  </simpleType>
+
+  <!-- define types used for Identify verb only -->
+  <!-- ======================================== -->
+
+  <simpleType name="protocolVersionType">
+    <restriction base="string">
+      <enumeration value="2.0"/>
+    </restriction>
+  </simpleType>
+
+  <simpleType name="emailType">
+    <restriction base="string">
+      <pattern value="\S+@(\S+\.)+\S+"/>
+    </restriction>
+  </simpleType>
+
+  <simpleType name="deletedRecordType">
+    <restriction base="string">
+      <enumeration value="no"/>
+      <enumeration value="persistent"/>
+      <enumeration value="transient"/>
+    </restriction>
+  </simpleType>
+
+  <simpleType name="granularityType">
+    <restriction base="string">
+      <enumeration value="YYYY-MM-DD"/>
+      <enumeration value="YYYY-MM-DDThh:mm:ssZ"/>
+    </restriction>
+  </simpleType>
+
+  <!-- define types used for ListMetadataFormats verb only -->
+  <!-- =================================================== -->
+
+  <complexType name="metadataFormatType">
+    <sequence>
+      <element name="metadataPrefix" type="oai:metadataPrefixType"/>
+      <element name="schema" type="anyURI"/>
+      <element name="metadataNamespace" type="anyURI"/>
+    </sequence>
+  </complexType>
+
+  <simpleType name="metadataPrefixType">
+    <restriction base="string">
+      <pattern value="[A-Za-z0-9\-_\.!~\*'\(\)]+"/>
+    </restriction>
+  </simpleType>
+
+  <!-- define types used for ListSets verb -->
+  <!-- =================================== -->
+
+  <complexType name="setType">
+    <sequence>
+      <element name="setSpec" type="oai:setSpecType"/>
+      <element name="setName" type="string"/>
+      <element name="setDescription" type="oai:descriptionType" 
+               minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+  </complexType>
+
+  <simpleType name="setSpecType">
+    <restriction base="string">
+      <pattern value="([A-Za-z0-9\-_\.!~\*'\(\)])+(:[A-Za-z0-9\-_\.!~\*'\(\)]+)*"/>
+    </restriction>
+  </simpleType>
+
+</schema>
diff --git a/tests/application/modules/opac/controllers/OAIControllerIdentifyTest.php b/tests/application/modules/opac/controllers/OAIControllerIdentifyTest.php
index 7d1d2a61ebd..e582df18427 100644
--- a/tests/application/modules/opac/controllers/OAIControllerIdentifyTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerIdentifyTest.php
@@ -53,6 +53,14 @@ class OAIControllerIdentifyTest extends AbstractControllerTestCase {
 	}
 
 
+	/** @test */
+	public function xmlShouldBeValid() {
+		$dom = new DOMDocument();
+		$dom->loadXml($this->_response->getBody());
+		$dom->schemaValidate('tests/application/modules/opac/controllers/OAI-PMH.xsd');
+	}
+
+
 	/** @test */
 	public function responseDateShouldBeNow() {
 		$this->_xpath->assertXPathContentContains($this->_response->getBody(),
diff --git a/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php b/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
index 2a5fb78690d..6353c83f36a 100644
--- a/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
@@ -64,6 +64,14 @@ class OAIControllerListIdentifiersValidTest extends AbstractControllerTestCase {
 	}
 
 
+	/** @test */
+	public function xmlShouldBeValid() {
+		$dom = new DOMDocument();
+		$dom->loadXml($this->_response->getBody());
+		$dom->schemaValidate('tests/application/modules/opac/controllers/OAI-PMH.xsd');
+	}
+
+
 	/** @test */
 	public function requestVerbShouldBeListIdentifiers() {
 		$this->_xpath->assertXPath($this->_xml,
diff --git a/tests/application/modules/opac/controllers/OAIControllerListMetadataFormatsTest.php b/tests/application/modules/opac/controllers/OAIControllerListMetadataFormatsTest.php
index 90c2e4e6e12..f85389ec16c 100644
--- a/tests/application/modules/opac/controllers/OAIControllerListMetadataFormatsTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerListMetadataFormatsTest.php
@@ -30,6 +30,14 @@ class OAIControllerListMetadataFormatsTest extends AbstractControllerTestCase {
 	}
 
 
+	/** @test */
+	public function xmlShouldBeValid() {
+		$dom = new DOMDocument();
+		$dom->loadXml($this->_response->getBody());
+		$dom->schemaValidate('tests/application/modules/opac/controllers/OAI-PMH.xsd');
+	}
+
+
 	/** @test */
 	public function requestVerbShouldBeListMetadataFormats() {
 		$this->_xpath->assertXPath($this->_response->getBody(),
diff --git a/tests/application/modules/opac/controllers/OAIControllerListSetsTest.php b/tests/application/modules/opac/controllers/OAIControllerListSetsTest.php
index ecfbbf8109f..cf1f910269b 100644
--- a/tests/application/modules/opac/controllers/OAIControllerListSetsTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerListSetsTest.php
@@ -47,6 +47,7 @@ class OAIControllerListSetsTest extends AbstractControllerTestCase {
 	}
 
 
+
 	/** @test */
 	public function setMusiqueShouldContainSpecMusic() {
 		$this->_xpath->assertXpathContentContains($this->_response->getBody(),
diff --git a/tests/library/Class/Notice/DublinCoreVisitorTest.php b/tests/library/Class/Notice/DublinCoreVisitorTest.php
index c5d1a0ea134..80926d18bf4 100644
--- a/tests/library/Class/Notice/DublinCoreVisitorTest.php
+++ b/tests/library/Class/Notice/DublinCoreVisitorTest.php
@@ -50,6 +50,14 @@ class DublinCoreVisitorPotterTest extends DublinCoreVisitorTestCase {
 	}
 
 
+	/** @test */
+	public function xmlShouldBeValid() {
+		$dom = new DOMDocument();
+		$dom->loadXml($this->_dublin_core_visitor->xml());
+		$dom->schemaValidate('tests/library/Class/Notice/oai_dc.xsd');
+	}
+
+
 	/** @test */
 	public function identifierShouldBeHarryPotterSorciers() {
 		$this->_xpath->assertXPathContentContains($this->_dublin_core_visitor->xml(),
diff --git a/tests/library/Class/Notice/oai_dc.xsd b/tests/library/Class/Notice/oai_dc.xsd
new file mode 100644
index 00000000000..0070f0e0f44
--- /dev/null
+++ b/tests/library/Class/Notice/oai_dc.xsd
@@ -0,0 +1,42 @@
+<schema targetNamespace="http://www.openarchives.org/OAI/2.0/oai_dc/" 
+        xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" 
+        xmlns:dc="http://purl.org/dc/elements/1.1/" 
+        xmlns="http://www.w3.org/2001/XMLSchema" 
+        elementFormDefault="qualified" attributeFormDefault="unqualified">
+	
+<annotation>
+  <documentation> 
+      XML Schema 2002-03-18 by Pete Johnston.
+      Adjusted for usage in the OAI-PMH.
+      Schema imports the Dublin Core elements from the DCMI schema for unqualified Dublin Core.
+      2002-12-19 updated to use simpledc20021212.xsd (instead of simpledc20020312.xsd)
+  </documentation>
+</annotation>
+
+<import namespace="http://purl.org/dc/elements/1.1/" 
+        schemaLocation="http://dublincore.org/schemas/xmls/simpledc20021212.xsd"/>
+	
+<element name="dc" type="oai_dc:oai_dcType"/>
+
+<complexType name="oai_dcType">
+  <choice minOccurs="0" maxOccurs="unbounded">
+    <element ref="dc:title"/>
+    <element ref="dc:creator"/>
+    <element ref="dc:subject"/>
+    <element ref="dc:description"/>
+    <element ref="dc:publisher"/>
+    <element ref="dc:contributor"/>
+    <element ref="dc:date"/>
+    <element ref="dc:type"/>
+    <element ref="dc:format"/>
+    <element ref="dc:identifier"/>
+    <element ref="dc:source"/>
+    <element ref="dc:language"/>
+    <element ref="dc:relation"/>
+    <element ref="dc:coverage"/>
+    <element ref="dc:rights"/>
+  </choice>
+</complexType>
+
+</schema>
+
diff --git a/tests/library/Class/Notice/simpledc20021212.xsd b/tests/library/Class/Notice/simpledc20021212.xsd
new file mode 100644
index 00000000000..bea04f8ec5e
--- /dev/null
+++ b/tests/library/Class/Notice/simpledc20021212.xsd
@@ -0,0 +1,78 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns="http://purl.org/dc/elements/1.1/"
+           targetNamespace="http://purl.org/dc/elements/1.1/"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified">
+
+  <xs:annotation>
+    <xs:documentation xml:lang="en">
+      Simple DC XML Schema, 2002-10-09
+      by Pete Johnston (p.johnston@ukoln.ac.uk),
+      Carl Lagoze (lagoze@cs.cornell.edu), Andy Powell (a.powell@ukoln.ac.uk),
+      Herbert Van de Sompel (hvdsomp@yahoo.com).
+      This schema defines terms for Simple Dublin Core, i.e. the 15
+      elements from the http://purl.org/dc/elements/1.1/ namespace, with
+      no use of encoding schemes or element refinements.
+      Default content type for all elements is xs:string with xml:lang
+      attribute available.
+
+      Supercedes version of 2002-03-12. 
+      Amended to remove namespace declaration for http://www.w3.org/XML/1998/namespace namespace,
+      and to reference lang attribute via built-in xml: namespace prefix.
+      xs:appinfo also removed.
+    </xs:documentation>
+  </xs:annotation>
+
+  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+             schemaLocation="http://www.w3.org/2001/03/xml.xsd">
+  </xs:import>
+
+  <xs:element name="title" type="elementType"/>
+  <xs:element name="creator" type="elementType"/>
+  <xs:element name="subject" type="elementType"/>
+  <xs:element name="description" type="elementType"/>
+  <xs:element name="publisher" type="elementType"/>
+  <xs:element name="contributor" type="elementType"/>
+  <xs:element name="date" type="elementType"/>
+  <xs:element name="type" type="elementType"/>
+  <xs:element name="format" type="elementType"/>
+  <xs:element name="identifier" type="elementType"/>
+  <xs:element name="source" type="elementType"/>
+  <xs:element name="language" type="elementType"/>
+  <xs:element name="relation" type="elementType"/>
+  <xs:element name="coverage" type="elementType"/>
+  <xs:element name="rights" type="elementType"/>
+
+  <xs:group name="elementsGroup">
+  <xs:sequence>
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element ref="title"/>
+      <xs:element ref="creator"/>
+      <xs:element ref="subject"/>
+      <xs:element ref="description"/>
+      <xs:element ref="publisher"/>
+      <xs:element ref="contributor"/>
+      <xs:element ref="date"/>
+      <xs:element ref="type"/>
+      <xs:element ref="format"/>
+      <xs:element ref="identifier"/>
+      <xs:element ref="source"/>
+      <xs:element ref="language"/>
+      <xs:element ref="relation"/>
+      <xs:element ref="coverage"/>
+      <xs:element ref="rights"/>
+    </xs:choice>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:complexType name="elementType">
+    <xs:simpleContent>
+      <xs:extension base="xs:string">
+        <xs:attribute ref="xml:lang" use="optional"/>
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+</xs:schema>
+
+
-- 
GitLab