<?xml version="1.0" encoding="UTF-8"?>
<!--

  This stylesheet converts data in the MARC-XML format (see
  http://www.loc.gov/marc/marcxml.html) to the Dublin Core Qualified
  format (see http://www.dublincore.org/). The translations performs
  as specified by http://www.loc.gov/marc/marc2dc.html.

  Note that http://www.loc.gov/marc/marc2dc.html does not specify
  translations for all datafield codes and only translates data for
  some subfields in other datafield codes, so the resulting document
  will not contain all information from the orginal MARC data.

-->
<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:qdc="http://cicharvest.grainger.uiuc.edu/schemas/qdc/2004/07/14/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
  <xsl:import href="GeneralMARCtoQDCutils.xsl"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xsl:if test="marc:collection">
      <qdc:dcCollection xsi:schemaLocation="http://cicharvest.grainger.uiuc.edu/schemas/qdc/2004/07/14/cicqualifieddc.xsd">
	<xsl:for-each select="marc:collection">
	  <xsl:for-each select="marc:record">
	    <qdc:dc>
	      <xsl:apply-templates select="."/>
	    </qdc:dc>
	  </xsl:for-each>
	</xsl:for-each>
      </qdc:dcCollection>
    </xsl:if>

    <xsl:if test="marc:record">
      <qdc:qualifieddc xsi:schemaLocation="http://cicharvest.grainger.uiuc.edu/schemas/qdc/2004/07/14/cicqualifieddc.xsd">
	<xsl:apply-templates/>
      </qdc:qualifieddc>
    </xsl:if>
  </xsl:template>
  
  <xsl:template match="marc:record">
    <xsl:variable name="leader" select="marc:leader"/>
    <xsl:variable name="leader6" select="substring($leader,7,1)"/>
    <xsl:variable name="leader7" select="substring($leader,8,1)"/>
    <xsl:variable name="controlField008" select="marc:controlfield[@tag=008]"/>
    
    <xsl:for-each select="marc:datafield[@tag=245]">
      <dc:title>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">abfghknp</xsl:with-param>
	</xsl:call-template>
      </dc:title>
    </xsl:for-each>

    <!-- find alternative representations of the title -->
    <xsl:for-each select="marc:datafield[@tag=130]|marc:datafield[@tag=210]|marc:datafield[@tag=240]|marc:datafield[@tag=242]|marc:datafield[@tag=246]|marc:datafield[@tag=730]|marc:datafield[@tag=740]">
      <dcterms:alternative>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">
	    <xsl:choose>
	      <xsl:when test="@tag=130 or @tag=240 or @tag=246">adfghklmnoprst</xsl:when>
	      <xsl:when test="@tag=210">ab</xsl:when>
	      <xsl:when test="@tag=242 or @tag=730">abcdfghklmnoprst</xsl:when>
	      <xsl:when test="@tag=740">ahnp</xsl:when>
	    </xsl:choose>
	  </xsl:with-param>
	</xsl:call-template>
      </dcterms:alternative>
    </xsl:for-each>
    
    <!-- generate creator tags; see http://www.loc.gov/marc/marc2dc.html for
         information on why these are creator tags and not contributor tags -->
    <xsl:for-each select="marc:datafield[@tag=100]|marc:datafield[@tag=110]|marc:datafield[@tag=111]|marc:datafield[@tag=700]|marc:datafield[@tag=710]|marc:datafield[@tag=711]|marc:datafield[@tag=720]">
      <dc:creator>
	<xsl:value-of select="."/>
      </dc:creator>
    </xsl:for-each>
    
    <!-- generate subject tags -->
    <!-- using 655 here overlaps with handling
         of 655 later in the stylesheet -->
    <xsl:for-each select="marc:datafield[@tag=600]|marc:datafield[@tag=610]|marc:datafield[@tag=611]|marc:datafield[@tag=630]|marc:datafield[@tag=650]|marc:datafield[@tag=651]|marc:datafield[@tag=653]|marc:datafield[@tag=654]|marc:datafield[@tag=655]|marc:datafield[@tag=656]|marc:datafield[@tag=657]|marc:datafield[@tag=658]">
      <dc:subject>
	<!-- the <xsl:attribute> tag goes inside the when clause because in
             some cases we will not add the type attribute -->
	<xsl:choose>
	  <xsl:when test="@ind2=0">
	    <xsl:attribute name="xsi:type">dcterms:LCSH</xsl:attribute>
	  </xsl:when>
	  <xsl:when test="@ind2=2">
	    <xsl:attribute name="xsi:type">dcterms:MESH</xsl:attribute>
	  </xsl:when>
	</xsl:choose>
	
	<!-- now populate the value of the tag -->
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">abcdqvxyz</xsl:with-param>
	</xsl:call-template>
      </dc:subject>
    </xsl:for-each>

    <!-- generate subject tag for Library of Congress catalog number -->
    <xsl:for-each select="marc:datafield[@tag=050]">
      <dc:subject xsi:type="dcterms:LCC">
	<xsl:value-of select="."/>
      </dc:subject>
    </xsl:for-each>
    
    <!-- generate subject tag for Dewey Decimal catalog number -->
    <xsl:for-each select="marc:datafield[@tag=082]">
      <dc:subject xsi:type="dcterms:DDC">
	<xsl:value-of select="."/>
      </dc:subject>
    </xsl:for-each>

    <!-- generate subject tag for Universal Decimal catalog number -->
    <xsl:for-each select="marc:datafield[@tag=080]">
      <dc:subject xsi:type="dcterms:UDC">
	<xsl:value-of select="."/>
      </dc:subject>
    </xsl:for-each>

    <!-- the 500 range tags are mostly dc:description tags in the output
         with some exceptions -->
    <xsl:for-each select="marc:datafield[@tag &gt;=500 and @tag &lt;= 599]">
      <xsl:choose>
      
	<!-- the 505 tag is a table of contents entry -->
	<xsl:when test="@tag=505">
	  <dcterms:tableOfConents>
	    <xsl:value-of select="."/>
	  </dcterms:tableOfConents>
	</xsl:when>

	<!-- 506 specifies the rights to a particular item -->
	<!-- 540 specifies the rights to a particular item -->
	<xsl:when test="@tag=506 or @tag=540">
	  <xsl:call-template name="noteUriRelation">
	    <xsl:with-param name="noteSubfields">abcd3</xsl:with-param>
	    <xsl:with-param name="uriSubfields">u</xsl:with-param>
	    <xsl:with-param name="elementName">dc:rights</xsl:with-param>
	  </xsl:call-template>
	</xsl:when>
	
	<!-- 510 is a citation reference note -->
	<xsl:when test="@tag=510">
	  <dcterms:isReferencedBy>
	    <xsl:value-of select="." />
	  </dcterms:isReferencedBy>
	</xsl:when>	
    
	<!-- 513$b contains period covered note -->
	<xsl:when test="@tag=513">
	  <dcterms:temporal>
	  <xsl:value-of select="."/>
	  </dcterms:temporal>
	</xsl:when>

	<!-- the 520 field is an abstract if indicator 1 is set to 3 -->
	<xsl:when test="@tag=520 and @ind1=3">
	  <dcterms:abstract>
	    <xsl:value-of select="."/>
	  </dcterms:abstract>
	</xsl:when>
	
	<!-- 522$a is spatial coverage -->
        <xsl:when test="@tag=522">
	  <dcterms:spatial>
	    <xsl:value-of select="."/>
	  </dcterms:spatial>
	</xsl:when>

	<!-- 530 additional physical format available -->
	<xsl:when test="@tag=530">
	  <xsl:call-template name="noteUriRelation">
	    <xsl:with-param name="noteSubfields">abcd3</xsl:with-param>
	    <xsl:with-param name="uriSubfields">u</xsl:with-param>
	    <xsl:with-param name="elementName">dcterms:isFormatOf</xsl:with-param>
	  </xsl:call-template>
	  <!--
	  <xsl:call-template name="noteUriRelation">
	    <xsl:with-param name="noteSubfields">abcd3</xsl:with-param>
	    <xsl:with-param name="uriSubfields">u</xsl:with-param>
	    <xsl:with-param name="elementName">dcterms:hasFormat</xsl:with-param>
	  </xsl:call-template>
	  -->
	</xsl:when>

	<!-- 538 specifies this item requires another -->
	<xsl:when test="@tag=538">
	  <xsl:call-template name="noteUriRelation">
	    <xsl:with-param name="noteSubfields">ai3</xsl:with-param>
	    <xsl:with-param name="uriSubfields">u</xsl:with-param>
	    <xsl:with-param name="elementName">dcterms:requires</xsl:with-param>
	  </xsl:call-template>
	</xsl:when>

	<!-- http://www.loc.gov/marc/marc2dc.html claims datafield contains
	     RFC1766 language codes. That doesn't appear to genereally be
	     the case. -->
	<xsl:when test="@tag=546">
	  <dc:language>
	    <xsl:call-template name="subfieldSelect">
	      <xsl:with-param name="codes">ab3</xsl:with-param>
	    </xsl:call-template>
	  </dc:language>
	</xsl:when>
	
	<!-- 561 Custodial History -->
	<xsl:when test="@tag=561">
	  <dcterms:provenance>
	    <xsl:value-of select="."/>
	  </dcterms:provenance>
	</xsl:when>

	<!-- everything else is just a description -->
	<xsl:otherwise>
	  <dc:description>
	    <xsl:value-of select="."/>
	  </dc:description>
	</xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
    
    <!-- extract the publisher name and creation date -->
    <xsl:for-each select="marc:datafield[@tag=260]">
      <!-- publisher tag is contained in 260$a$b -->
      <xsl:variable name="publisher">
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">ab</xsl:with-param>
	</xsl:call-template>
      </xsl:variable>
      <xsl:if test="string-length($publisher) &gt; 0">
	<dc:publisher>
	<xsl:value-of select="$publisher" />
	</dc:publisher>
      </xsl:if>

      <!-- created tag is contained in 260$c$g -->
      <xsl:variable name="created">
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">cg</xsl:with-param>
	</xsl:call-template>
      </xsl:variable>
      <xsl:if test="string-length($created) &gt; 0">
	<dcterms:created>
	<xsl:value-of select="$created" />
	</dcterms:created>
      </xsl:if>

      <!-- issued tag is contained in 260$c -->
      <xsl:for-each select="marc:subfield[@code='c']">
	<dcterms:issued>
	<xsl:value-of select="." />
	</dcterms:issued>
      </xsl:for-each>
    </xsl:for-each>

    <!-- 533$d contains data for a created tag -->
    <xsl:for-each select="marc:datafield[@tag=533]/marc:subfield[@code='d']">
      <dcterms:created>
      <xsl:value-of select="."/>
      </dcterms:created>
    </xsl:for-each>

    <!-- chars 7 through 10 of controlfield 008 contain a created date -->
    <xsl:variable name="controlFieldDate">
      <xsl:value-of select="normalize-space(substring($controlField008,8,4))" />
    </xsl:variable>
    <xsl:if test="string-length($controlFieldDate) &gt; 0">
      <dcterms:created>
	<xsl:value-of select="$controlFieldDate" />
      </dcterms:created>
    </xsl:if>

    <!-- generate type information based on leader6 and leader 7 data -->
  
    <xsl:if test="string-length(normalize-space($leader6))">
      <xsl:choose>
	<xsl:when test="contains('acdt', $leader6)">
	  <dc:type xsi:type="dcterms:DCMIType">Text</dc:type>
	</xsl:when>
	<xsl:when test="contains('efgk', $leader6)">
	  <dc:type xsi:type="dcterms:DCMIType">Image</dc:type>
	</xsl:when>
	<xsl:when test="contains('ij', $leader6)">
	  <dc:type xsi:type="dcterms:DCMIType">Sound</dc:type>
	</xsl:when>
	<xsl:when test="$leader6='m'">
	  <dc:type xsi:type="dcterms:DCMIType">Software</dc:type>
	</xsl:when>
	<xsl:when test="contains('opr', $leader6)">
	  <dc:type xsi:type="dcterms:DCMIType">PhysicalObject</dc:type>
	</xsl:when>
      </xsl:choose>
      
      <!-- refined types -->
      <xsl:choose>
	<xsl:when test="contains('efk', $leader6)">
	  <dc:type xsi:type="dcterms:DCMIType">StillImage</dc:type>
	</xsl:when>
	<xsl:when test="$leader6='g'">
	  <dc:type xsi:type="dcterms:DCMIType">MovingImage</dc:type>
	</xsl:when>
	<xsl:when test="contains('cd', $leader6)"> 
	  <dc:type>Notated music</dc:type>
	</xsl:when>
	<xsl:when test="$leader6='p'"> 
	  <dc:type>Mixed material</dc:type>
	</xsl:when>
      </xsl:choose>

      <!-- even more refinement on information in leader6 -->
      <xsl:if test="contains('ef', $leader6)">
	<dc:type>Cartographic</dc:type>
      </xsl:if>
    </xsl:if>
    <!-- end checks on $leader6 -->

    <!-- leader 7 can tell us if something is a collection -->
    <xsl:if test="string-length(normalize-space($leader7))">
      <xsl:choose>
	<xsl:when test="contains('csp', $leader7)">
	  <dc:type xsi:type="dcterms:DCMIType">Collection</dc:type>
	</xsl:when>
      </xsl:choose>
    </xsl:if>

    <!-- the 655 field in marc might contain DC type information -->
    <xsl:for-each select="marc:datafield[@tag=655]">
      <dc:type>
	<xsl:if test="marc:subfield[@code='2']='dct'">
	  <xsl:attribute name="xsi:type">dcterms:DCMIType</xsl:attribute>
	</xsl:if>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">abcvxyz3568</xsl:with-param>
	</xsl:call-template>
      </dc:type>
    </xsl:for-each>

    <!-- get the format code -->
    <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q']">
      <dc:format xsi:type="dcterms:IMT">
	<xsl:value-of select="."/>
      </dc:format>
    </xsl:for-each>

    <!-- generate format extent tags -->
    <xsl:for-each select="marc:datafield[@tag=300]/marc:subfield[@code='a']">
      <dcterms:extent>
	<xsl:value-of select="."/>
      </dcterms:extent>
    </xsl:for-each>

    <!-- 533$e contains data for an extent tag -->
    <xsl:for-each select="marc:datafield[@tag=533]/marc:subfield[@code='e']">
      <dcterms:extent>
	<xsl:value-of select="."/>
      </dcterms:extent>
    </xsl:for-each>

   <!-- 300 contains data about the medium -->
    <xsl:for-each select="marc:datafield[@tag=300]">
      <dcterms:medium>
	<xsl:value-of select="."/>
      </dcterms:medium>
    </xsl:for-each>

    <!-- 340$a contains data about the medium -->
    <xsl:for-each select="marc:datafield[@tag=340]/marc:subfield[@code='a']">
      <dcterms:medium>
	<xsl:value-of select="."/>
      </dcterms:medium>
    </xsl:for-each>

    <!-- 856$u contains the URI for the item -->
    <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='u']">
      <dc:identifier xsi:type="dcterms:URI">
	<xsl:value-of select="."/>
      </dc:identifier>
    </xsl:for-each>

    <!-- controlfield 8 chars 35 through 37 contain an ISO 639-2 language
         code -->
    <xsl:variable name="controlFieldLang">
      <xsl:value-of select="normalize-space(substring($controlField008,36,3))"/>
    </xsl:variable>
    <xsl:if test="string-length($controlFieldLang) &gt; 0">
      <dc:language xsi:type="dcterms:ISO639-2">
	<xsl:value-of select="$controlFieldLang"/>
      </dc:language>
    </xsl:if>

    <!-- 041 fields contain lists of ISO639-2 language codes -->
    <xsl:for-each select="marc:datafield[@tag=041]">
      <xsl:for-each select="marc:subfield[@code='a']|marc:subfield[@code='b']|marc:subfield[@code='d']|marc:subfield[@code='e']|marc:subfield[@code='f']|marc:subfield[@code='g']|marc:subfield[@code='h']">
	<dc:language xsi:type="dcterms:ISO639-2">
	  <xsl:value-of select="." />
	</dc:language>
      </xsl:for-each>
    </xsl:for-each>

    <!-- 775 contains isVersionOf and hasVersion information -->
    <xsl:for-each select="marc:datafield[@tag=775]">
      <xsl:call-template name="noteUriRelation" />
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:hasVersion</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 786 contains isVersionOf and source information -->
    <xsl:for-each select="marc:datafield[@tag=786]">
      <xsl:call-template name="noteUriRelation" />
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dc:source</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 785 specifies that this item is replaced by another item -->
    <xsl:for-each select="marc:datafield[@tag=785]">
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:isReplacedBy</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 780 specifies that this item replaces another item -->
    <xsl:for-each select="marc:datafield[@tag=780]">
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:replaces</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 760 and 773 specify that this item is part of another -->
    <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=773]">
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:isPartOf</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- it is claimed that tags 440, 490, 800, 810, 811, and 830 contain
	 "is part of" information; note, however, these relations do not
	 include a URI -->
    <xsl:for-each select="marc:datafield[@tag=440]|marc:datafield[@tag=490]|marc:datafield[@tag=800]|marc:datafield[@tag=810]|marc:datafield[@tag=811]|marc:datafield[@tag=830]">
      <dcterms:isPartOf><xsl:value-of select="." /></dcterms:isPartOf>
    </xsl:for-each>

    <!-- 774 indicates that another item has part of this item -->
    <xsl:for-each select="marc:datafield[@tag=774]">
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:hasPart</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 776 indicates this item is available in another format -->
    <xsl:for-each select="marc:datafield[@tag=776]">
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:isFormatOf</xsl:with-param>
      </xsl:call-template>
      <xsl:call-template name="noteUriRelation">
	<xsl:with-param name="elementName">dcterms:hasFormat</xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>

    <!-- 255 contains cartographic mathematical data -->
    <!-- 650$z contains geographic subject entry -->
    <xsl:for-each select="marc:datafield[@tag=255]|marc:datafield[@tag=650]/marc:subfield[@code='z']">
      <dcterms:spatial>
      <xsl:value-of select="."/>
      </dcterms:spatial>
    </xsl:for-each>

    <!-- 651 is subject geographic name -->
    <xsl:for-each select="marc:datafield[@tag=651]">
      <dcterms:spatial>
	<xsl:if test="marc:subfield[@code='2']='tgn'">
	  <xsl:attribute name="xsi:type">dcterms:TGN</xsl:attribute>
	</xsl:if>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">az</xsl:with-param>
	</xsl:call-template>
      </dcterms:spatial>
    </xsl:for-each>

    <!-- 752 hierarchical place name -->
    <xsl:for-each select="marc:datafield[@tag=752]">
      <dcterms:spatial>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">abcd</xsl:with-param>
	</xsl:call-template>
      </dcterms:spatial>
    </xsl:for-each>

    <!-- 043$c contains geographic area code -->
    <!-- 044$c contains contains country of publishing code -->
    <xsl:for-each select="marc:datafield[@tag=043]/marc:subfield[@code='c']|marc:datafield[@tag=044]/marc:subfield[@code='c']">
      <dcterms:spatial xsi:type="dcterms:ISO3166">
	<xsl:value-of select="."/>
      </dcterms:spatial>
    </xsl:for-each>

    <!-- 033$a contains date/time of event -->
    <xsl:for-each select="marc:datafield[@tag=033]/marc:subfield[@code='a']">
      <dcterms:temporal>
      <xsl:value-of select="."/>
      </dcterms:temporal>
    </xsl:for-each>

    <!-- the marc2dc crosswalk specifies that 760-787$o$t be translated to
         the relation tag; some, but not all, of the datafields in this
	 range are mentioned in the marc2qdc crosswalk. Those that have not
	 are handled here -->
    <xsl:for-each select="marc:datafield[(@tag &gt;= 761 and @tag &lt;= 772) or (@tag &gt;= 777 and @tag &lt;= 779) or (@tag &gt;= 781 and @tag &lt;= 784) or (@tag = 787)]">
      <dc:relation>
	<xsl:call-template name="subfieldSelect">
	  <xsl:with-param name="codes">ot</xsl:with-param>
	</xsl:call-template>
      </dc:relation>
    </xsl:for-each>	   

    <!-- 020 is mentioned in neither the marc2dc nor marc2qdc crosswalk;
         however, it contains ISBN information that can be listed as an
	 identifier field -->
    <xsl:for-each select="marc:datafield[@tag=020]/marc:subfield[@code='a']|marc:datafield[@tag=020]/marc:subfield[@code='z']">
      <dc:identifier xsi:type="dcterms:URI">
	<xsl:text>URN:ISBN:</xsl:text><xsl:value-of select="." />
      </dc:identifier>	   
    </xsl:for-each>

    <!-- the marc2dc stylesheet from which this stylesheet was derived
         includes this rule to handle the obsolete 090 datafield -->
    <xsl:for-each select="marc:datafield[@tag=090]">
      <dc:identifier>
	<xsl:value-of select="." />
      </dc:identifier>
    </xsl:for-each>
    
  </xsl:template>
</xsl:stylesheet>
