Bug 34434: Terminology: Biblio should be bibliographic
[koha.git] / koha-tmpl / opac-tmpl / xslt / OAI.xslt
1 <?xml version="1.0" encoding="utf-8"?>
2 <!--
3
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
7
8     http://www.dspace.org/license/
9
10 -->
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">
18
19     <xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd" />
20
21     <xsl:variable name="oai_script_name">/cgi-bin/koha/oai.pl</xsl:variable>
22
23     <xsl:template match="/">
24         <html>
25             <head>
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/lib/jquery/jquery-3.6.0.min.js"></script>
30                 <script src="/opac-tmpl/lib/jquery/jquery-migrate-3.3.2.min.js"></script>
31                 <script src="/opac-tmpl/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
32                 <link rel="stylesheet" href="/opac-tmpl/bootstrap/css/bootstrap-theme-oai.css" type="text/css" />
33                 <link rel="stylesheet" href="/opac-tmpl/bootstrap/css/oai.css" type="text/css" />
34             </head>
35             <body>
36                 <div class="container">
37                     <div class="navbar navbar-default" role="navigation">
38                         <div class="navbar-header">
39                             <a class="navbar-brand" href="#">Koha OAI-PMH Data Provider</a>
40                         </div>
41                         <div class="navbar-collapse collapse">
42                             <ul class="nav navbar-nav navbar-right">
43                                 <li>
44                                     <a title="Institutional information">
45                                         <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'Identify'">
46                                             <xsl:attribute name="class">active</xsl:attribute>
47                                         </xsl:if>
48                                         <xsl:attribute name="href">
49                                             <xsl:value-of
50                                                     select="concat($oai_script_name,'?verb=Identify')"></xsl:value-of>
51                                         </xsl:attribute>
52                                         Identify
53                                     </a>
54                                 </li>
55                                 <li>
56                                     <a title="Listing available sets">
57                                         <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListSets'">
58                                             <xsl:attribute name="class">active</xsl:attribute>
59                                         </xsl:if>
60                                         <xsl:attribute name="href">
61                                             <xsl:value-of
62                                                     select="concat($oai_script_name, '?verb=ListSets')"></xsl:value-of>
63                                         </xsl:attribute>
64                                         Sets
65                                     </a>
66                                 </li>
67                                 <li>
68                                     <a title="Listing records (with metadata)">
69                                         <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListRecords'">
70                                             <xsl:attribute name="class">active</xsl:attribute>
71                                         </xsl:if>
72                                         <xsl:attribute name="href">
73                                             <xsl:value-of
74                                                     select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc')"></xsl:value-of>
75                                         </xsl:attribute>
76                                         Records
77                                     </a>
78                                 </li>
79                                 <li>
80                                     <a title="Listing identifiers only">
81                                         <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'ListIdentifiers'">
82                                             <xsl:attribute name="class">active</xsl:attribute>
83                                         </xsl:if>
84                                         <xsl:attribute name="href">
85                                             <xsl:value-of
86                                                     select="concat($oai_script_name, '?verb=ListIdentifiers&amp;metadataPrefix=oai_dc')"></xsl:value-of>
87                                         </xsl:attribute>
88                                         Identifiers
89                                     </a>
90                                 </li>
91                                 <li>
92                                     <a title="Metadata Formats available">
93                                         <xsl:if
94                                                 test="/oai:OAI-PMH/oai:request/@verb = 'ListMetadataFormats'">
95                                             <xsl:attribute name="class">active</xsl:attribute>
96                                         </xsl:if>
97                                         <xsl:attribute name="href">
98                                             <xsl:value-of
99                                                     select="concat($oai_script_name, '?verb=ListMetadataFormats')"></xsl:value-of>
100                                         </xsl:attribute>
101                                         Metadata Formats
102                                     </a>
103                                 </li>
104                             </ul>
105                         </div><!--/.nav-collapse -->
106                     </div>
107                     <div class="row">
108                         <div class="col-lg-offset-1 col-lg-10">
109                             <div class="row">
110                                 <h5>Response Date <small><xsl:value-of select="translate(oai:OAI-PMH/oai:responseDate/text(), 'TZ', ' ')" /></small></h5>
111                             </div>
112                             <div class="row">
113                                 <xsl:apply-templates select="oai:OAI-PMH/oai:error" />
114                                 <xsl:apply-templates select="oai:OAI-PMH/oai:Identify" />
115                                 <xsl:apply-templates select="oai:OAI-PMH/oai:ListSets" />
116                                 <xsl:apply-templates select="oai:OAI-PMH/oai:ListRecords" />
117                                 <xsl:apply-templates select="oai:OAI-PMH/oai:ListIdentifiers" />
118                                 <xsl:apply-templates select="oai:OAI-PMH/oai:ListMetadataFormats" />
119                                 <xsl:apply-templates select="oai:OAI-PMH/oai:GetRecord" />
120                             </div>
121                         </div>
122                     </div>
123
124                     <div class="row-fluid text-center">
125                         <div class="vertical-space"></div>
126                         <p><small>Powered by <a href="http://koha-community.org">Koha</a></small></p>
127                     </div>
128                 </div>
129             </body>
130         </html>
131     </xsl:template>
132
133     <xsl:template match="oai:OAI-PMH/oai:error">
134         <div class="alert alert-danger">
135             <h4>Error</h4>
136             <p>
137                 <xsl:value-of select="text()"></xsl:value-of>
138             </p>
139         </div>
140     </xsl:template>
141
142     <xsl:template match="oai:OAI-PMH/oai:Identify">
143         <h2>Repository Information</h2>
144         <hr />
145         <table class="table table-striped table-bordered">
146             <tr>
147                 <td><strong>Repository Name</strong></td>
148                 <td><xsl:value-of select="oai:repositoryName/text()" /></td>
149             </tr>
150             <xsl:for-each select="oai:adminEmail">
151                 <tr>
152                     <td><strong>E-Mail Contact</strong></td>
153                     <td>
154                         <a>
155                             <xsl:attribute name="href">
156                                 <xsl:value-of select="concat('mailto:', text())" />
157                             </xsl:attribute>
158                             <xsl:value-of select="text()" />
159                         </a>
160                     </td>
161                 </tr>
162             </xsl:for-each>
163             <tr>
164                 <td><strong>Repository identifier</strong></td>
165                 <td>
166                     <xsl:value-of select="oai:description/oai_id:oai-identifier/oai_id:repositoryIdentifier/text()" />
167                 </td>
168             </tr>
169             <tr>
170                 <td><strong>Sample identifier</strong></td>
171                 <td>
172                     <xsl:value-of
173                             select="oai:description/oai_id:oai-identifier/oai_id:sampleIdentifier/text()" />
174                 </td>
175             </tr>
176             <tr>
177                 <td><strong>Protocol Version</strong></td>
178                 <td>
179                     <xsl:value-of
180                             select="oai:protocolVersion/text()" />
181                 </td>
182
183             </tr>
184             <tr>
185                 <td><strong>Earliest Registered Date</strong></td>
186                 <td>
187                     <xsl:value-of
188                             select="translate(oai:earliestDatestamp/text(), 'TZ' ,' ')" />
189                 </td>
190
191             </tr>
192             <tr>
193                 <td><strong>Date Granularity</strong></td>
194                 <td>
195                     <xsl:value-of
196                             select="translate(oai:granularity/text(), 'TZ', ' ')" />
197                 </td>
198
199             </tr>
200             <tr>
201                 <td><strong>Deletion Mode</strong></td>
202                 <td>
203                     <xsl:value-of
204                             select="oai:deletedRecord/text()" />
205                 </td>
206
207             </tr>
208         </table>
209     </xsl:template>
210
211     <xsl:template match="oai:OAI-PMH/oai:ListSets">
212         <h2>List of Sets</h2>
213         <hr />
214         <div class="well well-sm">
215             <h4>Results fetched
216                 <small>
217                     <xsl:call-template name="result-count">
218                         <xsl:with-param name="path" select="oai:set" />
219                     </xsl:call-template>
220                 </small>
221             </h4>
222         </div>
223         <div class="list-group">
224             <xsl:for-each select="oai:set">
225                 <div class="list-group-item">
226                     <h5 class="list-group-item-heading">
227                         <xsl:choose>
228                             <xsl:when test="string-length(oai:setName/text()) &gt; 83">
229                                 <xsl:value-of select="substring(oai:setName/text(),0, 80 )" />
230                                 ...
231                             </xsl:when>
232                             <xsl:otherwise>
233                                 <xsl:value-of select="oai:setName/text()" />
234                             </xsl:otherwise>
235                         </xsl:choose>
236                         <small>
237                             [<xsl:value-of select="oai:setSpec/text()" />]
238                         </small>
239                     </h5>
240                     <div class="spec">
241                         <a>
242                             <xsl:attribute name="href">
243                                 <xsl:value-of
244                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', oai:setSpec/text())" />
245                             </xsl:attribute>
246                             Records
247                         </a>
248                         <a>
249                             <xsl:attribute name="href">
250                                 <xsl:value-of
251                                         select="concat($oai_script_name, '?verb=ListIdentifiers&amp;metadataPrefix=oai_dc&amp;set=', oai:setSpec/text())" />
252                             </xsl:attribute>
253                             Identifiers
254                         </a>
255                     </div>
256                 </div>
257             </xsl:for-each>
258         </div>
259
260         <xsl:apply-templates select="oai:resumptionToken"/>
261     </xsl:template>
262
263     <xsl:template match="oai:OAI-PMH/oai:ListRecords">
264         <h2>List of Records</h2>
265         <hr />
266         <div class="well well-sm">
267             <h4>Results fetched
268                 <small>
269                     <xsl:call-template name="result-count">
270                         <xsl:with-param name="path" select="oai:record" />
271                     </xsl:call-template>
272                 </small>
273             </h4>
274         </div>
275         <xsl:for-each select="oai:record">
276             <div class="panel panel-default">
277                 <div class="panel-heading">
278                     <div class="row">
279                         <div class="col-lg-6">
280                             <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
281                         </div>
282                         <div class="col-lg-6">
283                             <h5>Last Modified <small><xsl:value-of select="translate(oai:header/oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
284                         </div>
285                     </div>
286                 </div>
287                 <div class="panel-body">
288                     <!-- If this record has a "status", display it as a warning -->
289                     <xsl:if test="oai:header/@status">
290                       <div class="alert alert-warning">Record Status: <xsl:value-of select="oai:header/@status"/></div>
291                     </xsl:if>
292                     <div class="panel panel-success">
293                         <a data-toggle="collapse">
294                             <xsl:attribute name="href">#sets<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
295                             <div class="panel-heading">
296                                 <h5 class="panel-title">
297                                     Sets
298                                 </h5>
299                             </div>
300                         </a>
301                         <div class="panel-collapse collapse">
302                             <xsl:attribute name="id">sets<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
303                             <div class="panel-body list-group">
304                                 <xsl:for-each select="oai:header/oai:setSpec">
305                                     <div class="list-group-item">
306                                         <a>
307                                             <xsl:attribute name="href">
308                                                 <xsl:value-of
309                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
310                                             </xsl:attribute>
311                                             <xsl:value-of select="text()" />
312                                         </a>
313                                     </div>
314                                 </xsl:for-each>
315                             </div>
316                         </div>
317                     </div>
318                     <div class="panel panel-info">
319                         <a data-toggle="collapse">
320                             <xsl:attribute name="href">#<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
321                             <div class="panel-heading">
322                                 <h5 class="panel-title">
323                                         Metadata
324                                 </h5>
325                             </div>
326                         </a>
327                         <div class="panel-collapse collapse">
328                             <xsl:attribute name="id"><xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
329                             <div class="panel-body">
330                                 <xsl:apply-templates select="oai:metadata/*" />
331                             </div>
332                         </div>
333                     </div>
334                     <xsl:if test="oai:about">
335                         <div class="panel panel-success">
336                             <a data-toggle="collapse">
337                                 <xsl:attribute name="href">#about<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
338                                 <div class="panel-heading">
339                                     <h5 class="panel-title">
340                                         About
341                                     </h5>
342                                 </div>
343                             </a>
344                             <div class="panel-collapse collapse">
345                                 <xsl:attribute name="id">about<xsl:value-of select="translate(oai:header/oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
346                                 <div class="panel-body list-group">
347                                     <xsl:for-each select="oai:about">
348                                         <div class="list-group-item">
349                                             <span>
350                                                 <xsl:choose>
351                                                     <xsl:when test="text()='INVALID_METADATA'">
352                                                         There was a problem decoding the metadata for this record, an attempt was made to ignore invalid characters, the metadata view may be degraded. See system logs for details
353                                                     </xsl:when>
354                                                     <xsl:otherwise>
355                                                         <xsl:value-of select="text()" />
356                                                     </xsl:otherwise>
357                                                 </xsl:choose>
358                                             </span>
359                                         </div>
360                                     </xsl:for-each>
361                                 </div>
362                             </div>
363                         </div>
364                     </xsl:if>
365                 </div>
366             </div>
367         </xsl:for-each>
368
369         <xsl:apply-templates select="oai:resumptionToken"/>
370     </xsl:template>
371
372     <xsl:template match="oai:OAI-PMH/oai:GetRecord">
373         <h2>Record Details</h2>
374         <hr />
375         <xsl:for-each select="oai:record">
376             <div class="panel panel-default">
377                 <div class="panel-heading">
378                     <div class="row">
379                         <div class="col-lg-6">
380                             <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
381                         </div>
382                         <div class="col-lg-6">
383                             <h5>Last Modified <small><xsl:value-of select="translate(oai:header/oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
384                         </div>
385                     </div>
386                 </div>
387                 <div class="panel-body">
388                     <!-- If this record has a "status", display it as a warning -->
389                     <xsl:if test="oai:header/@status">
390                       <div class="alert alert-warning">Record Status: <xsl:value-of select="oai:header/@status"/></div>
391                     </xsl:if>
392                     <div class="panel panel-success">
393                             <div class="panel-heading">
394                                 <h5 class="panel-title">
395                                     Sets
396                                 </h5>
397                             </div>
398                             <div class="panel-body list-group">
399                                 <xsl:for-each select="oai:header/oai:setSpec">
400                                     <div class="list-group-item">
401                                         <a>
402                                             <xsl:attribute name="href">
403                                                 <xsl:value-of
404                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
405                                             </xsl:attribute>
406                                             <xsl:value-of select="text()" />
407                                         </a>
408                                     </div>
409                                 </xsl:for-each>
410                             </div>
411                     </div>
412                     <div class="panel panel-info">
413                             <div class="panel-heading">
414                                 <h5 class="panel-title">
415                                     Metadata
416                                 </h5>
417                             </div>
418                             <div class="panel-body">
419                                 <xsl:apply-templates select="oai:metadata/*" />
420                             </div>
421                     </div>
422                     <xsl:if test="oai:about">
423                         <div class="panel panel-info">
424                                 <div class="panel-heading">
425                                     <h5 class="panel-title">
426                                         About
427                                     </h5>
428                                 </div>
429                                 <div class="panel-body list-group">
430                                     <xsl:for-each select="oai:about">
431                                         <div class="list-group-item">
432                                             <span>
433                                                 <xsl:choose>
434                                                     <xsl:when test="text()='INVALID_METADATA'">
435                                                         There was a problem decoding the metadata for this record, invalid characters were stripped. See system logs for details
436                                                     </xsl:when>
437                                                     <xsl:otherwise>
438                                                         <xsl:value-of select="text()" />
439                                                     </xsl:otherwise>
440                                                 </xsl:choose>
441                                             </span>
442                                         </div>
443                                     </xsl:for-each>
444                                 </div>
445                         </div>
446                     </xsl:if>
447                 </div>
448             </div>
449         </xsl:for-each>
450     </xsl:template>
451
452     <xsl:template match="oai:OAI-PMH/oai:ListIdentifiers">
453         <h2>List of Identifiers</h2>
454         <hr />
455         <div class="well well-sm">
456             <h4>Results fetched
457                 <small>
458                     <xsl:call-template name="result-count">
459                         <xsl:with-param name="path" select="oai:header" />
460                     </xsl:call-template>
461                 </small>
462             </h4>
463         </div>
464         <xsl:for-each select="oai:header">
465             <div class="panel panel-default">
466                 <div class="panel-heading">
467                     <div class="row">
468                         <div class="col-lg-4">
469                             <h5>Identifier <small><xsl:value-of select="oai:identifier/text()"></xsl:value-of></small></h5>
470                         </div>
471                         <div class="col-lg-4">
472                             <h5>Last Modified <small><xsl:value-of select="translate(oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
473                         </div>
474                         <div class="col-lg-4">
475                             <a class="btn btn-default pull-right">
476                                 <xsl:attribute name="href">
477                                     <xsl:value-of select="concat($oai_script_name, '?verb=GetRecord&amp;metadataPrefix=oai_dc&amp;identifier=', oai:identifier/text())" />
478                                 </xsl:attribute>
479                                 View Details
480                             </a>
481                         </div>
482                     </div>
483                 </div>
484                 <div class="panel-body">
485                     <!-- If this record has a "status", display it as a warning -->
486                     <xsl:if test="@status">
487                       <div class="alert alert-warning">Record Status: <xsl:value-of select="@status"/></div>
488                     </xsl:if>
489                     <div class="panel panel-success">
490                         <a data-toggle="collapse">
491                             <xsl:attribute name="href">#sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
492                             <div class="panel-heading">
493                                 <h5 class="panel-title">
494                                     Sets
495                                 </h5>
496                             </div>
497                         </a>
498                         <div class="panel-collapse collapse">
499                             <xsl:attribute name="id">sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
500                             <div class="panel-body list-group">
501                                 <xsl:for-each select="oai:setSpec">
502                                     <div class="list-group-item">
503                                         <a>
504                                             <xsl:attribute name="href">
505                                                 <xsl:value-of
506                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
507                                             </xsl:attribute>
508                                             <xsl:value-of select="text()" />
509                                         </a>
510                                     </div>
511                                 </xsl:for-each>
512                             </div>
513                         </div>
514                     </div>
515                 </div>
516             </div>
517         </xsl:for-each>
518
519         <xsl:apply-templates select="oai:resumptionToken"/>
520     </xsl:template>
521
522     <xsl:template match="oai:OAI-PMH/oai:ListMetadataFormats">
523         <h2>List of Metadata Formats</h2>
524         <hr />
525         <div class="well well-sm">
526             <h4>Results fetched
527                 <small>
528                     <xsl:value-of select="count(oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat)" />
529                 </small>
530             </h4>
531         </div>
532         <xsl:for-each select="oai:metadataFormat">
533             <div class="panel panel-default">
534                 <div class="panel-heading">
535                     <div class="row">
536                         <div class="col-lg-9">
537                             <h5><xsl:value-of select="oai:metadataPrefix/text()"></xsl:value-of></h5>
538                         </div>
539                         <div class="col-lg-3">
540                             <a class="btn btn-default pull-right">
541                                 <xsl:attribute name="href">
542                                     <xsl:value-of
543                                             select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=', oai:metadataPrefix/text())" />
544                                 </xsl:attribute>
545                                 List Records
546                             </a>
547                         </div>
548                     </div>
549                 </div>
550                 <div class="panel-body">
551                     <div class="row">
552                         <div class="col-lg-9">
553                             <h5>Namespace <small><xsl:value-of select="oai:metadataNamespace/text()"></xsl:value-of></small></h5>
554                             <h5>Schema <small><xsl:value-of select="oai:schema/text()"></xsl:value-of></small></h5>
555                         </div>
556                     </div>
557                 </div>
558             </div>
559         </xsl:for-each>
560     </xsl:template>
561
562     <xsl:template match="oai:resumptionToken">
563         <xsl:if test="text() != ''">
564             <div class="text-center">
565                 <a class="btn btn-primary">
566                 <xsl:attribute name="href">
567                     <xsl:value-of select="concat($oai_script_name, '?verb=',/oai:OAI-PMH/oai:request/@verb,'&amp;resumptionToken=', text())"></xsl:value-of>
568                 </xsl:attribute>
569                     Show More
570                 </a>
571             </div>
572         </xsl:if>
573     </xsl:template>
574
575     <xsl:template name="result-count">
576         <xsl:param name="path" />
577         <xsl:variable name="cursor" select="$path/../oai:resumptionToken/@cursor" />
578         <xsl:variable name="count" select="count($path)" />
579         <xsl:variable name="total" select="$path/../oai:resumptionToken/@completeListSize" />
580         <xsl:choose>
581             <xsl:when test="$cursor">
582                 <xsl:choose>
583                     <xsl:when test="normalize-space($path/../oai:resumptionToken/text()) = ''">
584                     <!-- on the last page of results we have to assume that @completeListSize is available -->
585                         <xsl:value-of
586                             select="$total - $count" />
587                         -
588                         <xsl:value-of select="$total" />
589                     </xsl:when>
590                     <xsl:otherwise>
591                         <xsl:value-of select="$cursor + 1 - $count" />
592                         -
593                         <xsl:value-of select="$cursor" />
594                     </xsl:otherwise>
595                 </xsl:choose>
596             </xsl:when>
597             <xsl:otherwise>
598                 <xsl:value-of select="$count" />
599             </xsl:otherwise>
600         </xsl:choose>
601         <xsl:if test="$total">
602             of
603             <xsl:value-of select="$total" />
604         </xsl:if>
605     </xsl:template>
606
607     <xsl:template match="oai:metadata/*" priority='-20'>
608         <xsl:apply-templates select="." mode='xmlverb' />
609     </xsl:template>
610
611     <xsl:param name="indent-elements" select="false()" />
612
613     <xsl:template match="/" mode="xmlverb">
614         <xsl:text>&#xA;</xsl:text>
615         <xsl:comment>
616             <xsl:text> converted by xmlverbatim.xsl 1.1, (c) O. Becker </xsl:text>
617         </xsl:comment>
618         <xsl:text>&#xA;</xsl:text>
619         <div class="xmlverb-default">
620             <xsl:apply-templates mode="xmlverb">
621                 <xsl:with-param name="indent-elements" select="$indent-elements" />
622             </xsl:apply-templates>
623         </div>
624         <xsl:text>&#xA;</xsl:text>
625     </xsl:template>
626
627     <!-- wrapper -->
628     <xsl:template match="verb:wrapper">
629         <xsl:apply-templates mode="xmlverb">
630             <xsl:with-param name="indent-elements" select="$indent-elements" />
631         </xsl:apply-templates>
632     </xsl:template>
633
634     <xsl:template match="verb:wrapper" mode="xmlverb">
635         <xsl:apply-templates mode="xmlverb">
636             <xsl:with-param name="indent-elements" select="$indent-elements" />
637         </xsl:apply-templates>
638     </xsl:template>
639
640     <!-- element nodes -->
641     <xsl:template match="*" mode="xmlverb">
642         <xsl:param name="indent-elements" select="true()" />
643         <xsl:param name="indent" select="''" />
644         <xsl:param name="indent-increment" select="'&#xA0;&#xA0;&#xA0;'" />
645         <xsl:if test="$indent-elements">
646             <br/>
647             <xsl:value-of select="$indent" />
648         </xsl:if>
649         <xsl:text>&lt;</xsl:text>
650         <xsl:variable name="ns-prefix"
651                       select="substring-before(name(),':')" />
652         <xsl:if test="$ns-prefix != ''">
653             <span class="xmlverb-element-nsprefix">
654                 <xsl:value-of select="$ns-prefix"/>
655             </span>
656             <xsl:text>:</xsl:text>
657         </xsl:if>
658         <span class="xmlverb-element-name">
659             <xsl:value-of select="local-name()"/>
660         </span>
661         <xsl:variable name="pns" select="../namespace::*"/>
662         <xsl:if test="$pns[name()=''] and not(namespace::*[name()=''])">
663             <span class="xmlverb-ns-name">
664                 <xsl:text> xmlns</xsl:text>
665             </span>
666             <xsl:text>=&quot;&quot;</xsl:text>
667         </xsl:if>
668         <xsl:for-each select="namespace::*">
669             <xsl:if test="not($pns[name()=name(current()) and
670                            .=current()])">
671                 <xsl:call-template name="xmlverb-ns" />
672             </xsl:if>
673         </xsl:for-each>
674         <xsl:for-each select="@*">
675             <xsl:call-template name="xmlverb-attrs" />
676         </xsl:for-each>
677         <xsl:choose>
678             <xsl:when test="node()">
679                 <xsl:text>&gt;</xsl:text>
680                 <xsl:apply-templates mode="xmlverb">
681                     <xsl:with-param name="indent-elements"
682                                     select="$indent-elements"/>
683                     <xsl:with-param name="indent"
684                                     select="concat($indent, $indent-increment)"/>
685                     <xsl:with-param name="indent-increment"
686                                     select="$indent-increment"/>
687                 </xsl:apply-templates>
688                 <xsl:if test="* and $indent-elements">
689                     <br/>
690                     <xsl:value-of select="$indent" />
691                 </xsl:if>
692                 <xsl:text>&lt;/</xsl:text>
693                 <xsl:if test="$ns-prefix != ''">
694                     <span class="xmlverb-element-nsprefix">
695                         <xsl:value-of select="$ns-prefix"/>
696                     </span>
697                     <xsl:text>:</xsl:text>
698                 </xsl:if>
699                 <span class="xmlverb-element-name">
700                     <xsl:value-of select="local-name()"/>
701                 </span>
702                 <xsl:text>&gt;</xsl:text>
703             </xsl:when>
704             <xsl:otherwise>
705                 <xsl:text> /&gt;</xsl:text>
706             </xsl:otherwise>
707         </xsl:choose>
708         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
709     </xsl:template>
710
711     <!-- attribute nodes -->
712     <xsl:template name="xmlverb-attrs">
713         <xsl:text> </xsl:text>
714         <span class="xmlverb-attr-name">
715             <xsl:value-of select="name()"/>
716         </span>
717         <xsl:text>=&quot;</xsl:text>
718         <span class="xmlverb-attr-content">
719             <xsl:call-template name="html-replace-entities">
720                 <xsl:with-param name="text" select="normalize-space(.)" />
721                 <xsl:with-param name="attrs" select="true()" />
722             </xsl:call-template>
723         </span>
724         <xsl:text>&quot;</xsl:text>
725     </xsl:template>
726
727     <!-- namespace nodes -->
728     <xsl:template name="xmlverb-ns">
729         <xsl:if test="name()!='xml'">
730             <span class="xmlverb-ns-name">
731                 <xsl:text> xmlns</xsl:text>
732                 <xsl:if test="name()!=''">
733                     <xsl:text>:</xsl:text>
734                 </xsl:if>
735                 <xsl:value-of select="name()"/>
736             </span>
737             <xsl:text>=&quot;</xsl:text>
738             <span class="xmlverb-ns-uri">
739                 <xsl:value-of select="."/>
740             </span>
741             <xsl:text>&quot;</xsl:text>
742         </xsl:if>
743     </xsl:template>
744
745     <!-- text nodes -->
746     <xsl:template match="text()" mode="xmlverb">
747         <span class="xmlverb-text">
748             <xsl:call-template name="preformatted-output">
749                 <xsl:with-param name="text">
750                     <xsl:call-template name="html-replace-entities">
751                         <xsl:with-param name="text" select="." />
752                     </xsl:call-template>
753                 </xsl:with-param>
754             </xsl:call-template>
755         </span>
756     </xsl:template>
757
758     <!-- comments -->
759     <xsl:template match="comment()" mode="xmlverb">
760         <xsl:text>&lt;!--</xsl:text>
761         <span class="xmlverb-comment">
762             <xsl:call-template name="preformatted-output">
763                 <xsl:with-param name="text" select="." />
764             </xsl:call-template>
765         </span>
766         <xsl:text>--&gt;</xsl:text>
767         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
768     </xsl:template>
769
770     <!-- processing instructions -->
771     <xsl:template match="processing-instruction()" mode="xmlverb">
772         <xsl:text>&lt;?</xsl:text>
773         <span class="xmlverb-pi-name">
774             <xsl:value-of select="name()"/>
775         </span>
776         <xsl:if test=".!=''">
777             <xsl:text> </xsl:text>
778             <span class="xmlverb-pi-content">
779                 <xsl:value-of select="."/>
780             </span>
781         </xsl:if>
782         <xsl:text>?&gt;</xsl:text>
783         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
784     </xsl:template>
785
786
787     <!-- =========================================================== -->
788     <!--                    Procedures / Functions                   -->
789     <!-- =========================================================== -->
790
791     <!-- generate entities by replacing &, ", < and > in $text -->
792     <xsl:template name="html-replace-entities">
793         <xsl:param name="text" />
794         <xsl:param name="attrs" />
795         <xsl:variable name="tmp">
796             <xsl:call-template name="replace-substring">
797                 <xsl:with-param name="from" select="'&gt;'" />
798                 <xsl:with-param name="to" select="'&amp;gt;'" />
799                 <xsl:with-param name="value">
800                     <xsl:call-template name="replace-substring">
801                         <xsl:with-param name="from" select="'&lt;'" />
802                         <xsl:with-param name="to" select="'&amp;lt;'" />
803                         <xsl:with-param name="value">
804                             <xsl:call-template name="replace-substring">
805                                 <xsl:with-param name="from"
806                                                 select="'&amp;'" />
807                                 <xsl:with-param name="to"
808                                                 select="'&amp;amp;'" />
809                                 <xsl:with-param name="value"
810                                                 select="$text" />
811                             </xsl:call-template>
812                         </xsl:with-param>
813                     </xsl:call-template>
814                 </xsl:with-param>
815             </xsl:call-template>
816         </xsl:variable>
817         <xsl:choose>
818             <!-- $text is an attribute value -->
819             <xsl:when test="$attrs">
820                 <xsl:call-template name="replace-substring">
821                     <xsl:with-param name="from" select="'&#xA;'" />
822                     <xsl:with-param name="to" select="'&amp;#xA;'" />
823                     <xsl:with-param name="value">
824                         <xsl:call-template name="replace-substring">
825                             <xsl:with-param name="from"
826                                             select="'&quot;'" />
827                             <xsl:with-param name="to"
828                                             select="'&amp;quot;'" />
829                             <xsl:with-param name="value" select="$tmp" />
830                         </xsl:call-template>
831                     </xsl:with-param>
832                 </xsl:call-template>
833             </xsl:when>
834             <xsl:otherwise>
835                 <xsl:value-of select="$tmp" />
836             </xsl:otherwise>
837         </xsl:choose>
838     </xsl:template>
839
840     <!-- replace in $value substring $from with $to -->
841     <xsl:template name="replace-substring">
842         <xsl:param name="value" />
843         <xsl:param name="from" />
844         <xsl:param name="to" />
845         <xsl:choose>
846             <xsl:when test="contains($value,$from)">
847                 <xsl:value-of select="substring-before($value,$from)" />
848                 <xsl:value-of select="$to" />
849                 <xsl:call-template name="replace-substring">
850                     <xsl:with-param name="value"
851                                     select="substring-after($value,$from)" />
852                     <xsl:with-param name="from" select="$from" />
853                     <xsl:with-param name="to" select="$to" />
854                 </xsl:call-template>
855             </xsl:when>
856             <xsl:otherwise>
857                 <xsl:value-of select="$value" />
858             </xsl:otherwise>
859         </xsl:choose>
860     </xsl:template>
861
862     <!-- preformatted output: space as &nbsp;, tab as 8 &nbsp;
863                               nl as <br> -->
864     <xsl:template name="preformatted-output">
865         <xsl:param name="text" />
866         <xsl:call-template name="output-nl">
867             <xsl:with-param name="text">
868                 <xsl:call-template name="replace-substring">
869                     <xsl:with-param name="value"
870                                     select="translate($text,' ','&#xA0;')" />
871                     <xsl:with-param name="from" select="'&#9;'" />
872                     <xsl:with-param name="to"
873                                     select="'&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'" />
874                 </xsl:call-template>
875             </xsl:with-param>
876         </xsl:call-template>
877     </xsl:template>
878
879     <!-- output nl as <br> -->
880     <xsl:template name="output-nl">
881         <xsl:param name="text" />
882         <xsl:choose>
883             <xsl:when test="contains($text,'&#xA;')">
884                 <xsl:value-of select="substring-before($text,'&#xA;')" />
885                 <br />
886                 <xsl:text>&#xA;</xsl:text>
887                 <xsl:call-template name="output-nl">
888                     <xsl:with-param name="text"
889                                     select="substring-after($text,'&#xA;')" />
890                 </xsl:call-template>
891             </xsl:when>
892             <xsl:otherwise>
893                 <xsl:value-of select="$text" />
894             </xsl:otherwise>
895         </xsl:choose>
896     </xsl:template>
897
898 </xsl:stylesheet>