Bruce had requested that I post these documents to the list. I hope that
someone may find them useful and I encourage all feedback and criticism.
These were developed to transform MODS (encoded in METS) into Dublin Core
for internal indexing purposes. While this is not a final version, it is
in production and seems to be doing what it is supposed to. A slightly
modified production version can be viewed at
http://ark.cdlib.org/xslt/extract-dc/OAC-LSTA-MODS2DC.qdc21.xsl.
I took the DC to MODS mapping stylesheet as a starting point, but as we all
know round-tripping is never the same both ways and I had to make a lot of
logical modification. Also, we are still working with MODS 2.0 so this
will need work when we make the transition.
I have attached the documents (an .xslt and a .txt) and have also pasted
them below. Again, please let me hear any opinions you may have.
Paul Fogel
California Digital Library
[log in to unmask]
510.987.0680
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/TR/xlink"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mets="http://www.loc.gov/METS/"
xmlns:cdl="http://ark.cdlib.org/schemas/appqualifieddc/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:mods="http://www.loc.gov/mods/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates select="mets:mets"/>
</xsl:template>
<xsl:template match="mets:mets">
<qdc2>
<xsl:call-template name="title"/>
<xsl:call-template name="creator"/>
<xsl:call-template name="subject"/>
<xsl:call-template name="description"/>
<xsl:call-template name="publisher"/>
<xsl:call-template name="contributor"/>
<xsl:call-template name="date"/>
<xsl:call-template name="type"/>
<xsl:call-template name="format"/>
<xsl:call-template name="identifier"/>
<xsl:call-template name="source"/>
<xsl:call-template name="language"/>
<xsl:call-template name="relation"/>
<xsl:call-template name="coverage"/>
<xsl:call-template name="rights"/>
<xsl:call-template name="dcterms"/>
</qdc2>
</xsl:template>
<xsl:template name="title">
<dc:title>
<xsl:value-of select="//mods:mods/mods:titleInfo/mods:title"/>
<xsl:if test="//mods:mods/mods:titleInfo/mods:subTitle">
<xsl:text>: </xsl:text>
<xsl:value-of select="//mods:mods/mods:titleInfo/mods:subTitle"/>
</xsl:if>
</dc:title>
</xsl:template>
<xsl:template name="creator">
<!-- This may be used in the future for alternate encoding practices -->
<!-- xsl:if test="contains(//mods:mods/mods:name/mods:role/mods:text,
'creator')" -->
<!-- dc:creator-->
<!-- xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/-->
<!--/dc:creator-->
<!--/xsl:if-->
<xsl:if test="contains(//mods:mods/mods:name/mods:role, 'creator')">
<dc:creator>
<xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/>
</dc:creator>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordContentSource">
<dc:creator>
<xsl:value-of
select="//mods:mods/mods:recordInfo/mods:recordContentSource"/>
</dc:creator>
</xsl:if>
</xsl:template>
<xsl:template name="subject">
<xsl:for-each select="//mods:mods/mods:subject/mods:topic">
<dc:subject>
<xsl:value-of select="."/>
</dc:subject>
</xsl:for-each>
<xsl:for-each select="//mods:mods/mods:subject/mods:name">
<dc:subject>
<xsl:value-of select="."/>
</dc:subject>
</xsl:for-each>
<xsl:if test="//mods:mods/mods:subject/mods:titleInfo/mods:title">
<dc:subject>
<xsl:value-of
select="//mods:mods/mods:subject/mods:titleInfo/mods:title"/>
</dc:subject>
</xsl:if>
</xsl:template>
<xsl:template name="description">
<xsl:if test="//mods:mods/mods:abstract">
<description>
<xsl:value-of select="//mods:mods/mods:abstract"/>
</description>
</xsl:if>
<xsl:if test="//mods:mods/mods:tableOfContents">
<dc:description>
<xsl:value-of select="//mods:mods/mods:tableOfContents"/>
</dc:description>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:note">
<dc:description>
<xsl:value-of select="."/>
</dc:description>
</xsl:for-each>
<xsl:if test="//mods:mods/mods:subject/mods:name/mods:description">
<dc:description>
<xsl:value-of
select="//mods:mods/mods:subject/mods:name/mods:description"/>
</dc:description>
</xsl:if>
</xsl:template>
<xsl:template name="publisher">
<xsl:if test="//mods:mods/mods:originInfo/mods:publisher">
<dc:publisher>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:publisher"/>
</dc:publisher>
</xsl:if>
<!-- may be used in the future, if deemed appropriate -->
<!--xsl:if test="//mods:mods/mods:recordInfo/mods:recordContentSource"-->
<!--dc:publisher-->
<!--xsl:value-of
select="//mods:mods/mods:recordInfo/mods:recordContentSource"/-->
<!--/dc:publisher-->
<!--/xsl:if-->
<xsl:if test="//mods:mods/mods:publicationInfo/mods:publisher">
<dc:publisher>
<xsl:value-of
select="//mods:mods/mods:publicationInfo/mods:publisher"/>
</dc:publisher>
</xsl:if>
</xsl:template>
<xsl:template name="contributor">
<xsl:if test="contains(//mods:mods/mods:name/mods:role/mods:text,
'contributor')">
<dc:contributor>
<xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/>
</dc:contributor>
</xsl:if>
</xsl:template>
<xsl:template name="date">
<xsl:if test="//mods:mods/mods:originInfo/mods:dateIssued">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateIssued"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:publicationInfo/mods:dateIssued">
<dc:date>
<xsl:value-of
select="//mods:mods/mods:publicationInfo/mods:dateIssued"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCreated">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCreated"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCaptured">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCaptured"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateOther">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateOther"/>
</dc:date>
</xsl:if>
</xsl:template>
<xsl:template name="type">
<xsl:if test="//mods:mods/mods:typeOfResource">
<dc:type>
<xsl:value-of select="//mods:mods/mods:typeOfResource"/>
</dc:type>
</xsl:if>
<xsl:if test="//mods:mods/mods:genre">
<dc:type>
<xsl:value-of select="//mods:mods/mods:genre"/>
</dc:type>
</xsl:if>
</xsl:template>
<xsl:template name="format">
<xsl:if test="//mods:mods/mods:physicalDescription/mods:extent">
<dc:format>
<xsl:value-of
select="//mods:mods/mods:physicalDescription/mods:extent"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:form">
<dc:format>
<xsl:value-of
select="//mods:mods/mods:physicalDescription/mods:form"/>
</dc:format>
</xsl:if>
<xsl:if
test="//mods:mods/mods:physicalDescription/mods:internetMediaType">
<dc:format>
<xsl:value-of
select="//mods:mods/mods:physicalDescription/mods:internetMediaType"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:digitalOrigin">
<dc:format>
<xsl:value-of
select="//mods:mods/mods:physicalDescription/mods:digitalOrigin"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:note">
<dc:format>
<xsl:value-of
select="//mods:mods/mods:physicalDescription/mods:note"/>
</dc:format>
</xsl:if>
</xsl:template>
<xsl:template name="identifier">
<xsl:for-each select="//mods:mods/mods:identifier">
<xsl:choose>
<xsl:when test="@type='isbn'">
<dc:identifier>
<xsl:text>isbn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='issn'">
<dc:identifier>
<xsl:text>issn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='doi'">
<dc:identifier>
<xsl:text>doi: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='lccn'">
<dc:identifier>
<xsl:text>lccn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='uri'">
<dc:identifier>
<xsl:text>uri: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:otherwise>
<dc:identifier>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="source">
<xsl:if test="//mods:mods/mods:relatedItem[@type='original']">
<xsl:for-each select="//mods:mods/mods:relatedItem[@type='original']/*">
<dc:source>
<xsl:value-of select="."/>
</dc:source>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template name="language">
<dc:language>
<xsl:value-of select="//mods:mods/mods:language"/>
</dc:language>
</xsl:template>
<xsl:template name="relation">
<xsl:for-each select="//mods:mods/mods:relatedItem">
<xsl:choose>
<xsl:when test="@type='original'"/>
<xsl:when test="@type='series'"/>
<xsl:otherwise>
<xsl:apply-templates mode="makeRelations"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:if test="//*[local-name()='relation']">
<dc:relation>
<xsl:value-of select="//*[local-name()='relation']"/>
</dc:relation>
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="makeRelations">
<xsl:apply-templates mode="makeRelations"/>
</xsl:template>
<xsl:template match="text()" mode="makeRelations">
<xsl:if test="normalize-space(.) != ''">
<dc:relation>
<xsl:value-of select="normalize-space(.)"/>
</dc:relation>
</xsl:if>
</xsl:template>
<xsl:template name="coverage">
<xsl:if test="//mods:mods/mods:subject/mods:geographic">
<dc:coverage>
<xsl:value-of select="//mods:mods/mods:subject/mods:geographic"/>
</dc:coverage>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:temporal">
<dc:coverage>
<xsl:value-of select="//mods:mods/mods:subject/mods:temporal"/>
</dc:coverage>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:hierarchicalGeographic">
<xsl:apply-templates mode="coverage1"
select="//mods:mods/mods:subject/mods:hierarchicalGeographic"/>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:cartographic">
<xsl:apply-templates mode="coverage2"
select="//mods:mods/mods:subject/mods:cartographic"/>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:classification">
<dc:coverage>
<xsl:value-of select="."/>
</dc:coverage>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="coverage1">
<xsl:apply-templates mode="coverage1"/>
</xsl:template>
<xsl:template match="text()" mode="coverage1">
<xsl:if test="normalize-space(.) != ''">
<dc:coverage>
<xsl:value-of select="normalize-space(.)"/>
</dc:coverage>
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="coverage2">
<xsl:apply-templates mode="coverage2"/>
</xsl:template>
<xsl:template match="text()" mode="coverage2">
<xsl:if test="normalize-space(.) != ''">
<dc:coverage>
<xsl:value-of select="normalize-space(.)"/>
</dc:coverage>
</xsl:if>
</xsl:template>
<xsl:template name="rights">
<xsl:if test="//mods:mods/mods:accessCondition">
<dc:rights>
<xsl:value-of select="//mods:mods/mods:accessCondition"/>
</dc:rights>
</xsl:if>
</xsl:template>
<xsl:template name="dcterms">
<xsl:if test="//mods:mods/mods:abstract">
<dcterms:abstract>
<xsl:value-of select="//mods:mods/mods:abstract"/>
</dcterms:abstract>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordCreationDate">
<dcterms:created>
<xsl:value-of
select="//mods:mods/mods:recordInfo/mods:recordCreationDate"/>
</dcterms:created>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCreated">
<dcterms:created>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCreated"/>
</dcterms:created>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordChangeDate">
<dcterms:modified>
<xsl:value-of
select="//mods:mods/mods:recordInfo/mods:recordChangeDate"/>
</dcterms:modified>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:relatedItem">
<xsl:choose>
<xsl:when test="@type='series'">
<xsl:apply-templates mode="makeIsPartOf"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="makeIsPartOf">
<xsl:apply-templates mode="makeIsPartOf"/>
</xsl:template>
<xsl:template match="text()" mode="makeIsPartOf">
<xsl:if test="normalize-space(.) != ''">
<dcterms:isPartOf>
<xsl:value-of select="normalize-space(.)"/>
</dcterms:isPartOf>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
MODS to Dublin Core Mapping
By Dublin Core Element, from MODS Element
Title:
//mods/titleInfo/title - A conditional IF statement is included to catch
<titleInfo><subTitle> and append it to the title, separated by colon space
(: ).
Creator:
//mods/name/namePart - when //mods/name/role[. = 'creator']
//mods/recordInfo/recordContentSource
Subject:
//mods/subject/topic
//mods/subject/name
//mods/subject/titleInfo/title
Description:
//mods/abstract
//mods/tableOfContents
//mods/note
//mods/subject/name<description>
Publisher:
//mods/originInfo/publisher
//mods/publicationInfo/publisher - to accommodate earlier encoding
practices; this usage is outdated
Contributor:
//mods/name/namePart - when //mods/name/role/text[. = 'contributor']
Date:
Mapped from:
//mods/originInfo/dateIssued
//mods/originInfo/dateCreated
//mods/originInfo/dateCaptured
//mods/originInfo/dateOther
//mods/publicationInfo/dateIssued - to accommodate earlier encoding
practices; this usage is outdated
Type:
//mods/typeOfResource
//mods/genre
Format:
//mods/physicalDescription/extent
//mods/physicalDescription/form
//mods/physicalDescription/internetMediaType
//mods/physicalDescription/digitalOrigin
//mods/physicalDescription/note
Identifier:
//mods/identifier - If @TYPE= 'isbn', 'issn', 'lccn', 'doi' or 'uri', then
this value precedes the data, separated by colon space.
Example: <identifier>uri:
http://www.ucpress.edu/books/pages/6178.html&isbn=0520081994</identifier>
If there is no TYPE attribute, or if it is not set to one of these
values, the data is mapped without qualification.
Source:
//mods/relatedItem[@TYPE='original']
Language:
//mods/language
Relation:
//mods/relatedItem - except when relatedItem[(@TYPE='original') or
(@TYPE='series')]
Coverage:
Mapped from:
//mods/subject/geographic
//mods/subject/temporal
//mods/subject/hierarchicalGeographic
//mods/subject/cartographic
//mods/classification
The hierarchicalGeographic and cartographic nodes are flattened so
that repeating values as well as sub-elements (and their children) are
strung into one element.
Rights:
//mods/accessCondition
DCTerms:Abstract:
//mods/abstract - this data is also mapped (see above) into Description, so
that data is not lost in Unqualified Dublin Core.
DCTerms:Created
//mods/recordInfo/recordCreationDate. This is also mapped to Date, so that
data is not lost in Unqualified Dublin Core.
DCTerms:Modified
//mods/recordInfo/recordChangeDate. This is also mapped to Date, so that
data is not lost in Unqualified Dublin Core.
DCTerms:isPartOf
//mods/relatedItem - when //mods/relatedItem[@TYPE='series']. This is also
mapped to Relation, so that data is not lost in Unqualified Dublin Core.
By MODS Element, to Dublin Core Element
ELEMENT MAPPED TO
//mods/titleInfo/title title
//mods/titleInfo/subTitle title
//mods/titleInfo/partNumber ignored
//mods/titleInfo/partName ignored
//mods/titleInfo/nonSort ignored
//mods/name/namePart creator, contributor (see
above)
//mods/name/displayForm ignored
//mods/name/affiliation ignored
//mods/name/role Used to assign creator and
contributor, otherwise ignored.
//mods/name/description description
//mods/typeOfResource type
//mods/genre type
//mods/originInfo/place ignored
//mods/originInfo/publisher publisher
//mods/originInfo/dateIssued date
//mods/originInfo/dateCreated date, dcterms:created
//mods/originInfo/dateCaptured date
//mods/originInfo/dateOther date
//mods/originInfo/edition ignored
//mods/originInfo/issuance ignored
//mods/originInfo/frequency ignored
//mods/language language
//mods/physicalDescription/form format
//mods/physicalDescription/reformattingQuality ignored
//mods/physicalDescription/internetMediaType format
//mods/physicalDescription/extent format
//mods/physicalDescription/digitalOrigin format
//mods/physicalDescription/note format
//mods/abstract description, dcterms:absctract
//mods/tableOfContents description
//mods/targetAudience ignored
//mods/note description
//mods/subject/topic subject
//mods/subject/geographical coverage
//mods/subject/temporal coverage
//mods/subject/titleInfo/title subject
(other subelements for titleInfo ignored)
//mods/subject/name<description> subject
(other subelements for name ignored)
//mods/subject/hierarchicalGeographic coverage
(subelements flattened to appear in one string)
//mods/subject/cartographic coverage
(subelements flattened to appear in one string)
//mods/classification coverage
//mods/relatedItem[@type='original'] source
//mods/relatedItem[@type='series'] dcterms:isPartOf
//mods/relatedItem[@type='*'] relation
(subelements flattened to appear in one string)
//mods/identifier identifier
(if type is issn, isbn, lccn, uri, or doi, it is applied at
beginning of data string; otherwise data is applied as is)
Ex. <dc:identifier>isbn: 0123456789</dc:identifier>
<dc:identifier>12-34567-8901234-5-67</dc:identifier>
//mods/location ignored
//mods/accessCondition rights
//mods/extension ignored
//mods/recordInfo/recordContentSource creator,
//mods/recordInfo/recordCreationDate dcterms:created
//mods/recordInfo/recordChangeDate dcterms:modified
//mods/recordInfo/recordIdentifier ignored
//mods/recordInfo/languageOfCataloging ignored
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/TR/xlink"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mets="http://www.loc.gov/METS/"
xmlns:cdl="http://ark.cdlib.org/schemas/appqualifieddc/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:mods="http://www.loc.gov/mods/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates select="mets:mets"/>
</xsl:template>
<xsl:template match="mets:mets">
<qdc2>
<xsl:call-template name="title"/>
<xsl:call-template name="creator"/>
<xsl:call-template name="subject"/>
<xsl:call-template name="description"/>
<xsl:call-template name="publisher"/>
<xsl:call-template name="contributor"/>
<xsl:call-template name="date"/>
<xsl:call-template name="type"/>
<xsl:call-template name="format"/>
<xsl:call-template name="identifier"/>
<xsl:call-template name="source"/>
<xsl:call-template name="language"/>
<xsl:call-template name="relation"/>
<xsl:call-template name="coverage"/>
<xsl:call-template name="rights"/>
<xsl:call-template name="dcterms"/>
</qdc2>
</xsl:template>
<xsl:template name="title">
<dc:title>
<xsl:value-of select="//mods:mods/mods:titleInfo/mods:title"/>
<xsl:if test="//mods:mods/mods:titleInfo/mods:subTitle">
<xsl:text>: </xsl:text>
<xsl:value-of select="//mods:mods/mods:titleInfo/mods:subTitle"/>
</xsl:if>
</dc:title>
</xsl:template>
<xsl:template name="creator">
<!-- This may be used in the future for alternate encoding practices -->
<!-- xsl:if test="contains(//mods:mods/mods:name/mods:role/mods:text, 'creator')" -->
<!-- dc:creator-->
<!-- xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/-->
<!--/dc:creator-->
<!--/xsl:if-->
<xsl:if test="contains(//mods:mods/mods:name/mods:role, 'creator')">
<dc:creator>
<xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/>
</dc:creator>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordContentSource">
<dc:creator>
<xsl:value-of select="//mods:mods/mods:recordInfo/mods:recordContentSource"/>
</dc:creator>
</xsl:if>
</xsl:template>
<xsl:template name="subject">
<xsl:for-each select="//mods:mods/mods:subject/mods:topic">
<dc:subject>
<xsl:value-of select="."/>
</dc:subject>
</xsl:for-each>
<xsl:for-each select="//mods:mods/mods:subject/mods:name">
<dc:subject>
<xsl:value-of select="."/>
</dc:subject>
</xsl:for-each>
<xsl:if test="//mods:mods/mods:subject/mods:titleInfo/mods:title">
<dc:subject>
<xsl:value-of select="//mods:mods/mods:subject/mods:titleInfo/mods:title"/>
</dc:subject>
</xsl:if>
</xsl:template>
<xsl:template name="description">
<xsl:if test="//mods:mods/mods:abstract">
<description>
<xsl:value-of select="//mods:mods/mods:abstract"/>
</description>
</xsl:if>
<xsl:if test="//mods:mods/mods:tableOfContents">
<dc:description>
<xsl:value-of select="//mods:mods/mods:tableOfContents"/>
</dc:description>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:note">
<dc:description>
<xsl:value-of select="."/>
</dc:description>
</xsl:for-each>
<xsl:if test="//mods:mods/mods:subject/mods:name/mods:description">
<dc:description>
<xsl:value-of select="//mods:mods/mods:subject/mods:name/mods:description"/>
</dc:description>
</xsl:if>
</xsl:template>
<xsl:template name="publisher">
<xsl:if test="//mods:mods/mods:originInfo/mods:publisher">
<dc:publisher>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:publisher"/>
</dc:publisher>
</xsl:if>
<!-- may be used in the future, if deemed appropriate -->
<!--xsl:if test="//mods:mods/mods:recordInfo/mods:recordContentSource"-->
<!--dc:publisher-->
<!--xsl:value-of select="//mods:mods/mods:recordInfo/mods:recordContentSource"/-->
<!--/dc:publisher-->
<!--/xsl:if-->
<xsl:if test="//mods:mods/mods:publicationInfo/mods:publisher">
<dc:publisher>
<xsl:value-of select="//mods:mods/mods:publicationInfo/mods:publisher"/>
</dc:publisher>
</xsl:if>
</xsl:template>
<xsl:template name="contributor">
<xsl:if test="contains(//mods:mods/mods:name/mods:role/mods:text, 'contributor')">
<dc:contributor>
<xsl:value-of select="//mods:mods/mods:name[1]/mods:namePart"/>
</dc:contributor>
</xsl:if>
</xsl:template>
<xsl:template name="date">
<xsl:if test="//mods:mods/mods:originInfo/mods:dateIssued">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateIssued"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:publicationInfo/mods:dateIssued">
<dc:date>
<xsl:value-of select="//mods:mods/mods:publicationInfo/mods:dateIssued"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCreated">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCreated"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCaptured">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCaptured"/>
</dc:date>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateOther">
<dc:date>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateOther"/>
</dc:date>
</xsl:if>
</xsl:template>
<xsl:template name="type">
<xsl:if test="//mods:mods/mods:typeOfResource">
<dc:type>
<xsl:value-of select="//mods:mods/mods:typeOfResource"/>
</dc:type>
</xsl:if>
<xsl:if test="//mods:mods/mods:genre">
<dc:type>
<xsl:value-of select="//mods:mods/mods:genre"/>
</dc:type>
</xsl:if>
</xsl:template>
<xsl:template name="format">
<xsl:if test="//mods:mods/mods:physicalDescription/mods:extent">
<dc:format>
<xsl:value-of select="//mods:mods/mods:physicalDescription/mods:extent"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:form">
<dc:format>
<xsl:value-of select="//mods:mods/mods:physicalDescription/mods:form"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:internetMediaType">
<dc:format>
<xsl:value-of select="//mods:mods/mods:physicalDescription/mods:internetMediaType"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:digitalOrigin">
<dc:format>
<xsl:value-of select="//mods:mods/mods:physicalDescription/mods:digitalOrigin"/>
</dc:format>
</xsl:if>
<xsl:if test="//mods:mods/mods:physicalDescription/mods:note">
<dc:format>
<xsl:value-of select="//mods:mods/mods:physicalDescription/mods:note"/>
</dc:format>
</xsl:if>
</xsl:template>
<xsl:template name="identifier">
<xsl:for-each select="//mods:mods/mods:identifier">
<xsl:choose>
<xsl:when test="@type='isbn'">
<dc:identifier>
<xsl:text>isbn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='issn'">
<dc:identifier>
<xsl:text>issn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='doi'">
<dc:identifier>
<xsl:text>doi: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='lccn'">
<dc:identifier>
<xsl:text>lccn: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:when test="@type='uri'">
<dc:identifier>
<xsl:text>uri: </xsl:text>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:when>
<xsl:otherwise>
<dc:identifier>
<xsl:value-of select="."/>
</dc:identifier>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="source">
<xsl:if test="//mods:mods/mods:relatedItem[@type='original']">
<xsl:for-each select="//mods:mods/mods:relatedItem[@type='original']/*">
<dc:source>
<xsl:value-of select="."/>
</dc:source>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template name="language">
<dc:language>
<xsl:value-of select="//mods:mods/mods:language"/>
</dc:language>
</xsl:template>
<xsl:template name="relation">
<xsl:for-each select="//mods:mods/mods:relatedItem">
<xsl:choose>
<xsl:when test="@type='original'"/>
<xsl:when test="@type='series'"/>
<xsl:otherwise>
<xsl:apply-templates mode="makeRelations"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:if test="//*[local-name()='relation']">
<dc:relation>
<xsl:value-of select="//*[local-name()='relation']"/>
</dc:relation>
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="makeRelations">
<xsl:apply-templates mode="makeRelations"/>
</xsl:template>
<xsl:template match="text()" mode="makeRelations">
<xsl:if test="normalize-space(.) != ''">
<dc:relation>
<xsl:value-of select="normalize-space(.)"/>
</dc:relation>
</xsl:if>
</xsl:template>
<xsl:template name="coverage">
<xsl:if test="//mods:mods/mods:subject/mods:geographic">
<dc:coverage>
<xsl:value-of select="//mods:mods/mods:subject/mods:geographic"/>
</dc:coverage>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:temporal">
<dc:coverage>
<xsl:value-of select="//mods:mods/mods:subject/mods:temporal"/>
</dc:coverage>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:hierarchicalGeographic">
<xsl:apply-templates mode="coverage1" select="//mods:mods/mods:subject/mods:hierarchicalGeographic"/>
</xsl:if>
<xsl:if test="//mods:mods/mods:subject/mods:cartographic">
<xsl:apply-templates mode="coverage2" select="//mods:mods/mods:subject/mods:cartographic"/>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:classification">
<dc:coverage>
<xsl:value-of select="."/>
</dc:coverage>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="coverage1">
<xsl:apply-templates mode="coverage1"/>
</xsl:template>
<xsl:template match="text()" mode="coverage1">
<xsl:if test="normalize-space(.) != ''">
<dc:coverage>
<xsl:value-of select="normalize-space(.)"/>
</dc:coverage>
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="coverage2">
<xsl:apply-templates mode="coverage2"/>
</xsl:template>
<xsl:template match="text()" mode="coverage2">
<xsl:if test="normalize-space(.) != ''">
<dc:coverage>
<xsl:value-of select="normalize-space(.)"/>
</dc:coverage>
</xsl:if>
</xsl:template>
<xsl:template name="rights">
<xsl:if test="//mods:mods/mods:accessCondition">
<dc:rights>
<xsl:value-of select="//mods:mods/mods:accessCondition"/>
</dc:rights>
</xsl:if>
</xsl:template>
<xsl:template name="dcterms">
<xsl:if test="//mods:mods/mods:abstract">
<dcterms:abstract>
<xsl:value-of select="//mods:mods/mods:abstract"/>
</dcterms:abstract>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordCreationDate">
<dcterms:created>
<xsl:value-of select="//mods:mods/mods:recordInfo/mods:recordCreationDate"/>
</dcterms:created>
</xsl:if>
<xsl:if test="//mods:mods/mods:originInfo/mods:dateCreated">
<dcterms:created>
<xsl:value-of select="//mods:mods/mods:originInfo/mods:dateCreated"/>
</dcterms:created>
</xsl:if>
<xsl:if test="//mods:mods/mods:recordInfo/mods:recordChangeDate">
<dcterms:modified>
<xsl:value-of select="//mods:mods/mods:recordInfo/mods:recordChangeDate"/>
</dcterms:modified>
</xsl:if>
<xsl:for-each select="//mods:mods/mods:relatedItem">
<xsl:choose>
<xsl:when test="@type='series'">
<xsl:apply-templates mode="makeIsPartOf"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="makeIsPartOf">
<xsl:apply-templates mode="makeIsPartOf"/>
</xsl:template>
<xsl:template match="text()" mode="makeIsPartOf">
<xsl:if test="normalize-space(.) != ''">
<dcterms:isPartOf>
<xsl:value-of select="normalize-space(.)"/>
</dcterms:isPartOf>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
MODS to Dublin Core Mapping
By Dublin Core Element, from MODS Element
Title:
//mods/titleInfo/title - A conditional IF statement is included to catch <titleInfo><subTitle> and append it to the title, separated by colon space (: ).
Creator:
//mods/name/namePart - when //mods/name/role[. = 'creator']
//mods/recordInfo/recordContentSource
Subject:
//mods/subject/topic
//mods/subject/name
//mods/subject/titleInfo/title
Description:
//mods/abstract
//mods/tableOfContents
//mods/note
//mods/subject/name<description>
Publisher:
//mods/originInfo/publisher
//mods/publicationInfo/publisher - to accommodate earlier encoding practices; this usage is outdated
Contributor:
//mods/name/namePart - when //mods/name/role/text[. = 'contributor']
Date:
Mapped from:
//mods/originInfo/dateIssued
//mods/originInfo/dateCreated
//mods/originInfo/dateCaptured
//mods/originInfo/dateOther
//mods/publicationInfo/dateIssued - to accommodate earlier encoding practices; this usage is outdated
Type:
//mods/typeOfResource
//mods/genre
Format:
//mods/physicalDescription/extent
//mods/physicalDescription/form
//mods/physicalDescription/internetMediaType
//mods/physicalDescription/digitalOrigin
//mods/physicalDescription/note
Identifier:
//mods/identifier - If @TYPE= 'isbn', 'issn', 'lccn', 'doi' or 'uri', then this value precedes the data, separated by colon space.
Example: <identifier>uri: http://www.ucpress.edu/books/pages/6178.html&isbn=0520081994</identifier>
If there is no TYPE attribute, or if it is not set to one of these values, the data is mapped without qualification.
Source:
//mods/relatedItem[@TYPE='original']
Language:
//mods/language
Relation:
//mods/relatedItem - except when relatedItem[(@TYPE='original') or (@TYPE='series')]
Coverage:
Mapped from:
//mods/subject/geographic
//mods/subject/temporal
//mods/subject/hierarchicalGeographic
//mods/subject/cartographic
//mods/classification
The hierarchicalGeographic and cartographic nodes are flattened so that repeating values as well as sub-elements (and their children) are strung into one element.
Rights:
//mods/accessCondition
DCTerms:Abstract:
//mods/abstract - this data is also mapped (see above) into Description, so that data is not lost in Unqualified Dublin Core.
DCTerms:Created
//mods/recordInfo/recordCreationDate. This is also mapped to Date, so that data is not lost in Unqualified Dublin Core.
DCTerms:Modified
//mods/recordInfo/recordChangeDate. This is also mapped to Date, so that data is not lost in Unqualified Dublin Core.
DCTerms:isPartOf
//mods/relatedItem - when //mods/relatedItem[@TYPE='series']. This is also mapped to Relation, so that data is not lost in Unqualified Dublin Core.
By MODS Element, to Dublin Core Element
ELEMENT MAPPED TO
//mods/titleInfo/title title
//mods/titleInfo/subTitle title
//mods/titleInfo/partNumber ignored
//mods/titleInfo/partName ignored
//mods/titleInfo/nonSort ignored
//mods/name/namePart creator, contributor (see above)
//mods/name/displayForm ignored
//mods/name/affiliation ignored
//mods/name/role Used to assign creator and contributor, otherwise ignored.
//mods/name/description description
//mods/typeOfResource type
//mods/genre type
//mods/originInfo/place ignored
//mods/originInfo/publisher publisher
//mods/originInfo/dateIssued date
//mods/originInfo/dateCreated date, dcterms:created
//mods/originInfo/dateCaptured date
//mods/originInfo/dateOther date
//mods/originInfo/edition ignored
//mods/originInfo/issuance ignored
//mods/originInfo/frequency ignored
//mods/language language
//mods/physicalDescription/form format
//mods/physicalDescription/reformattingQuality ignored
//mods/physicalDescription/internetMediaType format
//mods/physicalDescription/extent format
//mods/physicalDescription/digitalOrigin format
//mods/physicalDescription/note format
//mods/abstract description, dcterms:absctract
//mods/tableOfContents description
//mods/targetAudience ignored
//mods/note description
//mods/subject/topic subject
//mods/subject/geographical coverage
//mods/subject/temporal coverage
//mods/subject/titleInfo/title subject
(other subelements for titleInfo ignored)
//mods/subject/name<description> subject
(other subelements for name ignored)
//mods/subject/hierarchicalGeographic coverage
(subelements flattened to appear in one string)
//mods/subject/cartographic coverage
(subelements flattened to appear in one string)
//mods/classification coverage
//mods/relatedItem[@type='original'] source
//mods/relatedItem[@type='series'] dcterms:isPartOf
//mods/relatedItem[@type='*'] relation
(subelements flattened to appear in one string)
//mods/identifier identifier
(if type is issn, isbn, lccn, uri, or doi, it is applied at beginning of data string; otherwise data is applied as is)
Ex. <dc:identifier>isbn: 0123456789</dc:identifier>
<dc:identifier>12-34567-8901234-5-67</dc:identifier>
//mods/location ignored
//mods/accessCondition rights
//mods/extension ignored
//mods/recordInfo/recordContentSource creator,
//mods/recordInfo/recordCreationDate dcterms:created
//mods/recordInfo/recordChangeDate dcterms:modified
//mods/recordInfo/recordIdentifier ignored
//mods/recordInfo/languageOfCataloging ignored
|