Bug 12768: (QA follow-up) Add 'Processing fee' to templates
[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/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" />
33             </head>
34             <body>
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>
39                         </div>
40                         <div class="navbar-collapse collapse">
41                             <ul class="nav navbar-nav navbar-right">
42                                 <li>
43                                     <a title="Institutional information">
44                                         <xsl:if test="/oai:OAI-PMH/oai:request/@verb = 'Identify'">
45                                             <xsl:attribute name="class">active</xsl:attribute>
46                                         </xsl:if>
47                                         <xsl:attribute name="href">
48                                             <xsl:value-of
49                                                     select="concat($oai_script_name,'?verb=Identify')"></xsl:value-of>
50                                         </xsl:attribute>
51                                         Identify
52                                     </a>
53                                 </li>
54                                 <li>
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>
58                                         </xsl:if>
59                                         <xsl:attribute name="href">
60                                             <xsl:value-of
61                                                     select="concat($oai_script_name, '?verb=ListSets')"></xsl:value-of>
62                                         </xsl:attribute>
63                                         Sets
64                                     </a>
65                                 </li>
66                                 <li>
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>
70                                         </xsl:if>
71                                         <xsl:attribute name="href">
72                                             <xsl:value-of
73                                                     select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc')"></xsl:value-of>
74                                         </xsl:attribute>
75                                         Records
76                                     </a>
77                                 </li>
78                                 <li>
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>
82                                         </xsl:if>
83                                         <xsl:attribute name="href">
84                                             <xsl:value-of
85                                                     select="concat($oai_script_name, '?verb=ListIdentifiers&amp;metadataPrefix=oai_dc')"></xsl:value-of>
86                                         </xsl:attribute>
87                                         Identifiers
88                                     </a>
89                                 </li>
90                                 <li>
91                                     <a title="Metadata Formats available">
92                                         <xsl:if
93                                                 test="/oai:OAI-PMH/oai:request/@verb = 'ListMetadataFormats'">
94                                             <xsl:attribute name="class">active</xsl:attribute>
95                                         </xsl:if>
96                                         <xsl:attribute name="href">
97                                             <xsl:value-of
98                                                     select="concat($oai_script_name, '?verb=ListMetadataFormats')"></xsl:value-of>
99                                         </xsl:attribute>
100                                         Metadata Formats
101                                     </a>
102                                 </li>
103                             </ul>
104                         </div><!--/.nav-collapse -->
105                     </div>
106                     <div class="row">
107                         <div class="col-lg-offset-1 col-lg-10">
108                             <div class="row">
109                                 <h5>Response Date <small><xsl:value-of select="translate(oai:OAI-PMH/oai:responseDate/text(), 'TZ', ' ')" /></small></h5>
110                             </div>
111                             <div class="row">
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" />
119                             </div>
120                         </div>
121                     </div>
122
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>
126                     </div>
127                 </div>
128             </body>
129         </html>
130     </xsl:template>
131
132     <xsl:template match="oai:OAI-PMH/oai:error">
133         <div class="alert alert-danger">
134             <h4>Error</h4>
135             <p>
136                 <xsl:value-of select="text()"></xsl:value-of>
137             </p>
138         </div>
139     </xsl:template>
140
141     <xsl:template match="oai:OAI-PMH/oai:Identify">
142         <h2>Repository Information</h2>
143         <hr />
144         <table class="table table-striped table-bordered">
145             <tr>
146                 <td><b>Repository Name</b></td>
147                 <td><xsl:value-of select="oai:repositoryName/text()" /></td>
148             </tr>
149             <xsl:for-each select="oai:adminEmail">
150                 <tr>
151                     <td><b>E-Mail Contact</b></td>
152                     <td>
153                         <a>
154                             <xsl:attribute name="href">
155                                 <xsl:value-of select="concat('mailto:', text())" />
156                             </xsl:attribute>
157                             <xsl:value-of select="text()" />
158                         </a>
159                     </td>
160                 </tr>
161             </xsl:for-each>
162             <tr>
163                 <td><b>Repository identifier</b></td>
164                 <td>
165                     <xsl:value-of select="oai:description/oai_id:oai-identifier/oai_id:repositoryIdentifier/text()" />
166                 </td>
167             </tr>
168             <tr>
169                 <td><b>Sample identifier</b></td>
170                 <td>
171                     <xsl:value-of
172                             select="oai:description/oai_id:oai-identifier/oai_id:sampleIdentifier/text()" />
173                 </td>
174             </tr>
175             <tr>
176                 <td><b>Protocol Version</b></td>
177                 <td>
178                     <xsl:value-of
179                             select="oai:protocolVersion/text()" />
180                 </td>
181
182             </tr>
183             <tr>
184                 <td><b>Earliest Registered Date</b></td>
185                 <td>
186                     <xsl:value-of
187                             select="translate(oai:earliestDatestamp/text(), 'TZ' ,' ')" />
188                 </td>
189
190             </tr>
191             <tr>
192                 <td><b>Date Granularity</b></td>
193                 <td>
194                     <xsl:value-of
195                             select="translate(oai:granularity/text(), 'TZ', ' ')" />
196                 </td>
197
198             </tr>
199             <tr>
200                 <td><b>Deletion Mode</b></td>
201                 <td>
202                     <xsl:value-of
203                             select="oai:deletedRecord/text()" />
204                 </td>
205
206             </tr>
207         </table>
208     </xsl:template>
209
210     <xsl:template match="oai:OAI-PMH/oai:ListSets">
211         <h2>List of Sets</h2>
212         <hr />
213         <div class="well well-sm">
214             <h4>Results fetched
215                 <small>
216                     <xsl:call-template name="result-count">
217                         <xsl:with-param name="path" select="oai:set" />
218                     </xsl:call-template>
219                 </small>
220             </h4>
221         </div>
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">
226                         <xsl:choose>
227                             <xsl:when test="string-length(oai:setName/text()) &gt; 83">
228                                 <xsl:value-of select="substring(oai:setName/text(),0, 80 )" />
229                                 ...
230                             </xsl:when>
231                             <xsl:otherwise>
232                                 <xsl:value-of select="oai:setName/text()" />
233                             </xsl:otherwise>
234                         </xsl:choose>
235                         <small>
236                             [<xsl:value-of select="oai:setSpec/text()" />]
237                         </small>
238                     </h5>
239                     <div class="spec">
240                         <a>
241                             <xsl:attribute name="href">
242                                 <xsl:value-of
243                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', oai:setSpec/text())" />
244                             </xsl:attribute>
245                             Records
246                         </a>
247                         <a>
248                             <xsl:attribute name="href">
249                                 <xsl:value-of
250                                         select="concat($oai_script_name, '?verb=ListIdentifiers&amp;metadataPrefix=oai_dc&amp;set=', oai:setSpec/text())" />
251                             </xsl:attribute>
252                             Identifiers
253                         </a>
254                     </div>
255                 </div>
256             </xsl:for-each>
257         </div>
258
259         <xsl:apply-templates select="oai:resumptionToken"/>
260     </xsl:template>
261
262     <xsl:template match="oai:OAI-PMH/oai:ListRecords">
263         <h2>List of Records</h2>
264         <hr />
265         <div class="well well-sm">
266             <h4>Results fetched
267                 <small>
268                     <xsl:call-template name="result-count">
269                         <xsl:with-param name="path" select="oai:record" />
270                     </xsl:call-template>
271                 </small>
272             </h4>
273         </div>
274         <xsl:for-each select="oai:record">
275             <div class="panel panel-default">
276                 <div class="panel-heading">
277                     <div class="row">
278                         <div class="col-lg-6">
279                             <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
280                         </div>
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>
283                         </div>
284                     </div>
285                 </div>
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>
290                     </xsl:if>
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">
296                                     Sets
297                                 </h5>
298                             </div>
299                         </a>
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">
305                                         <a>
306                                             <xsl:attribute name="href">
307                                                 <xsl:value-of
308                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
309                                             </xsl:attribute>
310                                             <xsl:value-of select="text()" />
311                                         </a>
312                                     </div>
313                                 </xsl:for-each>
314                             </div>
315                         </div>
316                     </div>
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">
322                                         Metadata
323                                 </h5>
324                             </div>
325                         </a>
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/*" />
330                             </div>
331                         </div>
332                     </div>
333                 </div>
334             </div>
335         </xsl:for-each>
336
337         <xsl:apply-templates select="oai:resumptionToken"/>
338     </xsl:template>
339
340     <xsl:template match="oai:OAI-PMH/oai:GetRecord">
341         <h2>Record Details</h2>
342         <hr />
343         <xsl:for-each select="oai:record">
344             <div class="panel panel-default">
345                 <div class="panel-heading">
346                     <div class="row">
347                         <div class="col-lg-6">
348                             <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
349                         </div>
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>
352                         </div>
353                     </div>
354                 </div>
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>
359                     </xsl:if>
360                     <div class="panel panel-success">
361                             <div class="panel-heading">
362                                 <h5 class="panel-title">
363                                     Sets
364                                 </h5>
365                             </div>
366                             <div class="panel-body list-group">
367                                 <xsl:for-each select="oai:header/oai:setSpec">
368                                     <div class="list-group-item">
369                                         <a>
370                                             <xsl:attribute name="href">
371                                                 <xsl:value-of
372                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
373                                             </xsl:attribute>
374                                             <xsl:value-of select="text()" />
375                                         </a>
376                                     </div>
377                                 </xsl:for-each>
378                             </div>
379                     </div>
380                     <div class="panel panel-info">
381                             <div class="panel-heading">
382                                 <h5 class="panel-title">
383                                     Metadata
384                                 </h5>
385                             </div>
386                             <div class="panel-body">
387                                 <xsl:apply-templates select="oai:metadata/*" />
388                             </div>
389                     </div>
390                 </div>
391             </div>
392         </xsl:for-each>
393     </xsl:template>
394
395     <xsl:template match="oai:OAI-PMH/oai:ListIdentifiers">
396         <h2>List of Identifiers</h2>
397         <hr />
398         <div class="well well-sm">
399             <h4>Results fetched
400                 <small>
401                     <xsl:call-template name="result-count">
402                         <xsl:with-param name="path" select="oai:header" />
403                     </xsl:call-template>
404                 </small>
405             </h4>
406         </div>
407         <xsl:for-each select="oai:header">
408             <div class="panel panel-default">
409                 <div class="panel-heading">
410                     <div class="row">
411                         <div class="col-lg-4">
412                             <h5>Identifier <small><xsl:value-of select="oai:identifier/text()"></xsl:value-of></small></h5>
413                         </div>
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>
416                         </div>
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&amp;metadataPrefix=oai_dc&amp;identifier=', oai:identifier/text())" />
421                                 </xsl:attribute>
422                                 View Details
423                             </a>
424                         </div>
425                     </div>
426                 </div>
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>
431                     </xsl:if>
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">
437                                     Sets
438                                 </h5>
439                             </div>
440                         </a>
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">
446                                         <a>
447                                             <xsl:attribute name="href">
448                                                 <xsl:value-of
449                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
450                                             </xsl:attribute>
451                                             <xsl:value-of select="text()" />
452                                         </a>
453                                     </div>
454                                 </xsl:for-each>
455                             </div>
456                         </div>
457                     </div>
458                 </div>
459             </div>
460         </xsl:for-each>
461
462         <xsl:apply-templates select="oai:resumptionToken"/>
463     </xsl:template>
464
465     <xsl:template match="oai:OAI-PMH/oai:ListMetadataFormats">
466         <h2>List of Metadata Formats</h2>
467         <hr />
468         <div class="well well-sm">
469             <h4>Results fetched
470                 <small>
471                     <xsl:value-of select="count(oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat)" />
472                 </small>
473             </h4>
474         </div>
475         <xsl:for-each select="oai:metadataFormat">
476             <div class="panel panel-default">
477                 <div class="panel-heading">
478                     <div class="row">
479                         <div class="col-lg-9">
480                             <h5><xsl:value-of select="oai:metadataPrefix/text()"></xsl:value-of></h5>
481                         </div>
482                         <div class="col-lg-3">
483                             <a class="btn btn-default pull-right">
484                                 <xsl:attribute name="href">
485                                     <xsl:value-of
486                                             select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=', oai:metadataPrefix/text())" />
487                                 </xsl:attribute>
488                                 List Records
489                             </a>
490                         </div>
491                     </div>
492                 </div>
493                 <div class="panel-body">
494                     <div class="row">
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>
498                         </div>
499                     </div>
500                 </div>
501             </div>
502         </xsl:for-each>
503     </xsl:template>
504
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,'&amp;resumptionToken=', text())"></xsl:value-of>
511                 </xsl:attribute>
512                     Show More
513                 </a>
514             </div>
515         </xsl:if>
516     </xsl:template>
517
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" />
523         <xsl:choose>
524             <xsl:when test="$cursor">
525                 <xsl:choose>
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 -->
528                         <xsl:value-of
529                             select="$total - $count" />
530                         -
531                         <xsl:value-of select="$total" />
532                     </xsl:when>
533                     <xsl:otherwise>
534                         <xsl:value-of select="$cursor + 1 - $count" />
535                         -
536                         <xsl:value-of select="$cursor" />
537                     </xsl:otherwise>
538                 </xsl:choose>
539             </xsl:when>
540             <xsl:otherwise>
541                 <xsl:value-of select="$count" />
542             </xsl:otherwise>
543         </xsl:choose>
544         <xsl:if test="$total">
545             of
546             <xsl:value-of select="$total" />
547         </xsl:if>
548     </xsl:template>
549
550     <xsl:template match="oai:metadata/*" priority='-20'>
551         <xsl:apply-templates select="." mode='xmlverb' />
552     </xsl:template>
553
554     <xsl:param name="indent-elements" select="false()" />
555
556     <xsl:template match="/" mode="xmlverb">
557         <xsl:text>&#xA;</xsl:text>
558         <xsl:comment>
559             <xsl:text> converted by xmlverbatim.xsl 1.1, (c) O. Becker </xsl:text>
560         </xsl:comment>
561         <xsl:text>&#xA;</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>
566         </div>
567         <xsl:text>&#xA;</xsl:text>
568     </xsl:template>
569
570     <!-- wrapper -->
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>
575     </xsl:template>
576
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>
581     </xsl:template>
582
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="'&#xA0;&#xA0;&#xA0;'" />
588         <xsl:if test="$indent-elements">
589             <br/>
590             <xsl:value-of select="$indent" />
591         </xsl:if>
592         <xsl:text>&lt;</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"/>
598             </span>
599             <xsl:text>:</xsl:text>
600         </xsl:if>
601         <span class="xmlverb-element-name">
602             <xsl:value-of select="local-name()"/>
603         </span>
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>
608             </span>
609             <xsl:text>=&quot;&quot;</xsl:text>
610         </xsl:if>
611         <xsl:for-each select="namespace::*">
612             <xsl:if test="not($pns[name()=name(current()) and
613                            .=current()])">
614                 <xsl:call-template name="xmlverb-ns" />
615             </xsl:if>
616         </xsl:for-each>
617         <xsl:for-each select="@*">
618             <xsl:call-template name="xmlverb-attrs" />
619         </xsl:for-each>
620         <xsl:choose>
621             <xsl:when test="node()">
622                 <xsl:text>&gt;</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">
632                     <br/>
633                     <xsl:value-of select="$indent" />
634                 </xsl:if>
635                 <xsl:text>&lt;/</xsl:text>
636                 <xsl:if test="$ns-prefix != ''">
637                     <span class="xmlverb-element-nsprefix">
638                         <xsl:value-of select="$ns-prefix"/>
639                     </span>
640                     <xsl:text>:</xsl:text>
641                 </xsl:if>
642                 <span class="xmlverb-element-name">
643                     <xsl:value-of select="local-name()"/>
644                 </span>
645                 <xsl:text>&gt;</xsl:text>
646             </xsl:when>
647             <xsl:otherwise>
648                 <xsl:text> /&gt;</xsl:text>
649             </xsl:otherwise>
650         </xsl:choose>
651         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
652     </xsl:template>
653
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()"/>
659         </span>
660         <xsl:text>=&quot;</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()" />
665             </xsl:call-template>
666         </span>
667         <xsl:text>&quot;</xsl:text>
668     </xsl:template>
669
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>
677                 </xsl:if>
678                 <xsl:value-of select="name()"/>
679             </span>
680             <xsl:text>=&quot;</xsl:text>
681             <span class="xmlverb-ns-uri">
682                 <xsl:value-of select="."/>
683             </span>
684             <xsl:text>&quot;</xsl:text>
685         </xsl:if>
686     </xsl:template>
687
688     <!-- text nodes -->
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="." />
695                     </xsl:call-template>
696                 </xsl:with-param>
697             </xsl:call-template>
698         </span>
699     </xsl:template>
700
701     <!-- comments -->
702     <xsl:template match="comment()" mode="xmlverb">
703         <xsl:text>&lt;!--</xsl:text>
704         <span class="xmlverb-comment">
705             <xsl:call-template name="preformatted-output">
706                 <xsl:with-param name="text" select="." />
707             </xsl:call-template>
708         </span>
709         <xsl:text>--&gt;</xsl:text>
710         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
711     </xsl:template>
712
713     <!-- processing instructions -->
714     <xsl:template match="processing-instruction()" mode="xmlverb">
715         <xsl:text>&lt;?</xsl:text>
716         <span class="xmlverb-pi-name">
717             <xsl:value-of select="name()"/>
718         </span>
719         <xsl:if test=".!=''">
720             <xsl:text> </xsl:text>
721             <span class="xmlverb-pi-content">
722                 <xsl:value-of select="."/>
723             </span>
724         </xsl:if>
725         <xsl:text>?&gt;</xsl:text>
726         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
727     </xsl:template>
728
729
730     <!-- =========================================================== -->
731     <!--                    Procedures / Functions                   -->
732     <!-- =========================================================== -->
733
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="'&gt;'" />
741                 <xsl:with-param name="to" select="'&amp;gt;'" />
742                 <xsl:with-param name="value">
743                     <xsl:call-template name="replace-substring">
744                         <xsl:with-param name="from" select="'&lt;'" />
745                         <xsl:with-param name="to" select="'&amp;lt;'" />
746                         <xsl:with-param name="value">
747                             <xsl:call-template name="replace-substring">
748                                 <xsl:with-param name="from"
749                                                 select="'&amp;'" />
750                                 <xsl:with-param name="to"
751                                                 select="'&amp;amp;'" />
752                                 <xsl:with-param name="value"
753                                                 select="$text" />
754                             </xsl:call-template>
755                         </xsl:with-param>
756                     </xsl:call-template>
757                 </xsl:with-param>
758             </xsl:call-template>
759         </xsl:variable>
760         <xsl:choose>
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="'&#xA;'" />
765                     <xsl:with-param name="to" select="'&amp;#xA;'" />
766                     <xsl:with-param name="value">
767                         <xsl:call-template name="replace-substring">
768                             <xsl:with-param name="from"
769                                             select="'&quot;'" />
770                             <xsl:with-param name="to"
771                                             select="'&amp;quot;'" />
772                             <xsl:with-param name="value" select="$tmp" />
773                         </xsl:call-template>
774                     </xsl:with-param>
775                 </xsl:call-template>
776             </xsl:when>
777             <xsl:otherwise>
778                 <xsl:value-of select="$tmp" />
779             </xsl:otherwise>
780         </xsl:choose>
781     </xsl:template>
782
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" />
788         <xsl:choose>
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" />
797                 </xsl:call-template>
798             </xsl:when>
799             <xsl:otherwise>
800                 <xsl:value-of select="$value" />
801             </xsl:otherwise>
802         </xsl:choose>
803     </xsl:template>
804
805     <!-- preformatted output: space as &nbsp;, tab as 8 &nbsp;
806                               nl as <br> -->
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,' ','&#xA0;')" />
814                     <xsl:with-param name="from" select="'&#9;'" />
815                     <xsl:with-param name="to"
816                                     select="'&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'" />
817                 </xsl:call-template>
818             </xsl:with-param>
819         </xsl:call-template>
820     </xsl:template>
821
822     <!-- output nl as <br> -->
823     <xsl:template name="output-nl">
824         <xsl:param name="text" />
825         <xsl:choose>
826             <xsl:when test="contains($text,'&#xA;')">
827                 <xsl:value-of select="substring-before($text,'&#xA;')" />
828                 <br />
829                 <xsl:text>&#xA;</xsl:text>
830                 <xsl:call-template name="output-nl">
831                     <xsl:with-param name="text"
832                                     select="substring-after($text,'&#xA;')" />
833                 </xsl:call-template>
834             </xsl:when>
835             <xsl:otherwise>
836                 <xsl:value-of select="$text" />
837             </xsl:otherwise>
838         </xsl:choose>
839     </xsl:template>
840
841 </xsl:stylesheet>