normalize_record: missing else
[pazpar2-moved-to-github.git] / etc / marc21.xsl
1 <?xml version="1.0" encoding="UTF-8"?>
2 <xsl:stylesheet
3     version="1.0"
4     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5     xmlns:pz="http://www.indexdata.com/pazpar2/1.0"
6     xmlns:marc="http://www.loc.gov/MARC21/slim">
7   
8   <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
9
10 <!-- Extract metadata from MARC21/USMARC 
11       http://www.loc.gov/marc/bibliographic/ecbdhome.html
12 -->  
13   <xsl:template name="record-hook"/>
14
15   <xsl:template match="/">
16     <xsl:apply-templates/>
17   </xsl:template>
18
19   <xsl:template match="marc:collection">
20     <pz:collection>
21         <xsl:apply-templates/>
22     </pz:collection>
23   </xsl:template>
24
25   <xsl:template match="marc:record">
26     <xsl:variable name="title_medium" select="marc:datafield[@tag='245']/marc:subfield[@code='h']"/>
27     <xsl:variable name="journal_title" select="marc:datafield[@tag='773']/marc:subfield[@code='t']"/>
28     <xsl:variable name="electronic_location_url" select="marc:datafield[@tag='856']/marc:subfield[@code='u']"/>
29     <xsl:variable name="fulltext_a" select="marc:datafield[@tag='900']/marc:subfield[@code='a']"/>
30     <xsl:variable name="fulltext_b" select="marc:datafield[@tag='900']/marc:subfield[@code='b']"/>
31     <xsl:variable name="medium">
32       <xsl:choose>
33         <xsl:when test="$title_medium">
34           <xsl:value-of select="translate($title_medium, ' []/', '')"/>
35         </xsl:when>
36         <xsl:when test="$fulltext_a">
37           <xsl:text>electronic resource</xsl:text>
38         </xsl:when>
39         <xsl:when test="$fulltext_b">
40           <xsl:text>electronic resource</xsl:text>
41         </xsl:when>
42         <xsl:when test="$journal_title">
43           <xsl:text>article</xsl:text>
44         </xsl:when>
45         <xsl:otherwise>
46           <xsl:text>book</xsl:text>
47         </xsl:otherwise>
48       </xsl:choose>
49     </xsl:variable>
50
51     <xsl:variable name="has_fulltext">
52       <xsl:choose>
53         <xsl:when test="marc:datafield[@tag='856']/marc:subfield[@code='q']">
54           <xsl:text>yes</xsl:text>
55         </xsl:when>
56         <xsl:when test="marc:datafield[@tag='856']/marc:subfield[@code='i']='TEXT*'">
57           <xsl:text>yes</xsl:text>
58         </xsl:when>
59         <xsl:otherwise>
60           <xsl:text>no</xsl:text>
61         </xsl:otherwise>
62       </xsl:choose>
63     </xsl:variable>
64
65     <xsl:variable name="oclc_number">
66       <xsl:variable name="c001" select='marc:controlfield[@tag="001"]' />
67       <xsl:choose>
68         <xsl:when test='contains(marc:controlfield[@tag="001"],"ocn") or
69                         contains(marc:controlfield[@tag="001"],"ocm") or
70                         contains(marc:controlfield[@tag="001"],"OCoLC")'>
71             <xsl:value-of select="marc:controlfield[@tag='001']"/>
72         </xsl:when>
73         <xsl:when test='contains(marc:datafield[@tag="035"]/marc:subfield[@code="a"],"ocn") or
74                         contains(marc:datafield[@tag="035"]/marc:subfield[@code="a"],"ocm") or
75                         contains(marc:datafield[@tag="035"]/marc:subfield[@code="a"],"OCoLC") '>
76          <xsl:value-of select="marc:datafield[@tag='035']/marc:subfield[@code='a']"/>
77         </xsl:when>
78       </xsl:choose>
79     </xsl:variable>
80
81     <xsl:variable name="date_008">
82       <xsl:choose>
83         <xsl:when test="contains('cestpudikmr', substring(marc:controlfield[@tag='008'], 7, 1))">
84           <xsl:value-of select="substring(marc:controlfield[@tag='008'], 8, 4)" />
85         </xsl:when>
86       </xsl:choose>
87     </xsl:variable>
88
89     <xsl:variable name="date_end_008">
90       <xsl:choose>
91         <xsl:when test="contains('dikmr', substring(marc:controlfield[@tag='008'], 7, 1))">
92           <xsl:value-of select="substring(marc:controlfield[@tag='008'], 12, 4)" />
93         </xsl:when>
94       </xsl:choose>
95     </xsl:variable>
96
97     <pz:record>
98       <xsl:for-each select="marc:controlfield[@tag='001']">
99         <pz:metadata type="id">
100           <xsl:value-of select="."/>
101         </pz:metadata>
102       </xsl:for-each>
103
104       <pz:metadata type="oclc-number">
105         <xsl:value-of select="$oclc_number" />
106       </pz:metadata>
107
108       <xsl:for-each select="marc:datafield[@tag='010']">
109         <pz:metadata type="lccn">
110           <xsl:value-of select="marc:subfield[@code='a']"/>
111         </pz:metadata>
112       </xsl:for-each>
113
114       <xsl:for-each select="marc:datafield[@tag='020']">
115         <pz:metadata type="isbn">
116           <xsl:value-of select="marc:subfield[@code='a']"/>
117         </pz:metadata>
118       </xsl:for-each>
119
120       <xsl:for-each select="marc:datafield[@tag='022']">
121         <pz:metadata type="issn">
122           <xsl:value-of select="marc:subfield[@code='a']"/>
123         </pz:metadata>
124       </xsl:for-each>
125
126       <xsl:for-each select="marc:datafield[@tag='027']">
127         <pz:metadata type="tech-rep-nr">
128           <xsl:value-of select="marc:subfield[@code='a']"/>
129         </pz:metadata>
130       </xsl:for-each>
131
132       <xsl:for-each select="marc:datafield[@tag='035']">
133         <pz:metadata type="system-control-nr">
134           <xsl:choose>
135             <xsl:when test="marc:subfield[@code='a']">
136               <xsl:value-of select="marc:subfield[@code='a']"/>
137             </xsl:when>
138             <xsl:otherwise>
139               <xsl:value-of select="marc:subfield[@code='b']"/>
140             </xsl:otherwise>
141           </xsl:choose>
142         </pz:metadata>
143       </xsl:for-each>
144
145       <xsl:for-each select="marc:datafield[@tag='100']">
146         <pz:metadata type="author">
147           <xsl:value-of select="marc:subfield[@code='a']"/>
148         </pz:metadata>
149         <pz:metadata type="author-title">
150           <xsl:value-of select="marc:subfield[@code='c']"/>
151         </pz:metadata>
152         <pz:metadata type="author-date">
153           <xsl:value-of select="marc:subfield[@code='d']"/>
154         </pz:metadata>
155       </xsl:for-each>
156
157       <xsl:for-each select="marc:datafield[@tag='110']">
158         <pz:metadata type="corporate-name">
159             <xsl:value-of select="marc:subfield[@code='a']"/>
160         </pz:metadata>
161         <pz:metadata type="corporate-location">
162             <xsl:value-of select="marc:subfield[@code='c']"/>
163         </pz:metadata>
164         <pz:metadata type="corporate-date">
165             <xsl:value-of select="marc:subfield[@code='d']"/>
166         </pz:metadata>
167       </xsl:for-each>
168
169       <xsl:for-each select="marc:datafield[@tag='111']">
170         <pz:metadata type="meeting-name">
171             <xsl:value-of select="marc:subfield[@code='a']"/>
172         </pz:metadata>
173         <pz:metadata type="meeting-location">
174             <xsl:value-of select="marc:subfield[@code='c']"/>
175         </pz:metadata>
176         <pz:metadata type="meeting-date">
177             <xsl:value-of select="marc:subfield[@code='d']"/>
178         </pz:metadata>
179       </xsl:for-each>
180
181       <xsl:for-each select="marc:datafield[@tag='130']">
182         <pz:metadata type="title-uniform">
183           <xsl:value-of select="marc:subfield[@code='a']" />
184         </pz:metadata>
185         <pz:metadata type="title-uniform-media">
186           <xsl:value-of select="marc:subfield[@code='m']" />
187         </pz:metadata>
188         <pz:metadata type="title-uniform-parts">
189           <xsl:value-of select="marc:subfield[@code='n']" />
190         </pz:metadata>
191         <pz:metadata type="title-uniform-partname">
192           <xsl:value-of select="marc:subfield[@code='p']" />
193         </pz:metadata>
194         <pz:metadata type="title-uniform-key">
195           <xsl:value-of select="marc:subfield[@code='r']" />
196         </pz:metadata>
197       </xsl:for-each>
198
199       <xsl:for-each select="marc:datafield[@tag='260']">
200         <pz:metadata type="date">
201           <xsl:value-of select="translate(marc:subfield[@code='c'], 'cp[].', '')" />
202         </pz:metadata>
203       </xsl:for-each>
204
205       <xsl:if test="$date_008 and not(marc:datafield[@tag='260'])">
206         <pz:metadata type="date">
207           <xsl:choose>
208             <xsl:when test="$date_end_008">
209               <xsl:value-of select="concat($date_008,'-',$date_end_008)" />
210             </xsl:when>
211             <xsl:otherwise> 
212               <xsl:value-of select="$date_008" />
213             </xsl:otherwise>
214           </xsl:choose>
215         </pz:metadata>
216       </xsl:if>
217
218       <xsl:for-each select="marc:datafield[@tag='245']">
219         <pz:metadata type="title">
220           <xsl:value-of select="marc:subfield[@code='a']"/>
221         </pz:metadata>
222         <pz:metadata type="title-remainder">
223           <xsl:value-of select="marc:subfield[@code='b']"/>
224         </pz:metadata>
225         <pz:metadata type="title-responsibility">
226           <xsl:value-of select="marc:subfield[@code='c']"/>
227         </pz:metadata>
228         <pz:metadata type="title-dates">
229           <xsl:value-of select="marc:subfield[@code='f']"/>
230         </pz:metadata>
231         <pz:metadata type="title-medium">
232           <xsl:value-of select="marc:subfield[@code='h']"/>
233         </pz:metadata>
234         <pz:metadata type="title-number-section">
235           <xsl:value-of select="marc:subfield[@code='n']"/>
236         </pz:metadata>
237         <pz:metadata type="title-complete">
238           <xsl:value-of select="marc:subfield[@code='a']" />
239           <xsl:if test="marc:subfield[@code='b']" ><xsl:value-of select="concat(' ', marc:subfield[@code='b'])" /></xsl:if>
240         </pz:metadata>
241       </xsl:for-each>
242
243       <xsl:for-each select="marc:datafield[@tag='250']">
244         <pz:metadata type="edition">
245             <xsl:value-of select="marc:subfield[@code='a']"/>
246         </pz:metadata>
247       </xsl:for-each>
248
249       <xsl:for-each select="marc:datafield[@tag='260']">
250         <pz:metadata type="publication-place">
251           <xsl:value-of select="marc:subfield[@code='a']"/>
252         </pz:metadata>
253         <pz:metadata type="publication-name">
254           <xsl:value-of select="marc:subfield[@code='b']"/>
255         </pz:metadata>
256         <pz:metadata type="publication-date">
257           <xsl:value-of select="marc:subfield[@code='c']"/>
258         </pz:metadata>
259       </xsl:for-each>
260
261       <xsl:for-each select="marc:datafield[@tag='300']">
262         <pz:metadata type="physical-extent">
263           <xsl:value-of select="marc:subfield[@code='a']"/>
264         </pz:metadata>
265         <pz:metadata type="physical-format">
266           <xsl:value-of select="marc:subfield[@code='b']"/>
267         </pz:metadata>
268         <pz:metadata type="physical-dimensions">
269           <xsl:value-of select="marc:subfield[@code='c']"/>
270         </pz:metadata>
271         <pz:metadata type="physical-accomp">
272           <xsl:value-of select="marc:subfield[@code='e']"/>
273         </pz:metadata>
274         <pz:metadata type="physical-unittype">
275           <xsl:value-of select="marc:subfield[@code='f']"/>
276         </pz:metadata>
277         <pz:metadata type="physical-unitsize">
278           <xsl:value-of select="marc:subfield[@code='g']"/>
279         </pz:metadata>
280         <pz:metadata type="physical-specified">
281           <xsl:value-of select="marc:subfield[@code='3']"/>
282         </pz:metadata>
283       </xsl:for-each>
284
285       <xsl:for-each select="marc:datafield[@tag='440']">
286         <pz:metadata type="series-title">
287           <xsl:value-of select="marc:subfield[@code='a']"/>
288         </pz:metadata>
289       </xsl:for-each>
290
291       <xsl:for-each select="marc:datafield[@tag = '500' or @tag = '505' or
292                 @tag = '518' or @tag = '520' or @tag = '522']">
293         <pz:metadata type="description">
294             <xsl:value-of select="*/text()"/>
295         </pz:metadata>
296       </xsl:for-each>
297
298         <xsl:for-each
299                 select="marc:datafield[@tag='600' or @tag='610' or @tag='611' or @tag='630' or @tag='648' or @tag='650' or @tag='651' or @tag='653' or @tag='654' or @tag='655' or @tag='656' or @tag='657' or @tag='658' or @tag='662' or @tag='69X']">
300                 <pz:metadata type="subject">
301                         <xsl:value-of select="marc:subfield[@code='a']" />
302                 </pz:metadata>
303                 <pz:metadata type="subject-long">
304                         <xsl:for-each select="node()/text()">
305                                 <xsl:if test="position() > 1">
306                                         <xsl:text>, </xsl:text>
307                                 </xsl:if>
308                                 <xsl:variable name='value'>
309                                         <xsl:value-of select='normalize-space(.)' />
310                                 </xsl:variable>
311                                 <xsl:choose>
312                                         <xsl:when test="substring($value,string-length($value)) = ','">
313                                                 <xsl:value-of select="substring($value,1,string-length($value)-1)" />
314                                         </xsl:when>
315                                         <xsl:otherwise>
316                                                 <xsl:value-of select="$value" />
317                                         </xsl:otherwise>
318                                 </xsl:choose>
319                         </xsl:for-each>
320                 </pz:metadata>
321         </xsl:for-each>
322
323       <xsl:for-each select="marc:datafield[@tag='856']">
324         <pz:metadata type="electronic-url">
325           <xsl:value-of select="marc:subfield[@code='u']"/>
326         </pz:metadata>
327         <pz:metadata type="electronic-text">
328           <xsl:value-of select="marc:subfield[@code='y' or @code='3' or @code='a']"/>
329         </pz:metadata>
330         <pz:metadata type="electronic-note">
331           <xsl:value-of select="marc:subfield[@code='z']"/>
332         </pz:metadata>
333         <pz:metadata type="electronic-format-instruction">
334           <xsl:value-of select="marc:subfield[@code='i']"/>
335         </pz:metadata>
336         <pz:metadata type="electronic-format-type">
337           <xsl:value-of select="marc:subfield[@code='q']"/>
338         </pz:metadata>
339       </xsl:for-each>
340
341       <xsl:for-each select="marc:datafield[@tag='773']">
342         <pz:metadata type="citation">
343               <xsl:for-each select="*">
344                 <xsl:value-of select="normalize-space(.)"/>
345                 <xsl:text> </xsl:text>
346           </xsl:for-each>
347         </pz:metadata>
348         <xsl:if test="marc:subfield[@code='t']">
349           <pz:metadata type="journal-title">
350                 <xsl:value-of select="marc:subfield[@code='t']"/>
351           </pz:metadata>          
352         </xsl:if>
353         <xsl:if test="marc:subfield[@code='g']">
354           <pz:metadata type="journal-subpart">
355                 <xsl:value-of select="marc:subfield[@code='g']"/>
356           </pz:metadata>          
357         </xsl:if>
358       </xsl:for-each>
359
360       <xsl:for-each select="marc:datafield[@tag='852']">
361         <xsl:if test="marc:subfield[@code='y']">
362           <pz:metadata type="publicnote">
363             <xsl:value-of select="marc:subfield[@code='y']"/>
364           </pz:metadata>
365         </xsl:if>
366         <xsl:if test="marc:subfield[@code='h']">
367           <pz:metadata type="callnumber">
368             <xsl:value-of select="marc:subfield[@code='h']"/>
369           </pz:metadata>
370         </xsl:if>
371       </xsl:for-each>
372
373       <xsl:for-each select="marc:datafield[@tag='900']/marc:subfield[@code='a']">
374         <pz:metadata type="fulltext">
375           <xsl:value-of select="."/>
376         </pz:metadata>
377       </xsl:for-each>
378
379       <pz:metadata type="medium">
380         <xsl:value-of select="$medium"/>
381       </pz:metadata>
382
383       <pz:metadata type="has-fulltext">
384         <xsl:value-of select="$has_fulltext"/> 
385       </pz:metadata>
386
387       <xsl:for-each select="marc:datafield[@tag='900']/marc:subfield[@code='b']">
388         <pz:metadata type="fulltext">
389           <xsl:value-of select="."/>
390         </pz:metadata>
391       </xsl:for-each>
392
393       <!-- <xsl:if test="$fulltext_b">
394         <pz:metadata type="fulltext">
395           <xsl:value-of select="$fulltext_b"/>
396         </pz:metadata>
397       </xsl:if> -->
398
399       <xsl:for-each select="marc:datafield[@tag='907' or @tag='901']">
400         <pz:metadata type="iii-id">
401           <xsl:value-of select="marc:subfield[@code='a']"/>
402         </pz:metadata>
403       </xsl:for-each>
404
405       <xsl:for-each select="marc:datafield[@tag='926']">
406         <pz:metadata type="holding">
407           <xsl:for-each select="marc:subfield">
408             <xsl:if test="position() > 1">
409               <xsl:text> </xsl:text>
410             </xsl:if>
411             <xsl:value-of select="."/>
412           </xsl:for-each>
413         </pz:metadata>
414       </xsl:for-each>
415
416       <xsl:for-each select="marc:datafield[@tag='948']">
417         <pz:metadata type="holding">
418           <xsl:for-each select="marc:subfield">
419             <xsl:if test="position() > 1">
420               <xsl:text> </xsl:text>
421             </xsl:if>
422             <xsl:value-of select="."/>
423           </xsl:for-each>
424         </pz:metadata>
425       </xsl:for-each>
426
427       <xsl:for-each select="marc:datafield[@tag='991']">
428         <pz:metadata type="holding">
429           <xsl:for-each select="marc:subfield">
430             <xsl:if test="position() > 1">
431               <xsl:text> </xsl:text>
432             </xsl:if>
433             <xsl:value-of select="."/>
434           </xsl:for-each>
435         </pz:metadata>
436       </xsl:for-each>
437
438       <xsl:for-each select="marc:datafield[@tag='999']">
439         <pz:metadata type="localid">
440           <xsl:choose>
441             <xsl:when test="marc:subfield[@code='a']">
442               <xsl:value-of select="marc:subfield[@code='a']"/>
443             </xsl:when>
444             <xsl:when test="marc:subfield[@code='c']">
445               <xsl:value-of select="marc:subfield[@code='c']"/>
446             </xsl:when> 
447             <xsl:otherwise>
448               <xsl:value-of select="marc:subfield[@code='d']"/>
449             </xsl:otherwise>
450           </xsl:choose>
451         </pz:metadata>
452       </xsl:for-each>
453
454       <!-- passthrough id data -->
455       <xsl:for-each select="pz:metadata">
456           <xsl:copy-of select="."/>
457       </xsl:for-each>
458
459       <!-- other stylesheets importing this might want to define this -->
460       <xsl:call-template name="record-hook"/>
461
462     </pz:record>    
463   </xsl:template>
464   
465   <xsl:template match="text()"/>
466
467 </xsl:stylesheet>