About Features Downloads Getting Started Documentation Events Support

Site Tools


How to index DSpace with VuFind

These are the instructions used by the Naval Postgraduate School in Monterey, California to index DSpace records in VuFind.

:!: These instructions were written for VuFind 1.x; VuFind 2.x includes a DSpace example in the standard distribution, so most of the steps below are unnecessary in newer releases


OAI must be enabled on the DSpace repository first:

  1. Modify the DSpace server config in nginx.conf on the DSpace server:
    Location /oai/ {
        Proxy_set_header X-Forwarded-Host $host;
        Proxy_set_header X-Forwarded-Server $host;
        Proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        Proxy_pass http://yourdspacehostname:8080/oai/;
        Proxy_redirect http://yourdspacehostname:8080/oai/  http://yourdspacehostname/oai;
        Proxy_buffering off;
        Proxy_store off;
        Proxy_connect_timeout 120;
        Proxy_send_timeout 120;
        Proxy_read_timeout 120;

    Comparable configuration in Apache makes use of mod_proxy. Note that the proxy configuration is only necessary if you are unable to open port 8080 to your VuFind instance. If you are not limited by such restrictions, feel free to use your full DSpace hostname appended with “:8080” and skip the above proxy configuration.

  2. Modify the server.xml for the appropriate DSpace Tomcat instance in the HOST block:
    <Context path="/oai" docBase="/path_to_dspace/webapps/oai" debug="0"
        Reloadable="true" cachingAllowed="false"
        allowLinking="true" />
  3. Modify the dspace.conf config file for the appropriate DSpace instance:
    harvest.includerestricted.oai = true
    harvester.autoStart = true

Then you may proceed to import the OAI feed into VuFind:

  1. Modify $VUFIND_HOME/harvest/oai.ini as per oai.ini below
  2. Modify $VUFIND_HOME/import/dspace.properties as per dspace.properties below
  3. Modify $VUFIND_HOME/import/xsl/dspace.xsl as per dspace.xsl below
  4. Modify $VUFIND_HOME/web/RecordDrivers/DspaceRecord.php as per DspaceRecord.php below
  5. cd $VUFIND_HOME/harvest
  6. php harvest_oai.php
  7. sh batch-import-xsl.sh ./DSpace ../import/dspace.properties
  8. ../vufind.sh restart

Required Files




xslt = dspace.xsl
custom_class[] = VuFind

institution = "Library"
collection = "DSpace"


<!-- available fields are defined in solr/biblio/conf/schema.xml -->
<xsl:stylesheet version="1.0"
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>
    <xsl:param name="institution">My University</xsl:param>
    <xsl:param name="collection">DSpace</xsl:param>
    <xsl:param name="urlPrefix">http</xsl:param>
    <xsl:template match="oai_dc:dc">
                <!-- ID -->
                <!-- Important: This relies on an <identifier> tag being injected by the OAI-PMH harvester. -->
                <field name="id">
                    <xsl:value-of select="//identifier"/>

                <!-- RECORDTYPE -->
                <field name="recordtype">dspace</field>

                <!-- FULLRECORD -->
                <!-- disabled for now; records are so large that they cause memory problems!
                <field name="fullrecord">
                    <xsl:copy-of select="php:function('VuFind::xmlAsText', //oai_dc:dc)"/>

                <!-- ALLFIELDS -->
                <field name="allfields">
                    <xsl:value-of select="normalize-space(string(//oai_dc:dc))"/>

                <!-- INSTITUTION -->
                <field name="institution">
                    <xsl:value-of select="$institution" />

                <!-- COLLECTION -->
                <field name="collection">
                    <xsl:value-of select="$collection" />

                <!-- LANGUAGE -->
                <xsl:if test="//dc:language">
                    <xsl:for-each select="//dc:language">
                        <xsl:if test="string-length() > 0">
                            <field name="language">
                                <xsl:value-of select="php:function('VuFind::mapString', normalize-space(string(.)), 'language_map_iso639-1.properties')"/>

                <!-- FORMAT -->
                <!-- populating the format field with dc.type instead, see TYPE below.
                     if you like, you can uncomment this to add a hard-coded format
                     in addition to the dynamic ones extracted from the record.
                <field name="format">Online</field>

                <!-- SUBJECT -->
                <xsl:if test="//dc:subject">
                    <xsl:for-each select="//dc:subject">
                        <xsl:if test="string-length() > 0">
                            <field name="topic">
                                <xsl:value-of select="normalize-space()"/>

                <!-- DESCRIPTION -->
                <xsl:if test="//dc:description">
                    <field name="description">
                        <xsl:value-of select="//dc:description" />

                <!-- ADVISOR / CONTRIBUTOR -->
                <xsl:if test="//dc:contributor[normalize-space()]">
                    <field name="author_additional">
                        <xsl:value-of select="//dc:contributor[normalize-space()]" />
                <!-- TYPE -->
                <xsl:if test="//dc:type">
                    <field name="format">
                        <xsl:value-of select="//dc:type" />

                <!-- AUTHOR -->
                <xsl:if test="//dc:creator">
                    <xsl:for-each select="//dc:creator">
                        <xsl:if test="normalize-space()">
                            <!-- author is not a multi-valued field, so we'll put
                                 first value there and subsequent values in author2.
                            <xsl:if test="position()=1">
                                <field name="author">
                                    <xsl:value-of select="normalize-space()"/>
                                <field name="author-letter">
                                    <xsl:value-of select="normalize-space()"/>
                            <xsl:if test="position()>1">
                                <field name="author2">
                                    <xsl:value-of select="normalize-space()"/>

                <!-- TITLE -->
                <xsl:if test="//dc:title[normalize-space()]">
                    <field name="title">
                        <xsl:value-of select="//dc:title[normalize-space()]"/>
                    <field name="title_short">
                        <xsl:value-of select="//dc:title[normalize-space()]"/>
                    <field name="title_full">
                        <xsl:value-of select="//dc:title[normalize-space()]"/>
                    <field name="title_sort">
                        <xsl:value-of select="php:function('VuFind::stripArticles', string(//dc:title[normalize-space()]))"/>

                <!-- PUBLISHER -->
                <xsl:if test="//dc:publisher[normalize-space()]">
                    <field name="publisher">
                        <xsl:value-of select="//dc:publisher[normalize-space()]"/>

                <!-- PUBLISHDATE -->
                <xsl:if test="//dc:date">
                    <field name="publishDate">
                        <xsl:value-of select="substring(//dc:date, 1, 4)"/>
                    <field name="publishDateSort">
                        <xsl:value-of select="substring(//dc:date, 1, 4)"/>

                <!-- URL -->
               <xsl:for-each select="//dc:identifier">
                   <xsl:if test="substring(., 1, string-length($urlPrefix)) = $urlPrefix">
                       <field name="url">
                           <xsl:value-of select="." />


require_once 'RecordDrivers/IndexRecord.php';
class DspaceRecord extends IndexRecord {
     public function getSearchResult ($view = "list") {
          global $interface;
          $template = parent :: getSearchResult ();
          $interface -> assign ('summAjaxStatus', false); //Don't show Callnumber and Location
          $interface -> assign ('summDate', false); //Don't show date
          $interface -> assign ('summPublisher', $this->getPublishers()); //Show publisher name
          $interface -> assign ('summNotes', false); //Preventing to show any general note
          return $template;
indexing/dspace.txt · Last modified: 2015/12/14 11:31 by demiankatz