Bug 22672: Change <i> to <em> and <b> to <strong> in templates, includes, xslt
[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-3.4.1.min.js"></script>
30                 <script src="/opac-tmpl/bootstrap/lib/jquery/jquery-migrate-3.1.0.min.js"></script>
31                 <script src="/opac-tmpl/bootstrap/lib/bootstrap/js/bootstrap.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                 </div>
335             </div>
336         </xsl:for-each>
337
338         <xsl:apply-templates select="oai:resumptionToken"/>
339     </xsl:template>
340
341     <xsl:template match="oai:OAI-PMH/oai:GetRecord">
342         <h2>Record Details</h2>
343         <hr />
344         <xsl:for-each select="oai:record">
345             <div class="panel panel-default">
346                 <div class="panel-heading">
347                     <div class="row">
348                         <div class="col-lg-6">
349                             <h5>Identifier <small><xsl:value-of select="oai:header/oai:identifier/text()"></xsl:value-of></small></h5>
350                         </div>
351                         <div class="col-lg-6">
352                             <h5>Last Modified <small><xsl:value-of select="translate(oai:header/oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
353                         </div>
354                     </div>
355                 </div>
356                 <div class="panel-body">
357                     <!-- If this record has a "status", display it as a warning -->
358                     <xsl:if test="oai:header/@status">
359                       <div class="alert alert-warning">Record Status: <xsl:value-of select="oai:header/@status"/></div>
360                     </xsl:if>
361                     <div class="panel panel-success">
362                             <div class="panel-heading">
363                                 <h5 class="panel-title">
364                                     Sets
365                                 </h5>
366                             </div>
367                             <div class="panel-body list-group">
368                                 <xsl:for-each select="oai:header/oai:setSpec">
369                                     <div class="list-group-item">
370                                         <a>
371                                             <xsl:attribute name="href">
372                                                 <xsl:value-of
373                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
374                                             </xsl:attribute>
375                                             <xsl:value-of select="text()" />
376                                         </a>
377                                     </div>
378                                 </xsl:for-each>
379                             </div>
380                     </div>
381                     <div class="panel panel-info">
382                             <div class="panel-heading">
383                                 <h5 class="panel-title">
384                                     Metadata
385                                 </h5>
386                             </div>
387                             <div class="panel-body">
388                                 <xsl:apply-templates select="oai:metadata/*" />
389                             </div>
390                     </div>
391                 </div>
392             </div>
393         </xsl:for-each>
394     </xsl:template>
395
396     <xsl:template match="oai:OAI-PMH/oai:ListIdentifiers">
397         <h2>List of Identifiers</h2>
398         <hr />
399         <div class="well well-sm">
400             <h4>Results fetched
401                 <small>
402                     <xsl:call-template name="result-count">
403                         <xsl:with-param name="path" select="oai:header" />
404                     </xsl:call-template>
405                 </small>
406             </h4>
407         </div>
408         <xsl:for-each select="oai:header">
409             <div class="panel panel-default">
410                 <div class="panel-heading">
411                     <div class="row">
412                         <div class="col-lg-4">
413                             <h5>Identifier <small><xsl:value-of select="oai:identifier/text()"></xsl:value-of></small></h5>
414                         </div>
415                         <div class="col-lg-4">
416                             <h5>Last Modified <small><xsl:value-of select="translate(oai:datestamp/text(), 'TZ', ' ')"></xsl:value-of></small></h5>
417                         </div>
418                         <div class="col-lg-4">
419                             <a class="btn btn-default pull-right">
420                                 <xsl:attribute name="href">
421                                     <xsl:value-of select="concat($oai_script_name, '?verb=GetRecord&amp;metadataPrefix=oai_dc&amp;identifier=', oai:identifier/text())" />
422                                 </xsl:attribute>
423                                 View Details
424                             </a>
425                         </div>
426                     </div>
427                 </div>
428                 <div class="panel-body">
429                     <!-- If this record has a "status", display it as a warning -->
430                     <xsl:if test="@status">
431                       <div class="alert alert-warning">Record Status: <xsl:value-of select="@status"/></div>
432                     </xsl:if>
433                     <div class="panel panel-success">
434                         <a data-toggle="collapse">
435                             <xsl:attribute name="href">#sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
436                             <div class="panel-heading">
437                                 <h5 class="panel-title">
438                                     Sets
439                                 </h5>
440                             </div>
441                         </a>
442                         <div class="panel-collapse collapse">
443                             <xsl:attribute name="id">sets<xsl:value-of select="translate(oai:identifier/text(), ':/.', '')"></xsl:value-of></xsl:attribute>
444                             <div class="panel-body list-group">
445                                 <xsl:for-each select="oai:setSpec">
446                                     <div class="list-group-item">
447                                         <a>
448                                             <xsl:attribute name="href">
449                                                 <xsl:value-of
450                                                         select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set=', text())" />
451                                             </xsl:attribute>
452                                             <xsl:value-of select="text()" />
453                                         </a>
454                                     </div>
455                                 </xsl:for-each>
456                             </div>
457                         </div>
458                     </div>
459                 </div>
460             </div>
461         </xsl:for-each>
462
463         <xsl:apply-templates select="oai:resumptionToken"/>
464     </xsl:template>
465
466     <xsl:template match="oai:OAI-PMH/oai:ListMetadataFormats">
467         <h2>List of Metadata Formats</h2>
468         <hr />
469         <div class="well well-sm">
470             <h4>Results fetched
471                 <small>
472                     <xsl:value-of select="count(oai:OAI-PMH/oai:ListMetadataFormats/oai:metadataFormat)" />
473                 </small>
474             </h4>
475         </div>
476         <xsl:for-each select="oai:metadataFormat">
477             <div class="panel panel-default">
478                 <div class="panel-heading">
479                     <div class="row">
480                         <div class="col-lg-9">
481                             <h5><xsl:value-of select="oai:metadataPrefix/text()"></xsl:value-of></h5>
482                         </div>
483                         <div class="col-lg-3">
484                             <a class="btn btn-default pull-right">
485                                 <xsl:attribute name="href">
486                                     <xsl:value-of
487                                             select="concat($oai_script_name, '?verb=ListRecords&amp;metadataPrefix=', oai:metadataPrefix/text())" />
488                                 </xsl:attribute>
489                                 List Records
490                             </a>
491                         </div>
492                     </div>
493                 </div>
494                 <div class="panel-body">
495                     <div class="row">
496                         <div class="col-lg-9">
497                             <h5>Namespace <small><xsl:value-of select="oai:metadataNamespace/text()"></xsl:value-of></small></h5>
498                             <h5>Schema <small><xsl:value-of select="oai:schema/text()"></xsl:value-of></small></h5>
499                         </div>
500                     </div>
501                 </div>
502             </div>
503         </xsl:for-each>
504     </xsl:template>
505
506     <xsl:template match="oai:resumptionToken">
507         <xsl:if test="text() != ''">
508             <div class="text-center">
509                 <a class="btn btn-primary">
510                 <xsl:attribute name="href">
511                     <xsl:value-of select="concat($oai_script_name, '?verb=',/oai:OAI-PMH/oai:request/@verb,'&amp;resumptionToken=', text())"></xsl:value-of>
512                 </xsl:attribute>
513                     Show More
514                 </a>
515             </div>
516         </xsl:if>
517     </xsl:template>
518
519     <xsl:template name="result-count">
520         <xsl:param name="path" />
521         <xsl:variable name="cursor" select="$path/../oai:resumptionToken/@cursor" />
522         <xsl:variable name="count" select="count($path)" />
523         <xsl:variable name="total" select="$path/../oai:resumptionToken/@completeListSize" />
524         <xsl:choose>
525             <xsl:when test="$cursor">
526                 <xsl:choose>
527                     <xsl:when test="normalize-space($path/../oai:resumptionToken/text()) = ''">
528                     <!-- on the last page of results we have to assume that @completeListSize is available -->
529                         <xsl:value-of
530                             select="$total - $count" />
531                         -
532                         <xsl:value-of select="$total" />
533                     </xsl:when>
534                     <xsl:otherwise>
535                         <xsl:value-of select="$cursor + 1 - $count" />
536                         -
537                         <xsl:value-of select="$cursor" />
538                     </xsl:otherwise>
539                 </xsl:choose>
540             </xsl:when>
541             <xsl:otherwise>
542                 <xsl:value-of select="$count" />
543             </xsl:otherwise>
544         </xsl:choose>
545         <xsl:if test="$total">
546             of
547             <xsl:value-of select="$total" />
548         </xsl:if>
549     </xsl:template>
550
551     <xsl:template match="oai:metadata/*" priority='-20'>
552         <xsl:apply-templates select="." mode='xmlverb' />
553     </xsl:template>
554
555     <xsl:param name="indent-elements" select="false()" />
556
557     <xsl:template match="/" mode="xmlverb">
558         <xsl:text>&#xA;</xsl:text>
559         <xsl:comment>
560             <xsl:text> converted by xmlverbatim.xsl 1.1, (c) O. Becker </xsl:text>
561         </xsl:comment>
562         <xsl:text>&#xA;</xsl:text>
563         <div class="xmlverb-default">
564             <xsl:apply-templates mode="xmlverb">
565                 <xsl:with-param name="indent-elements" select="$indent-elements" />
566             </xsl:apply-templates>
567         </div>
568         <xsl:text>&#xA;</xsl:text>
569     </xsl:template>
570
571     <!-- wrapper -->
572     <xsl:template match="verb:wrapper">
573         <xsl:apply-templates mode="xmlverb">
574             <xsl:with-param name="indent-elements" select="$indent-elements" />
575         </xsl:apply-templates>
576     </xsl:template>
577
578     <xsl:template match="verb:wrapper" mode="xmlverb">
579         <xsl:apply-templates mode="xmlverb">
580             <xsl:with-param name="indent-elements" select="$indent-elements" />
581         </xsl:apply-templates>
582     </xsl:template>
583
584     <!-- element nodes -->
585     <xsl:template match="*" mode="xmlverb">
586         <xsl:param name="indent-elements" select="true()" />
587         <xsl:param name="indent" select="''" />
588         <xsl:param name="indent-increment" select="'&#xA0;&#xA0;&#xA0;'" />
589         <xsl:if test="$indent-elements">
590             <br/>
591             <xsl:value-of select="$indent" />
592         </xsl:if>
593         <xsl:text>&lt;</xsl:text>
594         <xsl:variable name="ns-prefix"
595                       select="substring-before(name(),':')" />
596         <xsl:if test="$ns-prefix != ''">
597             <span class="xmlverb-element-nsprefix">
598                 <xsl:value-of select="$ns-prefix"/>
599             </span>
600             <xsl:text>:</xsl:text>
601         </xsl:if>
602         <span class="xmlverb-element-name">
603             <xsl:value-of select="local-name()"/>
604         </span>
605         <xsl:variable name="pns" select="../namespace::*"/>
606         <xsl:if test="$pns[name()=''] and not(namespace::*[name()=''])">
607             <span class="xmlverb-ns-name">
608                 <xsl:text> xmlns</xsl:text>
609             </span>
610             <xsl:text>=&quot;&quot;</xsl:text>
611         </xsl:if>
612         <xsl:for-each select="namespace::*">
613             <xsl:if test="not($pns[name()=name(current()) and
614                            .=current()])">
615                 <xsl:call-template name="xmlverb-ns" />
616             </xsl:if>
617         </xsl:for-each>
618         <xsl:for-each select="@*">
619             <xsl:call-template name="xmlverb-attrs" />
620         </xsl:for-each>
621         <xsl:choose>
622             <xsl:when test="node()">
623                 <xsl:text>&gt;</xsl:text>
624                 <xsl:apply-templates mode="xmlverb">
625                     <xsl:with-param name="indent-elements"
626                                     select="$indent-elements"/>
627                     <xsl:with-param name="indent"
628                                     select="concat($indent, $indent-increment)"/>
629                     <xsl:with-param name="indent-increment"
630                                     select="$indent-increment"/>
631                 </xsl:apply-templates>
632                 <xsl:if test="* and $indent-elements">
633                     <br/>
634                     <xsl:value-of select="$indent" />
635                 </xsl:if>
636                 <xsl:text>&lt;/</xsl:text>
637                 <xsl:if test="$ns-prefix != ''">
638                     <span class="xmlverb-element-nsprefix">
639                         <xsl:value-of select="$ns-prefix"/>
640                     </span>
641                     <xsl:text>:</xsl:text>
642                 </xsl:if>
643                 <span class="xmlverb-element-name">
644                     <xsl:value-of select="local-name()"/>
645                 </span>
646                 <xsl:text>&gt;</xsl:text>
647             </xsl:when>
648             <xsl:otherwise>
649                 <xsl:text> /&gt;</xsl:text>
650             </xsl:otherwise>
651         </xsl:choose>
652         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
653     </xsl:template>
654
655     <!-- attribute nodes -->
656     <xsl:template name="xmlverb-attrs">
657         <xsl:text> </xsl:text>
658         <span class="xmlverb-attr-name">
659             <xsl:value-of select="name()"/>
660         </span>
661         <xsl:text>=&quot;</xsl:text>
662         <span class="xmlverb-attr-content">
663             <xsl:call-template name="html-replace-entities">
664                 <xsl:with-param name="text" select="normalize-space(.)" />
665                 <xsl:with-param name="attrs" select="true()" />
666             </xsl:call-template>
667         </span>
668         <xsl:text>&quot;</xsl:text>
669     </xsl:template>
670
671     <!-- namespace nodes -->
672     <xsl:template name="xmlverb-ns">
673         <xsl:if test="name()!='xml'">
674             <span class="xmlverb-ns-name">
675                 <xsl:text> xmlns</xsl:text>
676                 <xsl:if test="name()!=''">
677                     <xsl:text>:</xsl:text>
678                 </xsl:if>
679                 <xsl:value-of select="name()"/>
680             </span>
681             <xsl:text>=&quot;</xsl:text>
682             <span class="xmlverb-ns-uri">
683                 <xsl:value-of select="."/>
684             </span>
685             <xsl:text>&quot;</xsl:text>
686         </xsl:if>
687     </xsl:template>
688
689     <!-- text nodes -->
690     <xsl:template match="text()" mode="xmlverb">
691         <span class="xmlverb-text">
692             <xsl:call-template name="preformatted-output">
693                 <xsl:with-param name="text">
694                     <xsl:call-template name="html-replace-entities">
695                         <xsl:with-param name="text" select="." />
696                     </xsl:call-template>
697                 </xsl:with-param>
698             </xsl:call-template>
699         </span>
700     </xsl:template>
701
702     <!-- comments -->
703     <xsl:template match="comment()" mode="xmlverb">
704         <xsl:text>&lt;!--</xsl:text>
705         <span class="xmlverb-comment">
706             <xsl:call-template name="preformatted-output">
707                 <xsl:with-param name="text" select="." />
708             </xsl:call-template>
709         </span>
710         <xsl:text>--&gt;</xsl:text>
711         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
712     </xsl:template>
713
714     <!-- processing instructions -->
715     <xsl:template match="processing-instruction()" mode="xmlverb">
716         <xsl:text>&lt;?</xsl:text>
717         <span class="xmlverb-pi-name">
718             <xsl:value-of select="name()"/>
719         </span>
720         <xsl:if test=".!=''">
721             <xsl:text> </xsl:text>
722             <span class="xmlverb-pi-content">
723                 <xsl:value-of select="."/>
724             </span>
725         </xsl:if>
726         <xsl:text>?&gt;</xsl:text>
727         <xsl:if test="not(parent::*)"><br /><xsl:text>&#xA;</xsl:text></xsl:if>
728     </xsl:template>
729
730
731     <!-- =========================================================== -->
732     <!--                    Procedures / Functions                   -->
733     <!-- =========================================================== -->
734
735     <!-- generate entities by replacing &, ", < and > in $text -->
736     <xsl:template name="html-replace-entities">
737         <xsl:param name="text" />
738         <xsl:param name="attrs" />
739         <xsl:variable name="tmp">
740             <xsl:call-template name="replace-substring">
741                 <xsl:with-param name="from" select="'&gt;'" />
742                 <xsl:with-param name="to" select="'&amp;gt;'" />
743                 <xsl:with-param name="value">
744                     <xsl:call-template name="replace-substring">
745                         <xsl:with-param name="from" select="'&lt;'" />
746                         <xsl:with-param name="to" select="'&amp;lt;'" />
747                         <xsl:with-param name="value">
748                             <xsl:call-template name="replace-substring">
749                                 <xsl:with-param name="from"
750                                                 select="'&amp;'" />
751                                 <xsl:with-param name="to"
752                                                 select="'&amp;amp;'" />
753                                 <xsl:with-param name="value"
754                                                 select="$text" />
755                             </xsl:call-template>
756                         </xsl:with-param>
757                     </xsl:call-template>
758                 </xsl:with-param>
759             </xsl:call-template>
760         </xsl:variable>
761         <xsl:choose>
762             <!-- $text is an attribute value -->
763             <xsl:when test="$attrs">
764                 <xsl:call-template name="replace-substring">
765                     <xsl:with-param name="from" select="'&#xA;'" />
766                     <xsl:with-param name="to" select="'&amp;#xA;'" />
767                     <xsl:with-param name="value">
768                         <xsl:call-template name="replace-substring">
769                             <xsl:with-param name="from"
770                                             select="'&quot;'" />
771                             <xsl:with-param name="to"
772                                             select="'&amp;quot;'" />
773                             <xsl:with-param name="value" select="$tmp" />
774                         </xsl:call-template>
775                     </xsl:with-param>
776                 </xsl:call-template>
777             </xsl:when>
778             <xsl:otherwise>
779                 <xsl:value-of select="$tmp" />
780             </xsl:otherwise>
781         </xsl:choose>
782     </xsl:template>
783
784     <!-- replace in $value substring $from with $to -->
785     <xsl:template name="replace-substring">
786         <xsl:param name="value" />
787         <xsl:param name="from" />
788         <xsl:param name="to" />
789         <xsl:choose>
790             <xsl:when test="contains($value,$from)">
791                 <xsl:value-of select="substring-before($value,$from)" />
792                 <xsl:value-of select="$to" />
793                 <xsl:call-template name="replace-substring">
794                     <xsl:with-param name="value"
795                                     select="substring-after($value,$from)" />
796                     <xsl:with-param name="from" select="$from" />
797                     <xsl:with-param name="to" select="$to" />
798                 </xsl:call-template>
799             </xsl:when>
800             <xsl:otherwise>
801                 <xsl:value-of select="$value" />
802             </xsl:otherwise>
803         </xsl:choose>
804     </xsl:template>
805
806     <!-- preformatted output: space as &nbsp;, tab as 8 &nbsp;
807                               nl as <br> -->
808     <xsl:template name="preformatted-output">
809         <xsl:param name="text" />
810         <xsl:call-template name="output-nl">
811             <xsl:with-param name="text">
812                 <xsl:call-template name="replace-substring">
813                     <xsl:with-param name="value"
814                                     select="translate($text,' ','&#xA0;')" />
815                     <xsl:with-param name="from" select="'&#9;'" />
816                     <xsl:with-param name="to"
817                                     select="'&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'" />
818                 </xsl:call-template>
819             </xsl:with-param>
820         </xsl:call-template>
821     </xsl:template>
822
823     <!-- output nl as <br> -->
824     <xsl:template name="output-nl">
825         <xsl:param name="text" />
826         <xsl:choose>
827             <xsl:when test="contains($text,'&#xA;')">
828                 <xsl:value-of select="substring-before($text,'&#xA;')" />
829                 <br />
830                 <xsl:text>&#xA;</xsl:text>
831                 <xsl:call-template name="output-nl">
832                     <xsl:with-param name="text"
833                                     select="substring-after($text,'&#xA;')" />
834                 </xsl:call-template>
835             </xsl:when>
836             <xsl:otherwise>
837                 <xsl:value-of select="$text" />
838             </xsl:otherwise>
839         </xsl:choose>
840     </xsl:template>
841
842 </xsl:stylesheet>