1 <?xml version="1.0" encoding="utf-8"?>
4 The contents of this file are subject to the license and copyright
5 detailed in the LICENSE and NOTICE files at the root of the source
6 tree and available online at
8 http://www.dspace.org/license/
11 <xsl:stylesheet version="1.0"
12 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:oai="http://www.openarchives.org/OAI/2.0/"
13 xmlns:koha="http://koha-community.org" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
14 xmlns:dc="http://purl.org/dc/doc:elements/1.1/" xmlns:marc="http://www.loc.gov/MARC21/slim"
15 xmlns:verb="http://informatik.hu-berlin.de/xmlverbatim"
16 xmlns:oai_id="http://www.openarchives.org/OAI/2.0/oai-identifier"
17 exclude-result-prefixes="oai oai_dc dc marc marcxml verb oai_id">
19 <xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" />
21 <xsl:variable name="oai_script_name">/cgi-bin/koha/oai.pl</xsl:variable>
23 <xsl:template match="/">
26 <title>Koha OAI-PMH Data Provider</title>
27 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
28 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
29 <script src="/opac-tmpl/bootstrap/lib/jquery/jquery.js" type="text/javascript" />
30 <script src="/opac-tmpl/bootstrap/lib/bootstrap/js/bootstrap.min.js" type="text/javascript" />
31 <link rel="stylesheet" href="/opac-tmpl/bootstrap/css/bootstrap-theme-oai.css" type="text/css" />
32 <link rel="stylesheet" href="/opac-tmpl/bootstrap/css/oai.css" type="text/css" />
35 <div class="container">
36 <div class="navbar navbar-default" role="navigation">
37 <div class="navbar-header">
38 <a class="navbar-brand" href="#">Koha OAI-PMH Data Provider</a>
40 <div class="navbar-collapse collapse">
41 <ul class="nav navbar-nav navbar-right">
43 <a title="Institutional information">
44 <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'Identify'">
45 <xsl:attribute name="class">active</xsl:attribute>
47 <xsl:attribute name="href">
49 select="concat($oai_script_name,'?verb=Identify')"></xsl:value-of>
55 <a title="Listing available sets">
56 <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListSets'">
57 <xsl:attribute name="class">active</xsl:attribute>
59 <xsl:attribute name="href">
61 select="concat($oai_script_name, '?verb=ListSets')"></xsl:value-of>
67 <a title="Listing records (with metadata)">
68 <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListRecords'">
69 <xsl:attribute name="class">active</xsl:attribute>
71 <xsl:attribute name="href">
73 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=oai_dc')"></xsl:value-of>
79 <a title="Listing identifiers only">
80 <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListIdentifiers'">
81 <xsl:attribute name="class">active</xsl:attribute>
83 <xsl:attribute name="href">
85 select="concat($oai_script_name, '?verb=ListIdentifiers&metadataPrefix=oai_dc')"></xsl:value-of>
91 <a title="Metadata Formats available">
93 test="/oai:OAI-PMH/oai:request/@verb = 'ListMetadataFormats'">
94 <xsl:attribute name="class">active</xsl:attribute>
96 <xsl:attribute name="href">
98 select="concat($oai_script_name, '?verb=ListMetadataFormats')"></xsl:value-of>
104 </div><!--/.nav-collapse -->
107 <div class="col-lg-offset-1 col-lg-10">
109 <h5>Response Date <small><xsl:value-of select="translate(oai:OAI-PMH/oai:responseDate/text(), 'TZ', ' ')" /></small></h5>
112 <xsl:apply-templates select="oai:OAI-PMH/oai:error" />
113 <xsl:apply-templates select="oai:OAI-PMH/oai:Identify" />
114 <xsl:apply-templates select="oai:OAI-PMH/oai:ListSets" />
115 <xsl:apply-templates select="oai:OAI-PMH/oai:ListRecords" />
116 <xsl:apply-templates select="oai:OAI-PMH/oai:ListIdentifiers" />
117 <xsl:apply-templates select="oai:OAI-PMH/oai:ListMetadataFormats" />
118 <xsl:apply-templates select="oai:OAI-PMH/oai:GetRecord" />
123 <div class="row-fluid text-center">
124 <div class="vertical-space"></div>
125 <p><small>Powered by <a href="http://koha-community.org">Koha</a></small></p>
132 <xsl:template match="oai:OAI-PMH/oai:error">
133 <div class="alert alert-danger">
136 <xsl:value-of select="text()"></xsl:value-of>
141 <xsl:template match="oai:OAI-PMH/oai:Identify">
142 <h2>Repository Information</h2>
144 <table class="table table-striped table-bordered">
146 <td><b>Repository Name</b></td>
147 <td><xsl:value-of select="oai:repositoryName/text()" /></td>
149 <xsl:for-each select="oai:adminEmail">
151 <td><b>E-Mail Contact</b></td>
154 <xsl:attribute name="href">
155 <xsl:value-of select="concat('mailto:', text())" />
157 <xsl:value-of select="text()" />
163 <td><b>Repository identifier</b></td>
165 <xsl:value-of select="oai:description/oai_id:oai-identifier/oai_id:repositoryIdentifier/text()" />
169 <td><b>Sample identifier</b></td>
172 select="oai:description/oai_id:oai-identifier/oai_id:sampleIdentifier/text()" />
176 <td><b>Protocol Version</b></td>
179 select="oai:protocolVersion/text()" />
184 <td><b>Earliest Registered Date</b></td>
187 select="translate(oai:earliestDatestamp/text(), 'TZ' ,' ')" />
192 <td><b>Date Granularity</b></td>
195 select="translate(oai:granularity/text(), 'TZ', ' ')" />
200 <td><b>Deletion Mode</b></td>
203 select="oai:deletedRecord/text()" />
210 <xsl:template match="oai:OAI-PMH/oai:ListSets">
211 <h2>List of Sets</h2>
213 <div class="well well-sm">
216 <xsl:call-template name="result-count">
217 <xsl:with-param name="path" select="oai:set" />
222 <div class="list-group">
223 <xsl:for-each select="oai:set">
224 <div class="list-group-item">
225 <h5 class="list-group-item-heading">
227 <xsl:when test="string-length(oai:setName/text()) > 83">
228 <xsl:value-of select="substring(oai:setName/text(),0, 80 )" />
232 <xsl:value-of select="oai:setName/text()" />
236 [<xsl:value-of select="oai:setSpec/text()" />]
241 <xsl:attribute name="href">
243 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=oai_dc&set=', oai:setSpec/text())" />
248 <xsl:attribute name="href">
250 select="concat($oai_script_name, '?verb=ListIdentifiers&metadataPrefix=oai_dc&set=', oai:setSpec/text())" />
259 <xsl:apply-templates select="oai:resumptionToken"/>
262 <xsl:template match="oai:OAI-PMH/oai:ListRecords">
263 <h2>List of Records</h2>
265 <div class="well well-sm">
268 <xsl:call-template name="result-count">
269 <xsl:with-param name="path" select="oai:record" />
274 <xsl:for-each select="oai:record">
275 <div class="panel panel-default">
276 <div class="panel-heading">
278 <div class="col-lg-6">
279 <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
281 <div class="col-lg-6">
282 <h5>Last Modified <small><xsl:value-of select="translate(oai:header/oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
286 <div class="panel-body">
287 <!-- If this record has a "status", display it as a warning -->
288 <xsl:if test="oai:header/@status">
289 <div class="alert alert-warning">Record Status: <xsl:value-of select="oai:header/@status"/></div>
291 <div class="panel panel-success">
292 <a data-toggle="collapse">
293 <xsl:attribute name="href">#sets<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
294 <div class="panel-heading">
295 <h5 class="panel-title">
300 <div class="panel-collapse collapse">
301 <xsl:attribute name="id">sets<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
302 <div class="panel-body list-group">
303 <xsl:for-each select="oai:header/oai:setSpec">
304 <div class="list-group-item">
306 <xsl:attribute name="href">
308 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=oai_dc&set=', text())" />
310 <xsl:value-of select="text()" />
317 <div class="panel panel-info">
318 <a data-toggle="collapse">
319 <xsl:attribute name="href">#<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
320 <div class="panel-heading">
321 <h5 class="panel-title">
326 <div class="panel-collapse collapse">
327 <xsl:attribute name="id"><xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
328 <div class="panel-body">
329 <xsl:apply-templates select="oai:metadata/*" />
337 <xsl:apply-templates select="oai:resumptionToken"/>
340 <xsl:template match="oai:OAI-PMH/oai:GetRecord">
341 <h2>Record Details</h2>
343 <xsl:for-each select="oai:record">
344 <div class="panel panel-default">
345 <div class="panel-heading">
347 <div class="col-lg-6">
348 <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
350 <div class="col-lg-6">
351 <h5>Last Modified <small><xsl:value-of select="translate(oai:header/oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
355 <div class="panel-body">
356 <!-- If this record has a "status", display it as a warning -->
357 <xsl:if test="oai:header/@status">
358 <div class="alert alert-warning">Record Status: <xsl:value-of select="oai:header/@status"/></div>
360 <div class="panel panel-success">
361 <div class="panel-heading">
362 <h5 class="panel-title">
366 <div class="panel-body list-group">
367 <xsl:for-each select="oai:header/oai:setSpec">
368 <div class="list-group-item">
370 <xsl:attribute name="href">
372 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=oai_dc&set=', text())" />
374 <xsl:value-of select="text()" />
380 <div class="panel panel-info">
381 <div class="panel-heading">
382 <h5 class="panel-title">
386 <div class="panel-body">
387 <xsl:apply-templates select="oai:metadata/*" />
395 <xsl:template match="oai:OAI-PMH/oai:ListIdentifiers">
396 <h2>List of Identifiers</h2>
398 <div class="well well-sm">
401 <xsl:call-template name="result-count">
402 <xsl:with-param name="path" select="oai:header" />
407 <xsl:for-each select="oai:header">
408 <div class="panel panel-default">
409 <div class="panel-heading">
411 <div class="col-lg-4">
412 <h5>Identifier <small><xsl:value-of select="oai:identifier/text()"></xsl:value-of></small></h5>
414 <div class="col-lg-4">
415 <h5>Last Modified <small><xsl:value-of select="translate(oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
417 <div class="col-lg-4">
418 <a class="btn btn-default pull-right">
419 <xsl:attribute name="href">
420 <xsl:value-of select="concat($oai_script_name, '?verb=GetRecord&metadataPrefix=oai_dc&identifier=', oai:identifier/text())" />
427 <div class="panel-body">
428 <!-- If this record has a "status", display it as a warning -->
429 <xsl:if test="@status">
430 <div class="alert alert-warning">Record Status: <xsl:value-of select="@status"/></div>
432 <div class="panel panel-success">
433 <a data-toggle="collapse">
434 <xsl:attribute name="href">#sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
435 <div class="panel-heading">
436 <h5 class="panel-title">
441 <div class="panel-collapse collapse">
442 <xsl:attribute name="id">sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
443 <div class="panel-body list-group">
444 <xsl:for-each select="oai:setSpec">
445 <div class="list-group-item">
447 <xsl:attribute name="href">
449 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=oai_dc&set=', text())" />
451 <xsl:value-of select="text()" />
462 <xsl:apply-templates select="oai:resumptionToken"/>
465 <xsl:template match="oai:OAI-PMH/oai:ListMetadataFormats">
466 <h2>List of Metadata Formats</h2>
468 <div class="well well-sm">
471 <xsl:value-of select="count(oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat)" />
475 <xsl:for-each select="oai:metadataFormat">
476 <div class="panel panel-default">
477 <div class="panel-heading">
479 <div class="col-lg-9">
480 <h5><xsl:value-of select="oai:metadataPrefix/text()"></xsl:value-of></h5>
482 <div class="col-lg-3">
483 <a class="btn btn-default pull-right">
484 <xsl:attribute name="href">
486 select="concat($oai_script_name, '?verb=ListRecords&metadataPrefix=', oai:metadataPrefix/text())" />
493 <div class="panel-body">
495 <div class="col-lg-9">
496 <h5>Namespace <small><xsl:value-of select="oai:metadataNamespace/text()"></xsl:value-of></small></h5>
497 <h5>Schema <small><xsl:value-of select="oai:schema/text()"></xsl:value-of></small></h5>
505 <xsl:template match="oai:resumptionToken">
506 <xsl:if test="text() != ''">
507 <div class="text-center">
508 <a class="btn btn-primary">
509 <xsl:attribute name="href">
510 <xsl:value-of select="concat($oai_script_name, '?verb=',/oai:OAI-PMH/oai:request/@verb,'&resumptionToken=', text())"></xsl:value-of>
518 <xsl:template name="result-count">
519 <xsl:param name="path" />
520 <xsl:variable name="cursor" select="$path/../oai:resumptionToken/@cursor" />
521 <xsl:variable name="count" select="count($path)" />
522 <xsl:variable name="total" select="$path/../oai:resumptionToken/@completeListSize" />
524 <xsl:when test="$cursor">
526 <xsl:when test="normalize-space($path/../oai:resumptionToken/text()) = ''">
527 <!-- on the last page of results we have to assume that @completeListSize is available -->
529 select="$total - $count" />
531 <xsl:value-of select="$total" />
534 <xsl:value-of select="$cursor + 1 - $count" />
536 <xsl:value-of select="$cursor" />
541 <xsl:value-of select="$count" />
544 <xsl:if test="$total">
546 <xsl:value-of select="$total" />
550 <xsl:template match="oai:metadata/*" priority='-20'>
551 <xsl:apply-templates select="." mode='xmlverb' />
554 <xsl:param name="indent-elements" select="false()" />
556 <xsl:template match="/" mode="xmlverb">
557 <xsl:text>
</xsl:text>
559 <xsl:text> converted by xmlverbatim.xsl 1.1, (c) O. Becker </xsl:text>
561 <xsl:text>
</xsl:text>
562 <div class="xmlverb-default">
563 <xsl:apply-templates mode="xmlverb">
564 <xsl:with-param name="indent-elements" select="$indent-elements" />
565 </xsl:apply-templates>
567 <xsl:text>
</xsl:text>
571 <xsl:template match="verb:wrapper">
572 <xsl:apply-templates mode="xmlverb">
573 <xsl:with-param name="indent-elements" select="$indent-elements" />
574 </xsl:apply-templates>
577 <xsl:template match="verb:wrapper" mode="xmlverb">
578 <xsl:apply-templates mode="xmlverb">
579 <xsl:with-param name="indent-elements" select="$indent-elements" />
580 </xsl:apply-templates>
583 <!-- element nodes -->
584 <xsl:template match="*" mode="xmlverb">
585 <xsl:param name="indent-elements" select="true()" />
586 <xsl:param name="indent" select="''" />
587 <xsl:param name="indent-increment" select="'   '" />
588 <xsl:if test="$indent-elements">
590 <xsl:value-of select="$indent" />
592 <xsl:text><</xsl:text>
593 <xsl:variable name="ns-prefix"
594 select="substring-before(name(),':')" />
595 <xsl:if test="$ns-prefix != ''">
596 <span class="xmlverb-element-nsprefix">
597 <xsl:value-of select="$ns-prefix"/>
599 <xsl:text>:</xsl:text>
601 <span class="xmlverb-element-name">
602 <xsl:value-of select="local-name()"/>
604 <xsl:variable name="pns" select="../namespace::*"/>
605 <xsl:if test="$pns[name()=''] and not(namespace::*[name()=''])">
606 <span class="xmlverb-ns-name">
607 <xsl:text> xmlns</xsl:text>
609 <xsl:text>=""</xsl:text>
611 <xsl:for-each select="namespace::*">
612 <xsl:if test="not($pns[name()=name(current()) and
614 <xsl:call-template name="xmlverb-ns" />
617 <xsl:for-each select="@*">
618 <xsl:call-template name="xmlverb-attrs" />
621 <xsl:when test="node()">
622 <xsl:text>></xsl:text>
623 <xsl:apply-templates mode="xmlverb">
624 <xsl:with-param name="indent-elements"
625 select="$indent-elements"/>
626 <xsl:with-param name="indent"
627 select="concat($indent, $indent-increment)"/>
628 <xsl:with-param name="indent-increment"
629 select="$indent-increment"/>
630 </xsl:apply-templates>
631 <xsl:if test="* and $indent-elements">
633 <xsl:value-of select="$indent" />
635 <xsl:text></</xsl:text>
636 <xsl:if test="$ns-prefix != ''">
637 <span class="xmlverb-element-nsprefix">
638 <xsl:value-of select="$ns-prefix"/>
640 <xsl:text>:</xsl:text>
642 <span class="xmlverb-element-name">
643 <xsl:value-of select="local-name()"/>
645 <xsl:text>></xsl:text>
648 <xsl:text> /></xsl:text>
651 <xsl:if test="not(parent::*)"><br /><xsl:text>
</xsl:text></xsl:if>
654 <!-- attribute nodes -->
655 <xsl:template name="xmlverb-attrs">
656 <xsl:text> </xsl:text>
657 <span class="xmlverb-attr-name">
658 <xsl:value-of select="name()"/>
660 <xsl:text>="</xsl:text>
661 <span class="xmlverb-attr-content">
662 <xsl:call-template name="html-replace-entities">
663 <xsl:with-param name="text" select="normalize-space(.)" />
664 <xsl:with-param name="attrs" select="true()" />
667 <xsl:text>"</xsl:text>
670 <!-- namespace nodes -->
671 <xsl:template name="xmlverb-ns">
672 <xsl:if test="name()!='xml'">
673 <span class="xmlverb-ns-name">
674 <xsl:text> xmlns</xsl:text>
675 <xsl:if test="name()!=''">
676 <xsl:text>:</xsl:text>
678 <xsl:value-of select="name()"/>
680 <xsl:text>="</xsl:text>
681 <span class="xmlverb-ns-uri">
682 <xsl:value-of select="."/>
684 <xsl:text>"</xsl:text>
689 <xsl:template match="text()" mode="xmlverb">
690 <span class="xmlverb-text">
691 <xsl:call-template name="preformatted-output">
692 <xsl:with-param name="text">
693 <xsl:call-template name="html-replace-entities">
694 <xsl:with-param name="text" select="." />
702 <xsl:template match="comment()" mode="xmlverb">
703 <xsl:text><!--</xsl:text>
704 <span class="xmlverb-comment">
705 <xsl:call-template name="preformatted-output">
706 <xsl:with-param name="text" select="." />
709 <xsl:text>--></xsl:text>
710 <xsl:if test="not(parent::*)"><br /><xsl:text>
</xsl:text></xsl:if>
713 <!-- processing instructions -->
714 <xsl:template match="processing-instruction()" mode="xmlverb">
715 <xsl:text><?</xsl:text>
716 <span class="xmlverb-pi-name">
717 <xsl:value-of select="name()"/>
719 <xsl:if test=".!=''">
720 <xsl:text> </xsl:text>
721 <span class="xmlverb-pi-content">
722 <xsl:value-of select="."/>
725 <xsl:text>?></xsl:text>
726 <xsl:if test="not(parent::*)"><br /><xsl:text>
</xsl:text></xsl:if>
730 <!-- =========================================================== -->
731 <!-- Procedures / Functions -->
732 <!-- =========================================================== -->
734 <!-- generate entities by replacing &, ", < and > in $text -->
735 <xsl:template name="html-replace-entities">
736 <xsl:param name="text" />
737 <xsl:param name="attrs" />
738 <xsl:variable name="tmp">
739 <xsl:call-template name="replace-substring">
740 <xsl:with-param name="from" select="'>'" />
741 <xsl:with-param name="to" select="'&gt;'" />
742 <xsl:with-param name="value">
743 <xsl:call-template name="replace-substring">
744 <xsl:with-param name="from" select="'<'" />
745 <xsl:with-param name="to" select="'&lt;'" />
746 <xsl:with-param name="value">
747 <xsl:call-template name="replace-substring">
748 <xsl:with-param name="from"
750 <xsl:with-param name="to"
751 select="'&amp;'" />
752 <xsl:with-param name="value"
761 <!-- $text is an attribute value -->
762 <xsl:when test="$attrs">
763 <xsl:call-template name="replace-substring">
764 <xsl:with-param name="from" select="'
'" />
765 <xsl:with-param name="to" select="'&#xA;'" />
766 <xsl:with-param name="value">
767 <xsl:call-template name="replace-substring">
768 <xsl:with-param name="from"
770 <xsl:with-param name="to"
771 select="'&quot;'" />
772 <xsl:with-param name="value" select="$tmp" />
778 <xsl:value-of select="$tmp" />
783 <!-- replace in $value substring $from with $to -->
784 <xsl:template name="replace-substring">
785 <xsl:param name="value" />
786 <xsl:param name="from" />
787 <xsl:param name="to" />
789 <xsl:when test="contains($value,$from)">
790 <xsl:value-of select="substring-before($value,$from)" />
791 <xsl:value-of select="$to" />
792 <xsl:call-template name="replace-substring">
793 <xsl:with-param name="value"
794 select="substring-after($value,$from)" />
795 <xsl:with-param name="from" select="$from" />
796 <xsl:with-param name="to" select="$to" />
800 <xsl:value-of select="$value" />
805 <!-- preformatted output: space as , tab as 8
807 <xsl:template name="preformatted-output">
808 <xsl:param name="text" />
809 <xsl:call-template name="output-nl">
810 <xsl:with-param name="text">
811 <xsl:call-template name="replace-substring">
812 <xsl:with-param name="value"
813 select="translate($text,' ',' ')" />
814 <xsl:with-param name="from" select="'	'" />
815 <xsl:with-param name="to"
816 select="'        '" />
822 <!-- output nl as <br> -->
823 <xsl:template name="output-nl">
824 <xsl:param name="text" />
826 <xsl:when test="contains($text,'
')">
827 <xsl:value-of select="substring-before($text,'
')" />
829 <xsl:text>
</xsl:text>
830 <xsl:call-template name="output-nl">
831 <xsl:with-param name="text"
832 select="substring-after($text,'
')" />
836 <xsl:value-of select="$text" />