You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tellico/xslt/mods2tellico.xsl

522 lines
16 KiB

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://periapsis.org/tellico/"
xmlns:mods="http://www.loc.gov/mods/v3"
xmlns:l="uri:langs"
exclude-result-prefixes="mods l"
version="1.0">
<!--
===================================================================
Tellico XSLT file - used for importing MODS files.
Copyright (C) 2004-2008 Robby Stephenson - robby@periapsis.org
This XSLT stylesheet is designed to be used with the 'Tellico'
application, which can be found at http://www.periapsis.org/tellico/
===================================================================
-->
<!-- lookup table for languages -->
<!-- according to http://www.oasis-open.org/cover/iso639-2-en971019.html -->
<!-- I just added common ones -->
<l:langs>
<l:lang id="ara">Arabic</l:lang>
<l:lang id="cat">Catalan</l:lang>
<l:lang id="cze">Czech</l:lang>
<l:lang id="dut">Dutch</l:lang>
<l:lang id="eng">English</l:lang>
<l:lang id="fre">French</l:lang>
<l:lang id="ger">German</l:lang>
<l:lang id="dut">Dutch</l:lang>
<l:lang id="heb">Hebrew</l:lang>
<l:lang id="gre">Greek</l:lang>
<l:lang id="hin">Hindi</l:lang>
<l:lang id="hun">Hungarian</l:lang>
<l:lang id="ita">Italian</l:lang>
<l:lang id="jpn">Japanese</l:lang>
<l:lang id="kor">Korean</l:lang>
<l:lang id="lat">Latin</l:lang>
<l:lang id="lit">Lithuanian</l:lang>
<l:lang id="nob">Norwegian Bokm&#229;l</l:lang>
<l:lang id="nor">Norwegian</l:lang>
<l:lang id="nno">Norwegian Nynorsk</l:lang>
<l:lang id="pol">Polish</l:lang>
<l:lang id="por">Portuguese</l:lang>
<l:lang id="rus">Russian</l:lang>
<l:lang id="slo">Slovak</l:lang>
<l:lang id="spa">Spanish</l:lang>
<l:lang id="swe">Swedish</l:lang>
<l:lang id="chi">Chinese</l:lang>
</l:langs>
<xsl:key name="langs" match="l:lang" use="@id"/>
<xsl:variable name="langs-top" select="document('')/*/l:langs"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
doctype-public="-//Robby Stephenson/DTD Tellico V10.0//EN"
doctype-system="http://periapsis.org/tellico/dtd/v10/tellico.dtd"/>
<!-- for now, it's a bibtex collection if it has an identifier,
book collection if not -->
<xsl:variable name="type">
<xsl:choose>
<xsl:when test="count(//mods:mods[string-length(@ID)&gt;0 or mods:identifier[@type='citekey']]) &gt; 0">
<xsl:text>bibtex</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>book</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="npubs">
<xsl:value-of select="count(//mods:originInfo[count(mods:publisher) &gt; 1])"/>
</xsl:variable>
<!-- disable default behavior -->
<xsl:template match="text()|@*"></xsl:template>
<xsl:template match="/">
<tellico syntaxVersion="10">
<collection title="MODS Import">
<xsl:attribute name="type">
<xsl:choose>
<xsl:when test="$type='bibtex'">
<xsl:text>5</xsl:text>
</xsl:when>
<xsl:when test="$type='book'">
<xsl:text>2</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<fields>
<field name="_default"/>
<!-- the default collection does not have multiple publishers -->
<xsl:if test="$npubs &gt; 1">
<field flags="7" title="Publisher" category="Publishing" format="0" type="1" name="publisher" i18n="true">
<prop name="bibtex">publisher</prop>
</field>
</xsl:if>
<!-- default book collection does not include an abstract -->
<xsl:if test="$type='book' and .//mods:mods/mods:abstract">
<field flags="0" title="Abstract" format="4" type="2" name="abstract" i18n="true">
<prop name="bibtex">abstract</prop>
</field>
</xsl:if>
<!-- default book collection does not include an address -->
<xsl:if test="$type='book' and .//mods:originInfo/mods:place/mods:placeTerm[@type='text']">
<field flags="6" title="Address" category="Publishing" format="4" type="1" name="address" i18n="true">
<prop name="bibtex">address</prop>
</field>
</xsl:if>
<!-- add illustrator -->
<xsl:if test=".//mods:mods/mods:name[@type='personal']/mods:role/mods:roleTerm[@authority='marcrelator' and @type='code'] = 'ill.'">
<field flags="7" title="Illustrator" category="General" format="2" type="1" name="illustrator" i18n="true"/>
</xsl:if>
<xsl:if test=".//mods:identifier[@type='issn']">
<field flags="0" title="ISSN#" category="Publishing" format="4" type="1" name="issn" description="ISSN#" />
</xsl:if>
</fields>
<!-- for now, go the route of bibliox, and assume only text records
with an originInfo/publisher or identifier[isbn] elements are actually books -->
<!-- Changed in Tellico 1.1, don't be so strict about the text thing, not every library
includes that in the mods output, so just check for publisher
Changed in Tellico 1.2.9, allow anything that has typeOfResource='text'
//mods:mods[(mods:typeOfResource='text' and -->
<xsl:for-each select=".//mods:mods[ mods:typeOfResource='text' or
mods:originInfo/mods:publisher or
mods:identifier[@type='isbn'] or
mods:identifier[@type='lccn'] ]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</collection>
</tellico>
</xsl:template>
<xsl:template match="mods:mods">
<entry>
<xsl:if test="$type='bibtex'">
<entry-type>
<xsl:choose>
<xsl:when test="mods:genre[@authority='xbib']='article'">
<xsl:text>article</xsl:text>
</xsl:when>
<xsl:when test="mods:genre[@authority='xbib']='book'">
<xsl:text>book</xsl:text>
</xsl:when>
<xsl:when test="mods:identifier[@type='isbn']">
<xsl:text>book</xsl:text>
</xsl:when>
<xsl:when test="mods:genre[@authority='marc']='theses'">
<xsl:text>phdthesis</xsl:text>
</xsl:when>
<xsl:when test="mods:relatedItem[@type='host']/mods:genre[@authority='marc']='periodical'">
<xsl:text>article</xsl:text>
</xsl:when>
<xsl:when test="mods:relatedItem[@type='host']/mods:genre[@authority='marc']='book'">
<xsl:text>inbook</xsl:text>
</xsl:when>
<xsl:when test="mods:relatedItem[@type='host']/mods:name[@type='conference']">
<xsl:text>inproceedings</xsl:text>
</xsl:when>
<xsl:when test="mods:relatedItem[@type='host']">
<xsl:text>incollection</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>book</xsl:text>
</xsl:otherwise>
</xsl:choose>
</entry-type>
<!-- identifier overrides @ID -->
<xsl:for-each select="(mods:identifier[@type='citekey']|@ID)[1]">
<bibtex-key>
<xsl:value-of select="."/>
</bibtex-key>
</xsl:for-each>
</xsl:if>
<title>
<xsl:value-of select="mods:titleInfo/mods:nonSort"/>
<xsl:value-of select="mods:titleInfo/mods:title"/>
</title>
<xsl:call-template name="names">
<xsl:with-param name="elem" select="'author'"/>
<xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'author' or
mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'creator']"/>
</xsl:call-template>
<xsl:call-template name="names">
<xsl:with-param name="elem" select="'editor'"/>
<xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'editor']"/>
</xsl:call-template>
<xsl:call-template name="names">
<xsl:with-param name="elem" select="'illustrator'"/>
<xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='code'] = 'ill.']"/>
</xsl:call-template>
<genres i18n="true">
<xsl:for-each select="mods:genre">
<genre>
<xsl:value-of select="."/>
</genre>
</xsl:for-each>
</genres>
<xsl:choose>
<xsl:when test="$npubs &gt; 1">
<publishers>
<xsl:apply-templates select="mods:originInfo/mods:publisher"/>
</publishers>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="mods:originInfo/mods:publisher"/>
</xsl:otherwise>
</xsl:choose>
<!-- prefer the marc encoding for year -->
<!-- force numbers...is that ok? -->
<xsl:variable name="year-type">
<xsl:choose>
<xsl:when test="$type='bibtex'">
<xsl:text>year</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>pub_year</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="mods:originInfo/mods:dateIssued[@encoding='marc']">
<xsl:element name="{$year-type}">
<xsl:call-template name="numbers">
<xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[@encoding='marc'][1]"/>
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:when test="mods:originInfo/mods:dateIssued">
<xsl:element name="{$year-type}">
<xsl:call-template name="numbers">
<xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[1]"/>
</xsl:call-template>
</xsl:element>
</xsl:when>
</xsl:choose>
<languages i18n="true">
<xsl:for-each select="mods:language/mods:languageTerm">
<language>
<xsl:apply-templates select="$langs-top">
<xsl:with-param name="lang-id" select="text()"/>
</xsl:apply-templates>
</language>
</xsl:for-each>
</languages>
<comments>
<xsl:for-each select="mods:note | mods:physicalDescription/*">
<xsl:value-of select="."/>
<!-- add separating line, Tellico understands HTML now -->
<xsl:text>&lt;br/&gt;&lt;br/&gt;</xsl:text>
</xsl:for-each>
</comments>
<keywords i18n="true">
<xsl:for-each select="mods:subject/mods:topic">
<keyword>
<xsl:value-of select="."/>
</keyword>
</xsl:for-each>
</keywords>
<xsl:apply-templates select="mods:relatedItem[@type='host'] |
mods:relatedItem[@type='series'] |
mods:part |
mods:identifier |
mods:subTitle |
mods:note |
mods:abstract |
mods:originInfo/mods:place |
mods:originInfo/mods:copyrightDate |
mods:originInfo/mods:edition |
mods:location/mods:url"/>
</entry>
</xsl:template>
<xsl:template match="mods:relatedItem">
<xsl:variable name="elem">
<xsl:choose>
<xsl:when test="@type='series'">
<xsl:text>series</xsl:text>
</xsl:when>
<xsl:when test="mods:genre[@authority='marc']='periodical'">
<xsl:text>journal</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>booktitle</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$elem}">
<xsl:value-of select="mods:titleInfo/mods:nonSort"/>
<xsl:value-of select="mods:titleInfo/mods:title"/>
<xsl:if test="not(mods:titleInfo) and mods:name[@type='conference']">
<xsl:apply-templates select="mods:name[@type='conference']"/>
</xsl:if>
</xsl:element>
<xsl:call-template name="names">
<xsl:with-param name="elem" select="'editor'"/>
<xsl:with-param name="nodes" select="mods:name[mods:role/mods:roleTerm[@authority='marcrelator' and @type='text'] = 'editor']"/>
</xsl:call-template>
<xsl:choose>
<xsl:when test="$npubs &gt; 1">
<publishers>
<xsl:apply-templates select="mods:originInfo/mods:publisher"/>
</publishers>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="mods:originInfo/mods:publisher"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="mods:originInfo/mods:dateIssued[@encoding='marc']">
<year>
<xsl:call-template name="numbers">
<xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[@encoding='marc'][1]"/>
</xsl:call-template>
</year>
</xsl:when>
<xsl:when test="mods:originInfo/mods:dateIssued">
<year>
<xsl:call-template name="numbers">
<xsl:with-param name="value" select="mods:originInfo/mods:dateIssued[1]"/>
</xsl:call-template>
</year>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="mods:part |
mods:originInfo/mods:place |
mods:identifier |
mods:part |
mods:location/mods:url"/>
</xsl:template>
<xsl:template match="mods:part">
<xsl:apply-templates select="mods:detail | mods:extent"/>
</xsl:template>
<xsl:template name="names">
<xsl:param name="elem"/>
<xsl:param name="nodes"/>
<xsl:if test="$nodes">
<xsl:element name="{concat($elem,'s')}">
<xsl:for-each select="$nodes">
<xsl:element name="{$elem}">
<xsl:apply-templates select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="mods:name">
<!-- specific order -->
<xsl:apply-templates select="mods:namePart[@type='given']"/>
<xsl:apply-templates select="mods:namePart[@type='family']"/>
<xsl:apply-templates select="mods:namePart[not(@type)]"/>
</xsl:template>
<xsl:template match="mods:namePart">
<xsl:value-of select="."/>
<!-- assume single-character name parts are initials -->
<xsl:if test="string-length()=1">
<xsl:text>.</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="mods:identifier">
<xsl:choose>
<xsl:when test="@type='isbn'">
<isbn>
<xsl:value-of select="."/>
</isbn>
</xsl:when>
<xsl:when test="@type='lccn'">
<lccn>
<xsl:value-of select="."/>
</lccn>
</xsl:when>
<xsl:when test="@type='doi'">
<doi>
<xsl:value-of select="."/>
</doi>
</xsl:when>
<xsl:when test="@type='issn'">
<issn>
<xsl:value-of select="."/>
</issn>
</xsl:when>
<xsl:when test="@type='uri'">
<url>
<xsl:value-of select="."/>
</url>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:subTitle">
<subtitle>
<xsl:value-of select="."/>
</subtitle>
</xsl:template>
<xsl:template match="mods:publisher">
<publisher>
<xsl:value-of select="."/>
</publisher>
</xsl:template>
<xsl:template match="mods:copyrightDate">
<cr_year>
<xsl:call-template name="numbers">
<xsl:with-param name="value" select="."/>
</xsl:call-template>
</cr_year>
</xsl:template>
<xsl:template match="mods:abstract">
<abstract>
<xsl:value-of select="."/>
</abstract>
</xsl:template>
<xsl:template match="mods:edition">
<edition i18n="true">
<xsl:value-of select="."/>
</edition>
</xsl:template>
<xsl:template match="mods:url">
<url>
<xsl:value-of select="."/>
</url>
</xsl:template>
<xsl:template match="mods:note">
<note>
<xsl:value-of select="."/>
</note>
</xsl:template>
<xsl:template match="mods:place">
<address>
<xsl:value-of select="mods:placeTerm[@type='text' or not(@type)][1]"/>
</address>
</xsl:template>
<xsl:template match="mods:detail">
<xsl:choose>
<xsl:when test="@type='volume'">
<volume>
<xsl:value-of select="mods:number"/>
</volume>
</xsl:when>
<xsl:when test="@type='issue'">
<number>
<xsl:value-of select="mods:number"/>
</number>
</xsl:when>
<xsl:when test="@type='number'">
<number>
<xsl:value-of select="mods:number"/>
</number>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="mods:extent">
<xsl:if test="@unit='page'">
<pages>
<xsl:choose>
<xsl:when test="mods:start and mods:end">
<xsl:value-of select="concat(mods:start,'-',mods:end)"/>
</xsl:when>
<xsl:when test="mods:list">
<xsl:value-of select="mods:list"/>
</xsl:when>
</xsl:choose>
</pages>
</xsl:if>
</xsl:template>
<xsl:template name="numbers">
<xsl:param name="value"/>
<xsl:value-of select="translate($value, translate($value, '0123456789', ''), '')"/>
</xsl:template>
<xsl:template match="l:langs">
<xsl:param name="lang-id"/>
<xsl:variable name="l" select="key('langs', $lang-id)"/>
<xsl:if test="$l">
<xsl:value-of select="$l"/>
</xsl:if>
<xsl:if test="not($l)">
<xsl:value-of select="$lang-id"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>