]> git.evergreen-ils.org Git - evergreen/pines.git/blob - Open-ILS/src/sql/Pg/version-upgrade/pines-2.4.3-2.5.0-upgrade-db.sql
LP#1203734 copy circ counts include anon. circs
[evergreen/pines.git] / Open-ILS / src / sql / Pg / version-upgrade / pines-2.4.3-2.5.0-upgrade-db.sql
1 --Upgrade Script for 2.4.3 to 2.5.0
2
3 \qecho **** Libraries that upgraded or installed 2.0 before May 2011 never
4 \qecho **** got this schema, so add it first.
5 \qecho **** If this fails, don't worry, it probably won't be an issue.
6 \qecho
7
8 BEGIN;
9
10 CREATE SCHEMA staging;
11
12 CREATE TABLE staging.user_stage (
13         row_id                  BIGSERIAL PRIMARY KEY,
14         row_date                TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
15         usrname                 TEXT NOT NULL,
16         profile                 TEXT,
17         email                   TEXT,
18         passwd                  TEXT,
19         ident_type              INT DEFAULT 3,
20         first_given_name        TEXT,
21         second_given_name       TEXT,
22         family_name             TEXT,
23         day_phone               TEXT,
24         evening_phone           TEXT,
25         home_ou                 INT DEFAULT 2,
26         dob                     TEXT,
27         complete                BOOL DEFAULT FALSE
28 );
29
30 CREATE TABLE staging.card_stage ( -- for new library barcodes
31         row_id          BIGSERIAL PRIMARY KEY,
32         row_date        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
33         usrname         TEXT NOT NULL,
34         barcode         TEXT NOT NULL,
35         complete        BOOL DEFAULT FALSE
36 );
37
38 CREATE TABLE staging.mailing_address_stage (
39         row_id          BIGSERIAL PRIMARY KEY,
40         row_date        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
41         usrname         TEXT NOT NULL,  -- user's SIS barcode, for linking
42         street1         TEXT,
43         street2         TEXT,
44         city            TEXT NOT NULL DEFAULT '',
45         state           TEXT    NOT NULL DEFAULT 'OK',
46         country         TEXT NOT NULL DEFAULT 'US',
47         post_code       TEXT NOT NULL,
48         complete        BOOL DEFAULT FALSE
49 );
50
51 CREATE TABLE staging.billing_address_stage (
52         LIKE staging.mailing_address_stage INCLUDING DEFAULTS
53 );
54
55 ALTER TABLE staging.billing_address_stage ADD PRIMARY KEY (row_id);
56
57 CREATE TABLE staging.statcat_stage (
58         row_id          BIGSERIAL PRIMARY KEY,
59         row_date        TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
60         usrname         TEXT NOT NULL,
61         statcat         TEXT NOT NULL, -- for things like 'Year of study'
62         value           TEXT NOT NULL, -- and the value, such as 'Freshman'
63         complete        BOOL DEFAULT FALSE
64 );
65
66 COMMIT;
67
68
69 \qecho **** REAL 2.5 upgrade starting now...
70
71 \set eg_version '''2.5.0'''
72 BEGIN;
73 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.5.0', :eg_version);
74
75 SELECT evergreen.upgrade_deps_block_check('0794', :eg_version);
76
77 INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
78     VALUES (5,'PATRON_EXCEEDS_LOST_COUNT',oils_i18n_gettext(5, 'Patron exceeds max lost item threshold', 'csp', 'label'),'CIRC|FULFILL|HOLD|CAPTURE|RENEW', TRUE);
79
80 INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (
81     'circ.tally_lost', 'circ',
82     oils_i18n_gettext(
83         'circ.tally_lost',
84         'Include Lost circulations in lump sum tallies in Patron Display.',
85         'coust',
86         'label'),
87     oils_i18n_gettext(
88         'circ.tally_lost',
89         'In the Patron Display interface, the number of total active circulations for a given patron is presented in the Summary sidebar and underneath the Items Out navigation button.  This setting will include Lost circulations as counting toward these tallies.',
90         'coust',
91         'description'),
92     'bool'
93 );
94
95 -- Function: actor.calculate_system_penalties(integer, integer)
96 -- DROP FUNCTION actor.calculate_system_penalties(integer, integer);
97
98 CREATE OR REPLACE FUNCTION actor.calculate_system_penalties(match_user integer, context_org integer)
99     RETURNS SETOF actor.usr_standing_penalty AS
100 $BODY$
101 DECLARE
102     user_object             actor.usr%ROWTYPE;
103     new_sp_row            actor.usr_standing_penalty%ROWTYPE;
104     existing_sp_row       actor.usr_standing_penalty%ROWTYPE;
105     collections_fines      permission.grp_penalty_threshold%ROWTYPE;
106     max_fines               permission.grp_penalty_threshold%ROWTYPE;
107     max_overdue           permission.grp_penalty_threshold%ROWTYPE;
108     max_items_out       permission.grp_penalty_threshold%ROWTYPE;
109     max_lost                         permission.grp_penalty_threshold%ROWTYPE;
110     tmp_grp                 INT;
111     items_overdue        INT;
112     items_out              INT;
113     items_lost              INT;
114     context_org_list     INT[];
115     current_fines          NUMERIC(8,2) := 0.0;
116     tmp_fines               NUMERIC(8,2);
117     tmp_groc               RECORD;
118     tmp_circ                RECORD;
119     tmp_org                actor.org_unit%ROWTYPE;
120     tmp_penalty          config.standing_penalty%ROWTYPE;
121     tmp_depth            INTEGER;
122 BEGIN
123     SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
124
125     -- Max fines
126     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
127
128     -- Fail if the user has a high fine balance
129     LOOP
130         tmp_grp := user_object.profile;
131         LOOP
132             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 1 AND org_unit = tmp_org.id;
133
134             IF max_fines.threshold IS NULL THEN
135                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
136             ELSE
137                 EXIT;
138             END IF;
139
140             IF tmp_grp IS NULL THEN
141                 EXIT;
142             END IF;
143         END LOOP;
144
145         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
146             EXIT;
147         END IF;
148
149         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
150
151     END LOOP;
152
153     IF max_fines.threshold IS NOT NULL THEN
154
155         RETURN QUERY
156             SELECT  *
157               FROM  actor.usr_standing_penalty
158               WHERE usr = match_user
159                     AND org_unit = max_fines.org_unit
160                     AND (stop_date IS NULL or stop_date > NOW())
161                     AND standing_penalty = 1;
162
163         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
164
165         SELECT  SUM(f.balance_owed) INTO current_fines
166           FROM  money.materialized_billable_xact_summary f
167                 JOIN (
168                     SELECT  r.id
169                       FROM  booking.reservation r
170                       WHERE r.usr = match_user
171                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
172                             AND xact_finish IS NULL
173                                 UNION ALL
174                     SELECT  g.id
175                       FROM  money.grocery g
176                       WHERE g.usr = match_user
177                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
178                             AND xact_finish IS NULL
179                                 UNION ALL
180                     SELECT  circ.id
181                       FROM  action.circulation circ
182                       WHERE circ.usr = match_user
183                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
184                             AND xact_finish IS NULL ) l USING (id);
185
186         IF current_fines >= max_fines.threshold THEN
187             new_sp_row.usr := match_user;
188             new_sp_row.org_unit := max_fines.org_unit;
189             new_sp_row.standing_penalty := 1;
190             RETURN NEXT new_sp_row;
191         END IF;
192     END IF;
193
194     -- Start over for max overdue
195     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
196
197     -- Fail if the user has too many overdue items
198     LOOP
199         tmp_grp := user_object.profile;
200         LOOP
201
202             SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 2 AND org_unit = tmp_org.id;
203
204             IF max_overdue.threshold IS NULL THEN
205                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
206             ELSE
207                 EXIT;
208             END IF;
209
210             IF tmp_grp IS NULL THEN
211                 EXIT;
212             END IF;
213         END LOOP;
214
215         IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
216             EXIT;
217         END IF;
218
219         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
220
221     END LOOP;
222
223     IF max_overdue.threshold IS NOT NULL THEN
224
225         RETURN QUERY
226             SELECT  *
227               FROM  actor.usr_standing_penalty
228               WHERE usr = match_user
229                     AND org_unit = max_overdue.org_unit
230                     AND (stop_date IS NULL or stop_date > NOW())
231                     AND standing_penalty = 2;
232
233         SELECT  INTO items_overdue COUNT(*)
234           FROM  action.circulation circ
235                 JOIN  actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
236           WHERE circ.usr = match_user
237             AND circ.checkin_time IS NULL
238             AND circ.due_date < NOW()
239             AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);
240
241         IF items_overdue >= max_overdue.threshold::INT THEN
242             new_sp_row.usr := match_user;
243             new_sp_row.org_unit := max_overdue.org_unit;
244             new_sp_row.standing_penalty := 2;
245             RETURN NEXT new_sp_row;
246         END IF;
247     END IF;
248
249     -- Start over for max out
250     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
251
252     -- Fail if the user has too many checked out items
253     LOOP
254         tmp_grp := user_object.profile;
255         LOOP
256             SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 3 AND org_unit = tmp_org.id;
257
258             IF max_items_out.threshold IS NULL THEN
259                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
260             ELSE
261                 EXIT;
262             END IF;
263
264             IF tmp_grp IS NULL THEN
265                 EXIT;
266             END IF;
267         END LOOP;
268
269         IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
270             EXIT;
271         END IF;
272
273         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
274
275     END LOOP;
276
277     -- Fail if the user has too many items checked out
278     IF max_items_out.threshold IS NOT NULL THEN
279         RETURN QUERY
280             SELECT  *
281             FROM  actor.usr_standing_penalty
282             WHERE usr = match_user
283                 AND org_unit = max_items_out.org_unit
284                 AND (stop_date IS NULL or stop_date > NOW())
285                 AND standing_penalty = 3;
286             SELECT  INTO items_out COUNT(*)
287             FROM  action.circulation circ
288             JOIN  actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
289             WHERE circ.usr = match_user
290                 AND circ.checkin_time IS NULL
291                 AND (circ.stop_fines IN (
292                     SELECT 'MAXFINES'::TEXT
293                     UNION ALL
294                     SELECT 'LONGOVERDUE'::TEXT
295                     UNION ALL
296                     SELECT 'LOST'::TEXT
297                     WHERE 'true' ILIKE
298                     (
299                         SELECT CASE
300                             WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.tally_lost', circ.circ_lib)) ILIKE 'true' THEN 'true'
301                             ELSE 'false'
302                         END
303                     )
304                     UNION ALL
305                     SELECT 'CLAIMSRETURNED'::TEXT
306                     WHERE 'false' ILIKE
307                         (
308                             SELECT CASE
309                             WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.do_not_tally_claims_returned', circ.circ_lib)) ILIKE 'true' THEN 'true'
310                             ELSE 'false'
311                             END
312                         )
313                     ) OR circ.stop_fines IS NULL)
314                 AND xact_finish IS NULL;
315
316     IF items_out >= max_items_out.threshold::INT THEN
317         new_sp_row.usr := match_user;
318         new_sp_row.org_unit := max_items_out.org_unit;
319         new_sp_row.standing_penalty := 3;
320         RETURN NEXT new_sp_row;
321    END IF;
322 END IF;
323
324     -- Start over for max lost
325     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
326
327     -- Fail if the user has too many lost items
328     LOOP
329         tmp_grp := user_object.profile;
330         LOOP
331             SELECT * INTO max_lost FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 5 AND org_unit = tmp_org.id;
332             IF max_lost.threshold IS NULL THEN
333                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
334             ELSE
335                 EXIT;
336             END IF;
337
338             IF tmp_grp IS NULL THEN
339                 EXIT;
340             END IF;
341         END LOOP;
342
343         IF max_lost.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
344             EXIT;
345         END IF;
346
347         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
348
349     END LOOP;
350
351     IF max_lost.threshold IS NOT NULL THEN
352         RETURN QUERY
353             SELECT  *
354             FROM  actor.usr_standing_penalty
355             WHERE usr = match_user
356                 AND org_unit = max_lost.org_unit
357                 AND (stop_date IS NULL or stop_date > NOW())
358                 AND standing_penalty = 5;
359
360         SELECT INTO items_lost COUNT(*)
361         FROM  action.circulation circ
362             JOIN  actor.org_unit_full_path( max_lost.org_unit ) fp ON (circ.circ_lib = fp.id)
363             WHERE circ.usr = match_user
364                 AND circ.checkin_time IS NULL
365                 AND (circ.stop_fines = 'LOST')
366                 AND xact_finish IS NULL;
367
368         IF items_lost >= max_lost.threshold::INT AND 0 < max_lost.threshold::INT THEN
369             new_sp_row.usr := match_user;
370             new_sp_row.org_unit := max_lost.org_unit;
371             new_sp_row.standing_penalty := 5;
372             RETURN NEXT new_sp_row;
373         END IF;
374     END IF;
375
376     -- Start over for collections warning
377     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
378
379     -- Fail if the user has a collections-level fine balance
380     LOOP
381         tmp_grp := user_object.profile;
382         LOOP
383             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id;
384             IF max_fines.threshold IS NULL THEN
385                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
386             ELSE
387                 EXIT;
388             END IF;
389
390             IF tmp_grp IS NULL THEN
391                 EXIT;
392             END IF;
393         END LOOP;
394
395         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
396             EXIT;
397         END IF;
398
399         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
400
401     END LOOP;
402
403     IF max_fines.threshold IS NOT NULL THEN
404
405         RETURN QUERY
406             SELECT  *
407                 FROM  actor.usr_standing_penalty
408                 WHERE usr = match_user
409                     AND org_unit = max_fines.org_unit
410                     AND (stop_date IS NULL or stop_date > NOW())
411                     AND standing_penalty = 4;
412
413         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
414
415         SELECT  SUM(f.balance_owed) INTO current_fines
416             FROM  money.materialized_billable_xact_summary f
417                 JOIN (
418                     SELECT  r.id
419                         FROM  booking.reservation r
420                         WHERE r.usr = match_user
421                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
422                             AND r.xact_finish IS NULL
423                                 UNION ALL
424                     SELECT  g.id
425                         FROM  money.grocery g
426                         WHERE g.usr = match_user
427                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
428                             AND g.xact_finish IS NULL
429                                 UNION ALL
430                     SELECT  circ.id
431                         FROM  action.circulation circ
432                         WHERE circ.usr = match_user
433                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
434                             AND circ.xact_finish IS NULL ) l USING (id);
435
436         IF current_fines >= max_fines.threshold THEN
437             new_sp_row.usr := match_user;
438             new_sp_row.org_unit := max_fines.org_unit;
439             new_sp_row.standing_penalty := 4;
440             RETURN NEXT new_sp_row;
441         END IF;
442     END IF;
443
444     -- Start over for in collections
445     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
446
447     -- Remove the in-collections penalty if the user has paid down enough
448     -- This penalty is different, because this code is not responsible for creating 
449     -- new in-collections penalties, only for removing them
450     LOOP
451         tmp_grp := user_object.profile;
452         LOOP
453             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 30 AND org_unit = tmp_org.id;
454
455             IF max_fines.threshold IS NULL THEN
456                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
457             ELSE
458                 EXIT;
459             END IF;
460
461             IF tmp_grp IS NULL THEN
462                 EXIT;
463             END IF;
464         END LOOP;
465
466         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
467             EXIT;
468         END IF;
469
470         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
471
472     END LOOP;
473
474     IF max_fines.threshold IS NOT NULL THEN
475
476         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
477
478         -- first, see if the user had paid down to the threshold
479         SELECT  SUM(f.balance_owed) INTO current_fines
480           FROM  money.materialized_billable_xact_summary f
481                 JOIN (
482                     SELECT  r.id
483                         FROM  booking.reservation r
484                         WHERE r.usr = match_user
485                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
486                             AND r.xact_finish IS NULL
487                                 UNION ALL
488                     SELECT  g.id
489                         FROM  money.grocery g
490                         WHERE g.usr = match_user
491                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
492                             AND g.xact_finish IS NULL
493                                 UNION ALL
494                     SELECT  circ.id
495                         FROM  action.circulation circ
496                         WHERE circ.usr = match_user
497                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
498                             AND circ.xact_finish IS NULL ) l USING (id);
499
500         IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
501             -- patron has paid down enough
502
503             SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = 30;
504
505             IF tmp_penalty.org_depth IS NOT NULL THEN
506
507                 -- since this code is not responsible for applying the penalty, it can't 
508                 -- guarantee the current context org will match the org at which the penalty 
509                 --- was applied.  search up the org tree until we hit the configured penalty depth
510                 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
511                 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
512
513                 WHILE tmp_depth >= tmp_penalty.org_depth LOOP
514
515                     RETURN QUERY
516                         SELECT  *
517                             FROM  actor.usr_standing_penalty
518                             WHERE usr = match_user
519                                 AND org_unit = tmp_org.id
520                                 AND (stop_date IS NULL or stop_date > NOW())
521                                 AND standing_penalty = 30;
522
523                     IF tmp_org.parent_ou IS NULL THEN
524                         EXIT;
525                     END IF;
526
527                     SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
528                     SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
529                 END LOOP;
530
531             ELSE
532
533                 -- no penalty depth is defined, look for exact matches
534
535                 RETURN QUERY
536                     SELECT  *
537                         FROM  actor.usr_standing_penalty
538                         WHERE usr = match_user
539                             AND org_unit = max_fines.org_unit
540                             AND (stop_date IS NULL or stop_date > NOW())
541                             AND standing_penalty = 30;
542             END IF;
543
544         END IF;
545
546     END IF;
547
548     RETURN;
549 END;
550 $BODY$
551     LANGUAGE plpgsql VOLATILE
552     COST 100
553     ROWS 1000;
554
555
556 --SELECT evergreen.upgrade_deps_block_check('0795', :eg_version);
557 --
558 --CREATE OR REPLACE FUNCTION 
559 --    evergreen.z3950_attr_name_is_valid(TEXT) RETURNS BOOLEAN AS $func$
560 --    SELECT EXISTS (SELECT 1 FROM config.z3950_attr WHERE name = $1);
561 --$func$ LANGUAGE SQL STRICT IMMUTABLE;
562 --
563 --COMMENT ON FUNCTION evergreen.z3950_attr_name_is_valid(TEXT) IS $$
564 --Results in TRUE if there exists at least one config.z3950_attr
565 --with the provided name.  Used by config.z3950_index_field_map
566 --to verify z3950_attr_type maps.
567 --$$;
568 --
569 --CREATE TABLE config.z3950_index_field_map (
570 --    id              SERIAL  PRIMARY KEY,
571 --    label           TEXT    NOT NULL, -- i18n
572 --    metabib_field   INTEGER REFERENCES config.metabib_field(id),
573 --    record_attr     TEXT    REFERENCES config.record_attr_definition(name),
574 --    z3950_attr      INTEGER REFERENCES config.z3950_attr(id),
575 --    z3950_attr_type TEXT,-- REFERENCES config.z3950_attr(name)
576 --    CONSTRAINT metabib_field_or_record_attr CHECK (
577 --        metabib_field IS NOT NULL OR 
578 --        record_attr IS NOT NULL
579 --    ),
580 --    CONSTRAINT attr_or_attr_type CHECK (
581 --        z3950_attr IS NOT NULL OR 
582 --        z3950_attr_type IS NOT NULL
583 --    ),
584 --    -- ensure the selected z3950_attr_type refers to a valid attr name
585 --    CONSTRAINT valid_z3950_attr_type CHECK (
586 --        z3950_attr_type IS NULL OR 
587 --            evergreen.z3950_attr_name_is_valid(z3950_attr_type)
588 --    )
589 --);
590 --
591 ---- seed data
592 --
593 --INSERT INTO config.z3950_index_field_map 
594 --    (id, label, metabib_field, z3950_attr_type) VALUES 
595 --(1, oils_i18n_gettext(1, 'Title',   'czifm', 'label'), 5,  'title'),
596 --(2, oils_i18n_gettext(2, 'Author',  'czifm', 'label'), 8,  'author'),
597 --(3, oils_i18n_gettext(3, 'ISBN',    'czifm', 'label'), 18, 'isbn'),
598 --(4, oils_i18n_gettext(4, 'ISSN',    'czifm', 'label'), 19, 'issn'),
599 --(5, oils_i18n_gettext(5, 'LCCN',    'czifm', 'label'), 30, 'lccn');
600 --
601 --INSERT INTO config.z3950_index_field_map 
602 --    (id, label, record_attr, z3950_attr_type) VALUES 
603 --(6, oils_i18n_gettext(6, 'Pubdate',  'czifm', 'label'),'pubdate', 'pubdate'),
604 --(7, oils_i18n_gettext(7, 'Item Type', 'czifm', 'label'),'item_type', 'item_type');
605 --
606 --
607 ---- let's leave room for more stock mappings
608 --SELECT SETVAL('config.z3950_index_field_map_id_seq'::TEXT, 1000);
609 --
610 --INSERT INTO config.org_unit_setting_type
611 --    (name, grp, label, description, datatype)
612 --    VALUES (
613 --        'cat.z3950.batch.max_parallel',
614 --        'cat',
615 --        oils_i18n_gettext(
616 --            'cat.z3950.batch.max_parallel',
617 --            'Maximum Parallel Z39.50 Batch Searches',
618 --            'coust',
619 --            'label'
620 --        ),
621 --        oils_i18n_gettext(
622 --            'cat.z3950.batch.max_parallel',
623 --            'The maximum number of Z39.50 searches that can be in-flight at any given time when performing batch Z39.50 searches',
624 --            'coust',
625 --            'description'
626 --        ),
627 --        'integer'
628 --    );
629 --
630 --INSERT INTO config.org_unit_setting_type
631 --    (name, grp, label, description, datatype)
632 --    VALUES (
633 --        'cat.z3950.batch.max_results',
634 --        'cat',
635 --        oils_i18n_gettext(
636 --            'cat.z3950.batch.max_results',
637 --            'Maximum Z39.50 Batch Search Results',
638 --            'coust',
639 --            'label'
640 --        ),
641 --        oils_i18n_gettext(
642 --            'cat.z3950.batch.max_results',
643 --            'The maximum number of search results to retrieve and queue for each record + Z39 source during batch Z39.50 searches',
644 --            'coust',
645 --            'description'
646 --        ),
647 --        'integer'
648 --    );
649 --
650 --INSERT INTO vandelay.bib_attr_definition (id, code, description, xpath) 
651 --    VALUES (
652 --        16, 
653 --        'zsource',
654 --        oils_i18n_gettext(16, 'Z39.50 Source', 'vqbrad', 'description'),
655 --        '//*[@tag="901"]/*[@code="z"]'
656 --    );
657
658
659
660
661 SELECT evergreen.upgrade_deps_block_check('0796', :eg_version);
662
663 ALTER TABLE vandelay.bib_queue ADD COLUMN match_bucket
664    INTEGER REFERENCES container.biblio_record_entry_bucket(id)
665    ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;  
666
667 CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
668 DECLARE
669     incoming_existing_id    TEXT;
670     test_result             vandelay.match_set_test_result%ROWTYPE;
671     tmp_rec                 BIGINT;
672     match_set               INT;
673     match_bucket            INT;
674 BEGIN
675     IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
676         RETURN NEW;
677     END IF;
678
679     DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
680
681     SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
682
683     IF match_set IS NOT NULL THEN
684         NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
685     END IF;
686
687     -- Perfect matches on 901$c exit early with a match with high quality.
688     incoming_existing_id :=
689         oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
690
691     IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
692         SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
693         IF tmp_rec IS NOT NULL THEN
694             INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality) 
695                 SELECT
696                     NEW.id, 
697                     b.id,
698                     9999,
699                     -- note: no match_set means quality==0
700                     vandelay.measure_record_quality( b.marc, match_set )
701                 FROM biblio.record_entry b
702                 WHERE id = incoming_existing_id::bigint;
703         END IF;
704     END IF;
705
706     IF match_set IS NULL THEN
707         RETURN NEW;
708     END IF;
709
710     SELECT q.match_bucket INTO match_bucket FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
711
712     FOR test_result IN SELECT * FROM
713         vandelay.match_set_test_marcxml(match_set, NEW.marc, match_bucket) LOOP
714
715         INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
716             SELECT  
717                 NEW.id,
718                 test_result.record,
719                 test_result.quality,
720                 vandelay.measure_record_quality( b.marc, match_set )
721                 FROM  biblio.record_entry b
722                 WHERE id = test_result.record;
723
724     END LOOP;
725
726     RETURN NEW;
727 END;
728 $func$ LANGUAGE PLPGSQL;
729
730
731 DROP FUNCTION IF EXISTS vandelay.match_set_test_marcxml(INTEGER, TEXT);
732
733 CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
734     match_set_id INTEGER, record_xml TEXT, bucket_id INTEGER 
735 ) RETURNS SETOF vandelay.match_set_test_result AS $$
736 DECLARE
737     tags_rstore HSTORE;
738     svf_rstore  HSTORE;
739     coal        TEXT;
740     joins       TEXT;
741     query_      TEXT;
742     wq          TEXT;
743     qvalue      INTEGER;
744     rec         RECORD;
745 BEGIN
746     tags_rstore := vandelay.flatten_marc_hstore(record_xml);
747     svf_rstore := vandelay.extract_rec_attrs(record_xml);
748
749     CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
750     CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
751
752     -- generate the where clause and return that directly (into wq), and as
753     -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
754     wq := vandelay.get_expr_from_match_set(match_set_id, tags_rstore);
755
756     query_ := 'SELECT DISTINCT(record), ';
757
758     -- qrows table is for the quality bits we add to the SELECT clause
759     SELECT ARRAY_TO_STRING(
760         ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
761     ) INTO coal FROM _vandelay_tmp_qrows;
762
763     -- our query string so far is the SELECT clause and the inital FROM.
764     -- no JOINs yet nor the WHERE clause
765     query_ := query_ || coal || ' AS quality ' || E'\n';
766
767     -- jrows table is for the joins we must make (and the real text conditions)
768     SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
769         FROM _vandelay_tmp_jrows;
770
771     -- add those joins and the where clause to our query.
772     query_ := query_ || joins || E'\n';
773
774     -- join the record bucket
775     IF bucket_id IS NOT NULL THEN
776         query_ := query_ || 'JOIN container.biblio_record_entry_bucket_item ' ||
777             'brebi ON (brebi.target_biblio_record_entry = record ' ||
778             'AND brebi.bucket = ' || bucket_id || E')\n';
779     END IF;
780
781     query_ := query_ || 'JOIN biblio.record_entry bre ON (bre.id = record) ' || 'WHERE ' || wq || ' AND not bre.deleted';
782
783     -- this will return rows of record,quality
784     FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
785         RETURN NEXT rec;
786     END LOOP;
787
788     DROP TABLE _vandelay_tmp_qrows;
789     DROP TABLE _vandelay_tmp_jrows;
790     RETURN;
791 END;
792 $$ LANGUAGE PLPGSQL;
793
794
795 SELECT evergreen.upgrade_deps_block_check('0797', :eg_version);
796
797 -- New global flags for the purge function
798 INSERT INTO config.global_flag  (name, label, enabled)
799     VALUES (
800         'history.hold.retention_age',
801         oils_i18n_gettext('history.hold.retention_age', 'Historical Hold Retention Age', 'cgf', 'label'),
802         TRUE
803     ),(
804         'history.hold.retention_age_fulfilled',
805         oils_i18n_gettext('history.hold.retention_age_fulfilled', 'Historical Hold Retention Age - Fulfilled', 'cgf', 'label'),
806         FALSE
807     ),(
808         'history.hold.retention_age_canceled',
809         oils_i18n_gettext('history.hold.retention_age_canceled', 'Historical Hold Retention Age - Canceled (Default)', 'cgf', 'label'),
810         FALSE
811     ),(
812         'history.hold.retention_age_canceled_1',
813         oils_i18n_gettext('history.hold.retention_age_canceled_1', 'Historical Hold Retention Age - Canceled (Untarged expiration)', 'cgf', 'label'),
814         FALSE
815     ),(
816         'history.hold.retention_age_canceled_2',
817         oils_i18n_gettext('history.hold.retention_age_canceled_2', 'Historical Hold Retention Age - Canceled (Hold Shelf expiration)', 'cgf', 'label'),
818         FALSE
819     ),(
820         'history.hold.retention_age_canceled_3',
821         oils_i18n_gettext('history.hold.retention_age_canceled_3', 'Historical Hold Retention Age - Canceled (Patron via phone)', 'cgf', 'label'),
822         TRUE
823     ),(
824         'history.hold.retention_age_canceled_4',
825         oils_i18n_gettext('history.hold.retention_age_canceled_4', 'Historical Hold Retention Age - Canceled (Patron in person)', 'cgf', 'label'),
826         TRUE
827     ),(
828         'history.hold.retention_age_canceled_5',
829         oils_i18n_gettext('history.hold.retention_age_canceled_5', 'Historical Hold Retention Age - Canceled (Staff forced)', 'cgf', 'label'),
830         TRUE
831     ),(
832         'history.hold.retention_age_canceled_6',
833         oils_i18n_gettext('history.hold.retention_age_canceled_6', 'Historical Hold Retention Age - Canceled (Patron via OPAC)', 'cgf', 'label'),
834         FALSE
835     );
836
837 CREATE OR REPLACE FUNCTION action.purge_holds() RETURNS INT AS $func$
838 DECLARE
839   current_hold RECORD;
840   purged_holds INT;
841   cgf_d INTERVAL;
842   cgf_f INTERVAL;
843   cgf_c INTERVAL;
844   prev_usr INT;
845   user_start TIMESTAMPTZ;
846   user_age INTERVAL;
847   user_count INT;
848 BEGIN
849   purged_holds := 0;
850   SELECT INTO cgf_d value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age' AND enabled;
851   SELECT INTO cgf_f value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age_fulfilled' AND enabled;
852   SELECT INTO cgf_c value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age_canceled' AND enabled;
853   FOR current_hold IN
854     SELECT
855       rank() OVER (PARTITION BY usr ORDER BY COALESCE(fulfillment_time, cancel_time) DESC),
856       cgf_cs.value::INTERVAL as cgf_cs,
857       ahr.*
858     FROM
859       action.hold_request ahr
860       LEFT JOIN config.global_flag cgf_cs ON (ahr.cancel_cause IS NOT NULL AND cgf_cs.name = 'history.hold.retention_age_canceled_' || ahr.cancel_cause AND cgf_cs.enabled)
861     WHERE
862       (fulfillment_time IS NOT NULL OR cancel_time IS NOT NULL)
863   LOOP
864     IF prev_usr IS NULL OR prev_usr != current_hold.usr THEN
865       prev_usr := current_hold.usr;
866       SELECT INTO user_start oils_json_to_text(value)::TIMESTAMPTZ FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_start';
867       SELECT INTO user_age oils_json_to_text(value)::INTERVAL FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_age';
868       SELECT INTO user_count oils_json_to_text(value)::INT FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_count';
869       IF user_start IS NOT NULL THEN
870         user_age := LEAST(user_age, AGE(NOW(), user_start));
871       END IF;
872       IF user_count IS NULL THEN
873         user_count := 1000; -- Assumption based on the user visible holds routine
874       END IF;
875     END IF;
876     -- Library keep age trumps user keep anything, for purposes of being able to hold on to things when staff canceled and such.
877     IF current_hold.fulfillment_time IS NOT NULL AND current_hold.fulfillment_time > NOW() - COALESCE(cgf_f, cgf_d) THEN
878       CONTINUE;
879     END IF;
880     IF current_hold.cancel_time IS NOT NULL AND current_hold.cancel_time > NOW() - COALESCE(current_hold.cgf_cs, cgf_c, cgf_d) THEN
881       CONTINUE;
882     END IF;
883
884     -- User keep age needs combining with count. If too old AND within the count, keep!
885     IF user_start IS NOT NULL AND COALESCE(current_hold.fulfillment_time, current_hold.cancel_time) > NOW() - user_age AND current_hold.rank <= user_count THEN
886       CONTINUE;
887     END IF;
888
889     -- All checks should have passed, delete!
890     DELETE FROM action.hold_request WHERE id = current_hold.id;
891     purged_holds := purged_holds + 1;
892   END LOOP;
893   RETURN purged_holds;
894 END;
895 $func$ LANGUAGE plpgsql;
896
897 CREATE OR REPLACE FUNCTION action.usr_visible_holds (usr_id INT) RETURNS SETOF action.hold_request AS $func$
898 DECLARE
899     h               action.hold_request%ROWTYPE;
900     view_age        INTERVAL;
901     view_count      INT;
902     usr_view_count  actor.usr_setting%ROWTYPE;
903     usr_view_age    actor.usr_setting%ROWTYPE;
904     usr_view_start  actor.usr_setting%ROWTYPE;
905 BEGIN
906     SELECT * INTO usr_view_count FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_count';
907     SELECT * INTO usr_view_age FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_age';
908     SELECT * INTO usr_view_start FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_start';
909
910     FOR h IN
911         SELECT  *
912           FROM  action.hold_request
913           WHERE usr = usr_id
914                 AND fulfillment_time IS NULL
915                 AND cancel_time IS NULL
916           ORDER BY request_time DESC
917     LOOP
918         RETURN NEXT h;
919     END LOOP;
920
921     IF usr_view_start.value IS NULL THEN
922         RETURN;
923     END IF;
924
925     IF usr_view_age.value IS NOT NULL THEN
926         -- User opted in and supplied a retention age
927         IF oils_json_to_text(usr_view_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ) THEN
928             view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
929         ELSE
930             view_age := oils_json_to_text(usr_view_age.value)::INTERVAL;
931         END IF;
932     ELSE
933         -- User opted in
934         view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
935     END IF;
936
937     IF usr_view_count.value IS NOT NULL THEN
938         view_count := oils_json_to_text(usr_view_count.value)::INT;
939     ELSE
940         view_count := 1000;
941     END IF;
942
943     -- show some fulfilled/canceled holds
944     FOR h IN
945         SELECT  *
946           FROM  action.hold_request
947           WHERE usr = usr_id
948                 AND ( fulfillment_time IS NOT NULL OR cancel_time IS NOT NULL )
949                 AND COALESCE(fulfillment_time, cancel_time) > NOW() - view_age
950           ORDER BY COALESCE(fulfillment_time, cancel_time) DESC
951           LIMIT view_count
952     LOOP
953         RETURN NEXT h;
954     END LOOP;
955
956     RETURN;
957 END;
958 $func$ LANGUAGE PLPGSQL;
959
960 CREATE TABLE action.aged_hold_request (
961     usr_post_code               TEXT,
962     usr_home_ou         INT     NOT NULL,
963     usr_profile         INT     NOT NULL,
964     usr_birth_year              INT,
965     staff_placed        BOOLEAN NOT NULL,
966     LIKE action.hold_request
967 );
968 ALTER TABLE action.aged_hold_request
969       ADD PRIMARY KEY (id),
970       DROP COLUMN usr,
971       DROP COLUMN requestor,
972       DROP COLUMN sms_carrier,
973       ALTER COLUMN phone_notify TYPE BOOLEAN
974             USING CASE WHEN phone_notify IS NULL OR phone_notify = '' THEN FALSE ELSE TRUE END,
975       ALTER COLUMN sms_notify TYPE BOOLEAN
976             USING CASE WHEN sms_notify IS NULL OR sms_notify = '' THEN FALSE ELSE TRUE END,
977       ALTER COLUMN phone_notify SET NOT NULL,
978       ALTER COLUMN sms_notify SET NOT NULL;
979 CREATE INDEX aged_hold_request_target_idx ON action.aged_hold_request (target);
980 CREATE INDEX aged_hold_request_pickup_lib_idx ON action.aged_hold_request (pickup_lib);
981 CREATE INDEX aged_hold_request_current_copy_idx ON action.aged_hold_request (current_copy);
982 CREATE INDEX aged_hold_request_fulfillment_staff_idx ON action.aged_hold_request ( fulfillment_staff );
983
984 CREATE OR REPLACE VIEW action.all_hold_request AS
985     SELECT DISTINCT
986            COALESCE(a.post_code, b.post_code) AS usr_post_code,
987            p.home_ou AS usr_home_ou,
988            p.profile AS usr_profile,
989            EXTRACT(YEAR FROM p.dob)::INT AS usr_birth_year,
990            CAST(ahr.requestor <> ahr.usr AS BOOLEAN) AS staff_placed,
991            ahr.id,
992            ahr.request_time,
993            ahr.capture_time,
994            ahr.fulfillment_time,
995            ahr.checkin_time,
996            ahr.return_time,
997            ahr.prev_check_time,
998            ahr.expire_time,
999            ahr.cancel_time,
1000            ahr.cancel_cause,
1001            ahr.cancel_note,
1002            ahr.target,
1003            ahr.current_copy,
1004            ahr.fulfillment_staff,
1005            ahr.fulfillment_lib,
1006            ahr.request_lib,
1007            ahr.selection_ou,
1008            ahr.selection_depth,
1009            ahr.pickup_lib,
1010            ahr.hold_type,
1011            ahr.holdable_formats,
1012            CASE
1013            WHEN ahr.phone_notify IS NULL THEN FALSE
1014            WHEN ahr.phone_notify = '' THEN FALSE
1015            ELSE TRUE
1016            END AS phone_notify,
1017            ahr.email_notify,
1018            CASE
1019            WHEN ahr.sms_notify IS NULL THEN FALSE
1020            WHEN ahr.sms_notify = '' THEN FALSE
1021            ELSE TRUE
1022            END AS sms_notify,
1023            ahr.frozen,
1024            ahr.thaw_date,
1025            ahr.shelf_time,
1026            ahr.cut_in_line,
1027            ahr.mint_condition,
1028            ahr.shelf_expire_time,
1029            ahr.current_shelf_lib
1030     FROM action.hold_request ahr
1031          JOIN actor.usr p ON (ahr.usr = p.id)
1032          LEFT JOIN actor.usr_address a ON (p.mailing_address = a.id)
1033          LEFT JOIN actor.usr_address b ON (p.billing_address = b.id)
1034     UNION ALL
1035     SELECT 
1036            usr_post_code,
1037            usr_home_ou,
1038            usr_profile,
1039            usr_birth_year,
1040            staff_placed,
1041            id,
1042            request_time,
1043            capture_time,
1044            fulfillment_time,
1045            checkin_time,
1046            return_time,
1047            prev_check_time,
1048            expire_time,
1049            cancel_time,
1050            cancel_cause,
1051            cancel_note,
1052            target,
1053            current_copy,
1054            fulfillment_staff,
1055            fulfillment_lib,
1056            request_lib,
1057            selection_ou,
1058            selection_depth,
1059            pickup_lib,
1060            hold_type,
1061            holdable_formats,
1062            phone_notify,
1063            email_notify,
1064            sms_notify,
1065            frozen,
1066            thaw_date,
1067            shelf_time,
1068            cut_in_line,
1069            mint_condition,
1070            shelf_expire_time,
1071            current_shelf_lib
1072     FROM action.aged_hold_request;
1073
1074 CREATE OR REPLACE FUNCTION action.age_hold_on_delete () RETURNS TRIGGER AS $$
1075 DECLARE
1076 BEGIN
1077     -- Archive a copy of the old row to action.aged_hold_request
1078
1079     INSERT INTO action.aged_hold_request
1080            (usr_post_code,
1081             usr_home_ou,
1082             usr_profile,
1083             usr_birth_year,
1084             staff_placed,
1085             id,
1086             request_time,
1087             capture_time,
1088             fulfillment_time,
1089             checkin_time,
1090             return_time,
1091             prev_check_time,
1092             expire_time,
1093             cancel_time,
1094             cancel_cause,
1095             cancel_note,
1096             target,
1097             current_copy,
1098             fulfillment_staff,
1099             fulfillment_lib,
1100             request_lib,
1101             selection_ou,
1102             selection_depth,
1103             pickup_lib,
1104             hold_type,
1105             holdable_formats,
1106             phone_notify,
1107             email_notify,
1108             sms_notify,
1109             frozen,
1110             thaw_date,
1111             shelf_time,
1112             cut_in_line,
1113             mint_condition,
1114             shelf_expire_time,
1115             current_shelf_lib)
1116       SELECT 
1117            usr_post_code,
1118            usr_home_ou,
1119            usr_profile,
1120            usr_birth_year,
1121            staff_placed,
1122            id,
1123            request_time,
1124            capture_time,
1125            fulfillment_time,
1126            checkin_time,
1127            return_time,
1128            prev_check_time,
1129            expire_time,
1130            cancel_time,
1131            cancel_cause,
1132            cancel_note,
1133            target,
1134            current_copy,
1135            fulfillment_staff,
1136            fulfillment_lib,
1137            request_lib,
1138            selection_ou,
1139            selection_depth,
1140            pickup_lib,
1141            hold_type,
1142            holdable_formats,
1143            phone_notify,
1144            email_notify,
1145            sms_notify,
1146            frozen,
1147            thaw_date,
1148            shelf_time,
1149            cut_in_line,
1150            mint_condition,
1151            shelf_expire_time,
1152            current_shelf_lib
1153         FROM action.all_hold_request WHERE id = OLD.id;
1154
1155     RETURN OLD;
1156 END;
1157 $$ LANGUAGE 'plpgsql';
1158
1159 CREATE TRIGGER action_hold_request_aging_tgr
1160         BEFORE DELETE ON action.hold_request
1161         FOR EACH ROW
1162         EXECUTE PROCEDURE action.age_hold_on_delete ();
1163
1164
1165 SELECT evergreen.upgrade_deps_block_check('0798', :eg_version);
1166
1167 INSERT INTO config.global_flag (name, label)
1168     VALUES (
1169         'history.circ.retention_uses_last_finished',
1170         oils_i18n_gettext(
1171             'history.circ.retention_uses_last_finished',
1172             'Historical Circulations use most recent xact_finish date instead of last circ''s.',
1173             'cgf',
1174             'label'
1175         )
1176     ),(
1177         'history.circ.retention_age_is_min',
1178         oils_i18n_gettext(
1179             'history.circ.retention_age_is_min',
1180             'Historical Circulations are kept for global retention age at a minimum, regardless of user preferences.',
1181             'cgf',
1182             'label'
1183         )
1184     );
1185
1186
1187 -- Drop old variants
1188 DROP FUNCTION IF EXISTS action.circ_chain(INTEGER);
1189 DROP FUNCTION IF EXISTS action.summarize_circ_chain(INTEGER);
1190
1191 CREATE OR REPLACE FUNCTION action.circ_chain ( ctx_circ_id BIGINT ) RETURNS SETOF action.circulation AS $$
1192 DECLARE
1193     tmp_circ action.circulation%ROWTYPE;
1194     circ_0 action.circulation%ROWTYPE;
1195 BEGIN
1196
1197     SELECT INTO tmp_circ * FROM action.circulation WHERE id = ctx_circ_id;
1198
1199     IF tmp_circ IS NULL THEN
1200         RETURN NEXT tmp_circ;
1201     END IF;
1202     circ_0 := tmp_circ;
1203
1204     -- find the front of the chain
1205     WHILE TRUE LOOP
1206         SELECT INTO tmp_circ * FROM action.circulation WHERE id = tmp_circ.parent_circ;
1207         IF tmp_circ IS NULL THEN
1208             EXIT;
1209         END IF;
1210         circ_0 := tmp_circ;
1211     END LOOP;
1212
1213     -- now send the circs to the caller, oldest to newest
1214     tmp_circ := circ_0;
1215     WHILE TRUE LOOP
1216         IF tmp_circ IS NULL THEN
1217             EXIT;
1218         END IF;
1219         RETURN NEXT tmp_circ;
1220         SELECT INTO tmp_circ * FROM action.circulation WHERE parent_circ = tmp_circ.id;
1221     END LOOP;
1222
1223 END;
1224 $$ LANGUAGE 'plpgsql';
1225
1226 CREATE OR REPLACE FUNCTION action.summarize_circ_chain ( ctx_circ_id BIGINT ) RETURNS action.circ_chain_summary AS $$
1227
1228 DECLARE
1229
1230     -- first circ in the chain
1231     circ_0 action.circulation%ROWTYPE;
1232
1233     -- last circ in the chain
1234     circ_n action.circulation%ROWTYPE;
1235
1236     -- circ chain under construction
1237     chain action.circ_chain_summary;
1238     tmp_circ action.circulation%ROWTYPE;
1239
1240 BEGIN
1241     
1242     chain.num_circs := 0;
1243     FOR tmp_circ IN SELECT * FROM action.circ_chain(ctx_circ_id) LOOP
1244
1245         IF chain.num_circs = 0 THEN
1246             circ_0 := tmp_circ;
1247         END IF;
1248
1249         chain.num_circs := chain.num_circs + 1;
1250         circ_n := tmp_circ;
1251     END LOOP;
1252
1253     chain.start_time := circ_0.xact_start;
1254     chain.last_stop_fines := circ_n.stop_fines;
1255     chain.last_stop_fines_time := circ_n.stop_fines_time;
1256     chain.last_checkin_time := circ_n.checkin_time;
1257     chain.last_checkin_scan_time := circ_n.checkin_scan_time;
1258     SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
1259     SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
1260
1261     IF chain.num_circs > 1 THEN
1262         chain.last_renewal_time := circ_n.xact_start;
1263         SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
1264     END IF;
1265
1266     RETURN chain;
1267
1268 END;
1269 $$ LANGUAGE 'plpgsql';
1270
1271 CREATE OR REPLACE FUNCTION action.purge_circulations () RETURNS INT AS $func$
1272 DECLARE
1273     usr_keep_age    actor.usr_setting%ROWTYPE;
1274     usr_keep_start  actor.usr_setting%ROWTYPE;
1275     org_keep_age    INTERVAL;
1276     org_use_last    BOOL = false;
1277     org_age_is_min  BOOL = false;
1278     org_keep_count  INT;
1279
1280     keep_age        INTERVAL;
1281
1282     target_acp      RECORD;
1283     circ_chain_head action.circulation%ROWTYPE;
1284     circ_chain_tail action.circulation%ROWTYPE;
1285
1286     count_purged    INT;
1287     num_incomplete  INT;
1288
1289     last_finished   TIMESTAMP WITH TIME ZONE;
1290 BEGIN
1291
1292     count_purged := 0;
1293
1294     SELECT value::INTERVAL INTO org_keep_age FROM config.global_flag WHERE name = 'history.circ.retention_age' AND enabled;
1295
1296     SELECT value::INT INTO org_keep_count FROM config.global_flag WHERE name = 'history.circ.retention_count' AND enabled;
1297     IF org_keep_count IS NULL THEN
1298         RETURN count_purged; -- Gimme a count to keep, or I keep them all, forever
1299     END IF;
1300
1301     SELECT enabled INTO org_use_last FROM config.global_flag WHERE name = 'history.circ.retention_uses_last_finished';
1302     SELECT enabled INTO org_age_is_min FROM config.global_flag WHERE name = 'history.circ.retention_age_is_min';
1303
1304     -- First, find copies with more than keep_count non-renewal circs
1305     FOR target_acp IN
1306         SELECT  target_copy,
1307                 COUNT(*) AS total_real_circs
1308           FROM  action.circulation
1309           WHERE parent_circ IS NULL
1310                 AND xact_finish IS NOT NULL
1311           GROUP BY target_copy
1312           HAVING COUNT(*) > org_keep_count
1313     LOOP
1314         -- And, for those, select circs that are finished and older than keep_age
1315         FOR circ_chain_head IN
1316             -- For reference, the subquery uses a window function to order the circs newest to oldest and number them
1317             -- The outer query then uses that information to skip the most recent set the library wants to keep
1318             -- End result is we don't care what order they come out in, as they are all potentials for deletion.
1319             SELECT ac.* FROM action.circulation ac JOIN (
1320               SELECT  rank() OVER (ORDER BY xact_start DESC), ac.id
1321                 FROM  action.circulation ac
1322                 WHERE ac.target_copy = target_acp.target_copy
1323                   AND ac.parent_circ IS NULL
1324                 ORDER BY ac.xact_start ) ranked USING (id)
1325                 WHERE ranked.rank > org_keep_count
1326         LOOP
1327
1328             SELECT * INTO circ_chain_tail FROM action.circ_chain(circ_chain_head.id) ORDER BY xact_start DESC LIMIT 1;
1329             SELECT COUNT(CASE WHEN xact_finish IS NULL THEN 1 ELSE NULL END), MAX(xact_finish) INTO num_incomplete, last_finished FROM action.circ_chain(circ_chain_head.id);
1330             CONTINUE WHEN circ_chain_tail.xact_finish IS NULL OR num_incomplete > 0;
1331
1332             IF NOT org_use_last THEN
1333                 last_finished := circ_chain_tail.xact_finish;
1334             END IF;
1335
1336             -- Now get the user settings, if any, to block purging if the user wants to keep more circs
1337             usr_keep_age.value := NULL;
1338             SELECT * INTO usr_keep_age FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_age';
1339
1340             usr_keep_start.value := NULL;
1341             SELECT * INTO usr_keep_start FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_start';
1342
1343             IF usr_keep_age.value IS NOT NULL AND usr_keep_start.value IS NOT NULL THEN
1344                 IF oils_json_to_text(usr_keep_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ) THEN
1345                     keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
1346                 ELSE
1347                     keep_age := oils_json_to_text(usr_keep_age.value)::INTERVAL;
1348                 END IF;
1349             ELSIF usr_keep_start.value IS NOT NULL THEN
1350                 keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
1351             ELSE
1352                 keep_age := COALESCE( org_keep_age, '2000 years'::INTERVAL );
1353             END IF;
1354
1355             IF org_age_is_min THEN
1356                 keep_age := GREATEST( keep_age, org_keep_age );
1357             END IF;
1358
1359             CONTINUE WHEN AGE(NOW(), last_finished) < keep_age;
1360
1361             -- We've passed the purging tests, purge the circ chain starting at the end
1362             -- A trigger should auto-purge the rest of the chain.
1363             DELETE FROM action.circulation WHERE id = circ_chain_tail.id;
1364
1365             count_purged := count_purged + 1;
1366
1367         END LOOP;
1368     END LOOP;
1369
1370     return count_purged;
1371 END;
1372 $func$ LANGUAGE PLPGSQL;
1373
1374
1375 SELECT evergreen.upgrade_deps_block_check('0799', :eg_version);
1376
1377 -- allow state to be null
1378 ALTER TABLE actor.usr_address ALTER COLUMN state DROP NOT NULL;
1379
1380 -- create new YAOUS
1381 INSERT into config.org_unit_setting_type
1382     (name, grp, label, description, datatype)
1383     VALUES (
1384         'ui.patron.edit.au.state.require',
1385         'gui',
1386         oils_i18n_gettext(
1387             'ui.patron.edit.au.state.require',
1388             'Require State field on patron registration',
1389             'coust',
1390             'label'
1391         ),
1392         oils_i18n_gettext(
1393             'ui.patron.edit.au.state.require',
1394             'The State field will be required on the patron registration screen.',
1395             'coust',
1396             'description'
1397         ),
1398         'bool'
1399     );
1400
1401 INSERT into config.org_unit_setting_type
1402     (name, grp, label, description, datatype)
1403     VALUES (
1404         'ui.patron.edit.au.state.show',
1405         'gui',
1406         oils_i18n_gettext(
1407             'ui.patron.edit.au.state.show',
1408             'Show State field on patron registration',
1409             'coust',
1410             'label'
1411         ),
1412         oils_i18n_gettext(
1413             'ui.patron.edit.au.state.show',
1414             'The State field will be shown on the patron registration screen. Showing a field makes it appear with required fields even when not required. If the field is required this setting is ignored.',
1415             'coust',
1416             'description'
1417         ),
1418         'bool'
1419     );  
1420
1421 INSERT into config.org_unit_setting_type
1422     (name, grp, label, description, datatype)
1423     VALUES (
1424         'ui.patron.edit.au.state.suggest',
1425         'gui',
1426         oils_i18n_gettext(
1427             'ui.patron.edit.au.state.suggest',
1428             'Suggest State field on patron registration',
1429             'coust',
1430             'label'
1431         ),
1432         oils_i18n_gettext(
1433             'ui.patron.edit.au.state.suggest',
1434             'The State field will be suggested on the patron registration screen. Suggesting a field makes it appear when suggested fields are shown. If the field is shown or required this setting is ignored.',
1435             'coust',
1436             'description'
1437         ),
1438         'bool'
1439     );          
1440
1441
1442 SELECT evergreen.upgrade_deps_block_check('0801', :eg_version);
1443
1444 INSERT into config.org_unit_setting_type
1445 ( name, grp, label, description, datatype, fm_class ) VALUES
1446 ( 'ui.patron.edit.ac.barcode.regex', 'gui',
1447     oils_i18n_gettext('ui.patron.edit.ac.barcode.regex',
1448         'Regex for barcodes on patron registration',
1449         'coust', 'label'),
1450     oils_i18n_gettext('ui.patron.edit.ac.barcode.regex',
1451         'The Regular Expression for validation on barcodes in patron registration.',
1452         'coust', 'description'),
1453     'string', null);
1454
1455
1456 SELECT evergreen.upgrade_deps_block_check('0802', :eg_version);
1457
1458 CREATE OR REPLACE FUNCTION authority.normalize_heading( marcxml TEXT, no_thesaurus BOOL ) RETURNS TEXT AS $func$
1459 DECLARE
1460     acsaf           authority.control_set_authority_field%ROWTYPE;
1461     tag_used        TEXT;
1462     nfi_used        TEXT;
1463     sf              TEXT;
1464     sf_node         TEXT;
1465     tag_node        TEXT;
1466     thes_code       TEXT;
1467     cset            INT;
1468     heading_text    TEXT;
1469     tmp_text        TEXT;
1470     first_sf        BOOL;
1471     auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
1472 BEGIN
1473     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
1474
1475     IF cset IS NULL THEN
1476         SELECT  control_set INTO cset
1477           FROM  authority.control_set_authority_field
1478           WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
1479           LIMIT 1;
1480     END IF;
1481
1482     thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
1483     IF thes_code IS NULL THEN
1484         thes_code := '|';
1485     ELSIF thes_code = 'z' THEN
1486         thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), '' );
1487     END IF;
1488
1489     heading_text := '';
1490     FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
1491         tag_used := acsaf.tag;
1492         nfi_used := acsaf.nfi;
1493         first_sf := TRUE;
1494
1495         FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml)) LOOP
1496             FOR sf_node IN SELECT unnest(oils_xpath('//*[contains("'||acsaf.sf_list||'",@code)]',tag_node)) LOOP
1497
1498                 tmp_text := oils_xpath_string('.', sf_node);
1499                 sf := oils_xpath_string('./@code', sf_node);
1500
1501                 IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
1502
1503                     tmp_text := SUBSTRING(
1504                         tmp_text FROM
1505                         COALESCE(
1506                             NULLIF(
1507                                 REGEXP_REPLACE(
1508                                     oils_xpath_string('./@ind'||nfi_used, tag_node),
1509                                     $$\D+$$,
1510                                     '',
1511                                     'g'
1512                                 ),
1513                                 ''
1514                             )::INT,
1515                             0
1516                         ) + 1
1517                     );
1518
1519                 END IF;
1520
1521                 first_sf := FALSE;
1522
1523                 IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
1524                     heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
1525                 END IF;
1526             END LOOP;
1527
1528             EXIT WHEN heading_text <> '';
1529         END LOOP;
1530
1531         EXIT WHEN heading_text <> '';
1532     END LOOP;
1533
1534     IF heading_text <> '' THEN
1535         IF no_thesaurus IS TRUE THEN
1536             heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
1537         ELSE
1538             heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
1539         END IF;
1540     ELSE
1541         heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
1542     END IF;
1543
1544     RETURN heading_text;
1545 END;
1546 $func$ LANGUAGE PLPGSQL IMMUTABLE;
1547
1548 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
1549 DECLARE
1550     res             authority.simple_heading%ROWTYPE;
1551     acsaf           authority.control_set_authority_field%ROWTYPE;
1552     tag_used        TEXT;
1553     nfi_used        TEXT;
1554     sf              TEXT;
1555     cset            INT;
1556     heading_text    TEXT;
1557     sort_text       TEXT;
1558     tmp_text        TEXT;
1559     tmp_xml         TEXT;
1560     first_sf        BOOL;
1561     auth_id         INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml)::INT;
1562 BEGIN
1563
1564     res.record := auth_id;
1565
1566     SELECT  control_set INTO cset
1567       FROM  authority.control_set_authority_field
1568       WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]) )
1569       LIMIT 1;
1570
1571     FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
1572
1573         res.atag := acsaf.id;
1574         tag_used := acsaf.tag;
1575         nfi_used := acsaf.nfi;
1576
1577         FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)) LOOP
1578
1579             heading_text := public.naco_normalize(
1580                 COALESCE(
1581                     oils_xpath_string('//*[contains("'||acsaf.sf_list||'",@code)]',tmp_xml::TEXT, ' '),
1582                     ''
1583                 )
1584             );
1585
1586             IF nfi_used IS NOT NULL THEN
1587
1588                 sort_text := SUBSTRING(
1589                     heading_text FROM
1590                     COALESCE(
1591                         NULLIF(
1592                             REGEXP_REPLACE(
1593                                 oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
1594                                 $$\D+$$,
1595                                 '',
1596                                 'g'
1597                             ),
1598                             ''
1599                         )::INT,
1600                         0
1601                     ) + 1
1602                 );
1603
1604             ELSE
1605                 sort_text := heading_text;
1606             END IF;
1607
1608             IF heading_text IS NOT NULL AND heading_text <> '' THEN
1609                 res.value := heading_text;
1610                 res.sort_value := sort_text;
1611                 RETURN NEXT res;
1612             END IF;
1613
1614         END LOOP;
1615
1616     END LOOP;
1617
1618     RETURN;
1619 END;
1620 $func$ LANGUAGE PLPGSQL IMMUTABLE;
1621
1622
1623
1624 -- check whether patch can be applied
1625 SELECT evergreen.upgrade_deps_block_check('0805', :eg_version);
1626
1627 INSERT INTO config.global_flag (name, label, enabled)
1628     VALUES (
1629         'circ.desk_renewal.use_original_circ_lib',
1630         oils_i18n_gettext(
1631             'circ.desk_renewal.use_original_circ_lib',
1632             'Circ: Use original circulation library on desk renewal instead of user home library',
1633             'cgf',
1634             'label'
1635         ),
1636         FALSE
1637     );
1638
1639
1640 -- check whether patch can be applied
1641 SELECT evergreen.upgrade_deps_block_check('0806', :eg_version);
1642
1643 INSERT INTO action.hold_request_cancel_cause (id,label) 
1644     VALUES (7,'Patron via SIP');
1645
1646
1647 -- check whether patch can be applied
1648 SELECT evergreen.upgrade_deps_block_check('0807', :eg_version);
1649
1650 ALTER TABLE config.usr_setting_type
1651     ADD COLUMN reg_default TEXT;
1652
1653
1654 SELECT evergreen.upgrade_deps_block_check('0809', :eg_version);
1655
1656 ALTER TABLE actor.org_address ALTER COLUMN state DROP NOT NULL;
1657
1658
1659 -- Evergreen DB patch 0812.data.add_library_info_url_OUS.sql
1660 --
1661 -- Adds YAOUS for enabling information links from the TPAC to a library URL
1662 --
1663
1664 -- check whether patch can be applied
1665 SELECT evergreen.upgrade_deps_block_check('0812', :eg_version);
1666
1667 -- FIXME: add/check SQL statements to perform the upgrade
1668 INSERT into config.org_unit_setting_type
1669 ( name, grp, label, description, datatype, fm_class ) VALUES
1670 ( 'lib.info_url', 'lib',
1671     oils_i18n_gettext('lib.info_url',
1672         'Library information URL (such as "http://example.com/about.html")',
1673         'coust', 'label'),
1674     oils_i18n_gettext('lib.info_url',
1675         'URL for information on this library, such as contact information, hours of operation, and directions. If set, the library name in the copy details section links to that URL. Use a complete URL, such as "http://example.com/hours.html".',
1676         'coust', 'description'),
1677     'string', null)
1678 ;
1679
1680
1681 SELECT evergreen.upgrade_deps_block_check('0813', :eg_version);
1682
1683 -- Don't require state in the auditor tracking for user addresses
1684
1685 ALTER TABLE auditor.actor_usr_address_history ALTER COLUMN state DROP NOT NULL;
1686
1687 -- Change constraint on actor.org_unit_setting_log to be deferrable initially
1688
1689 ALTER TABLE config.org_unit_setting_type_log
1690   DROP CONSTRAINT org_unit_setting_type_log_field_name_fkey,
1691   ADD CONSTRAINT org_unit_setting_type_log_field_name_fkey FOREIGN KEY (field_name)
1692     REFERENCES config.org_unit_setting_type (name) MATCH SIMPLE
1693     ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;
1694
1695 -- Fix names in the org unit setting configuration
1696
1697 UPDATE config.org_unit_setting_type SET name = overlay(name placing 'aua' from 16 for 2) where name like 'ui.patron.edit.au.state.%';
1698
1699 -- Fix names if they have already been set in the editor
1700
1701 UPDATE actor.org_unit_setting SET name = overlay(name placing 'aua' from 16 for 2) where name like 'ui.patron.edit.au.state.%';
1702
1703 -- and the logs too
1704
1705 UPDATE config.org_unit_setting_type_log SET field_name = overlay(field_name placing 'aua' from 16 for 2) where field_name like 'ui.patron.edit.au.state.%';
1706
1707
1708 SELECT evergreen.upgrade_deps_block_check('0814', :eg_version);
1709
1710 UPDATE permission.perm_list
1711 SET description = 'Allow a user to delete a provider'
1712 WHERE code = 'DELETE_PROVIDER';
1713
1714
1715 -- check whether patch can be applied
1716 SELECT evergreen.upgrade_deps_block_check('0815', :eg_version);
1717
1718 ALTER TABLE authority.control_set_authority_field
1719     ADD COLUMN linking_subfield CHAR(1);
1720
1721 UPDATE authority.control_set_authority_field
1722     SET linking_subfield = '0' WHERE main_entry IS NOT NULL;
1723
1724 CREATE TABLE authority.authority_linking (
1725     id      BIGSERIAL PRIMARY KEY,
1726     source  BIGINT REFERENCES authority.record_entry (id) NOT NULL,
1727     target  BIGINT REFERENCES authority.record_entry (id) NOT NULL,
1728     field   INT REFERENCES authority.control_set_authority_field (id) NOT NULL
1729 );
1730
1731 -- Given an authority record's ID, control set ID (if known), and marc::XML,
1732 -- return all links to other authority records in the form of rows that
1733 -- can be inserted into authority.authority_linking.
1734 CREATE OR REPLACE FUNCTION authority.calculate_authority_linking(
1735     rec_id BIGINT, rec_control_set INT, rec_marc_xml XML
1736 ) RETURNS SETOF authority.authority_linking AS $func$
1737 DECLARE
1738     acsaf       authority.control_set_authority_field%ROWTYPE;
1739     link        TEXT;
1740     aal         authority.authority_linking%ROWTYPE;
1741 BEGIN
1742     IF rec_control_set IS NULL THEN
1743         -- No control_set on record?  Guess at one
1744         SELECT control_set INTO rec_control_set
1745             FROM authority.control_set_authority_field
1746             WHERE tag IN (
1747                 SELECT UNNEST(
1748                     XPATH('//*[starts-with(@tag,"1")]/@tag',rec_marc_xml::XML)::TEXT[]
1749                 )
1750             ) LIMIT 1;
1751
1752         IF NOT FOUND THEN
1753             RAISE WARNING 'Could not even guess at control set for authority record %', rec_id;
1754             RETURN;
1755         END IF;
1756     END IF;
1757
1758     aal.source := rec_id;
1759
1760     FOR acsaf IN
1761         SELECT * FROM authority.control_set_authority_field
1762         WHERE control_set = rec_control_set
1763             AND linking_subfield IS NOT NULL
1764             AND main_entry IS NOT NULL
1765     LOOP
1766         link := SUBSTRING(
1767             (XPATH('//*[@tag="' || acsaf.tag || '"]/*[@code="' ||
1768                 acsaf.linking_subfield || '"]/text()', rec_marc_xml))[1]::TEXT,
1769             '\d+$'
1770         );
1771
1772         -- Ignore links that are null, malformed, circular, or point to
1773         -- non-existent authority records.
1774         IF link IS NOT NULL AND link::BIGINT <> rec_id THEN
1775             PERFORM * FROM authority.record_entry WHERE id = link::BIGINT;
1776             IF FOUND THEN
1777                 aal.target := link::BIGINT;
1778                 aal.field := acsaf.id;
1779                 RETURN NEXT aal;
1780             END IF;
1781         END IF;
1782     END LOOP;
1783 END;
1784 $func$ LANGUAGE PLPGSQL;
1785
1786
1787 -- AFTER UPDATE OR INSERT trigger for authority.record_entry
1788 CREATE OR REPLACE FUNCTION authority.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
1789 BEGIN
1790
1791     IF NEW.deleted IS TRUE THEN -- If this authority is deleted
1792         DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
1793         DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
1794         DELETE FROM authority.simple_heading WHERE record = NEW.id;
1795           -- Should remove matching $0 from controlled fields at the same time?
1796
1797         -- XXX What do we about the actual linking subfields present in
1798         -- authority records that target this one when this happens?
1799         DELETE FROM authority.authority_linking
1800             WHERE source = NEW.id OR target = NEW.id;
1801
1802         RETURN NEW; -- and we're done
1803     END IF;
1804
1805     IF TG_OP = 'UPDATE' THEN -- re-ingest?
1806         PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
1807
1808         IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
1809             RETURN NEW;
1810         END IF;
1811
1812         -- Propagate these updates to any linked bib records
1813         PERFORM authority.propagate_changes(NEW.id) FROM authority.record_entry WHERE id = NEW.id;
1814
1815         DELETE FROM authority.simple_heading WHERE record = NEW.id;
1816         DELETE FROM authority.authority_linking WHERE source = NEW.id;
1817     END IF;
1818
1819     INSERT INTO authority.authority_linking (source, target, field)
1820         SELECT source, target, field FROM authority.calculate_authority_linking(
1821             NEW.id, NEW.control_set, NEW.marc::XML
1822         );
1823
1824     INSERT INTO authority.simple_heading (record,atag,value,sort_value)
1825         SELECT record, atag, value, sort_value FROM authority.simple_heading_set(NEW.marc);
1826
1827     -- Flatten and insert the afr data
1828     PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
1829     IF NOT FOUND THEN
1830         PERFORM authority.reingest_authority_full_rec(NEW.id);
1831         PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
1832         IF NOT FOUND THEN
1833             PERFORM authority.reingest_authority_rec_descriptor(NEW.id);
1834         END IF;
1835     END IF;
1836
1837     RETURN NEW;
1838 END;
1839 $func$ LANGUAGE PLPGSQL;
1840
1841
1842 -- check whether patch can be applied
1843 SELECT evergreen.upgrade_deps_block_check('0816', :eg_version);
1844
1845 -- To avoid problems with altering a table column after doing an
1846 -- update.
1847 ALTER TABLE authority.control_set_authority_field
1848     DISABLE TRIGGER ALL;
1849
1850 ALTER TABLE authority.control_set_authority_field
1851     ADD COLUMN display_sf_list TEXT;
1852
1853 UPDATE authority.control_set_authority_field
1854     SET display_sf_list = REGEXP_REPLACE(sf_list, '[w254]', '', 'g');
1855
1856 ALTER TABLE authority.control_set_authority_field
1857     ALTER COLUMN display_sf_list SET NOT NULL;
1858
1859 ALTER TABLE authority.control_set_authority_field
1860     ENABLE TRIGGER ALL;
1861
1862 ALTER TABLE metabib.browse_entry_def_map
1863     ADD COLUMN authority BIGINT REFERENCES authority.record_entry (id)
1864         ON DELETE SET NULL;
1865
1866 ALTER TABLE config.metabib_field ADD COLUMN authority_xpath TEXT;
1867 ALTER TABLE config.metabib_field ADD COLUMN browse_sort_xpath TEXT;
1868
1869 UPDATE config.metabib_field
1870     SET authority_xpath = '//@xlink:href'
1871     WHERE
1872         format = 'mods32' AND
1873         field_class IN ('subject','series','title','author') AND
1874         browse_field IS TRUE;
1875
1876 ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE authority BIGINT;
1877 ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE sort_value TEXT;
1878
1879 CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( bib_id BIGINT, skip_facet BOOL DEFAULT FALSE, skip_browse BOOL DEFAULT FALSE, skip_search BOOL DEFAULT FALSE ) RETURNS VOID AS $func$
1880 DECLARE
1881     fclass          RECORD;
1882     ind_data        metabib.field_entry_template%ROWTYPE;
1883     mbe_row         metabib.browse_entry%ROWTYPE;
1884     mbe_id          BIGINT;
1885     b_skip_facet    BOOL;
1886     b_skip_browse   BOOL;
1887     b_skip_search   BOOL;
1888     value_prepped   TEXT;
1889 BEGIN
1890
1891     SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
1892     SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
1893     SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
1894
1895     PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
1896     IF NOT FOUND THEN
1897         IF NOT b_skip_search THEN
1898             FOR fclass IN SELECT * FROM config.metabib_class LOOP
1899                 -- RAISE NOTICE 'Emptying out %', fclass.name;
1900                 EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
1901             END LOOP;
1902         END IF;
1903         IF NOT b_skip_facet THEN
1904             DELETE FROM metabib.facet_entry WHERE source = bib_id;
1905         END IF;
1906         IF NOT b_skip_browse THEN
1907             DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
1908         END IF;
1909     END IF;
1910
1911     FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id ) LOOP
1912         IF ind_data.field < 0 THEN
1913             ind_data.field = -1 * ind_data.field;
1914         END IF;
1915
1916         IF ind_data.facet_field AND NOT b_skip_facet THEN
1917             INSERT INTO metabib.facet_entry (field, source, value)
1918                 VALUES (ind_data.field, ind_data.source, ind_data.value);
1919         END IF;
1920
1921         IF ind_data.browse_field AND NOT b_skip_browse THEN
1922             -- A caveat about this SELECT: this should take care of replacing
1923             -- old mbe rows when data changes, but not if normalization (by
1924             -- which I mean specifically the output of
1925             -- evergreen.oils_tsearch2()) changes.  It may or may not be
1926             -- expensive to add a comparison of index_vector to index_vector
1927             -- to the WHERE clause below.
1928
1929             value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
1930             SELECT INTO mbe_row * FROM metabib.browse_entry
1931                 WHERE value = value_prepped AND sort_value = ind_data.sort_value;
1932
1933             IF FOUND THEN
1934                 mbe_id := mbe_row.id;
1935             ELSE
1936                 INSERT INTO metabib.browse_entry
1937                     ( value, sort_value ) VALUES
1938                     ( value_prepped, ind_data.sort_value );
1939
1940                 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
1941             END IF;
1942
1943             INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
1944                 VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
1945         END IF;
1946
1947         IF ind_data.search_field AND NOT b_skip_search THEN
1948             EXECUTE $$
1949                 INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
1950                     VALUES ($$ ||
1951                         quote_literal(ind_data.field) || $$, $$ ||
1952                         quote_literal(ind_data.source) || $$, $$ ||
1953                         quote_literal(ind_data.value) ||
1954                     $$);$$;
1955         END IF;
1956
1957     END LOOP;
1958
1959     IF NOT b_skip_search THEN
1960         PERFORM metabib.update_combined_index_vectors(bib_id);
1961     END IF;
1962
1963     RETURN;
1964 END;
1965 $func$ LANGUAGE PLPGSQL;
1966
1967
1968 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
1969 DECLARE
1970     bib     biblio.record_entry%ROWTYPE;
1971     idx     config.metabib_field%ROWTYPE;
1972     xfrm        config.xml_transform%ROWTYPE;
1973     prev_xfrm   TEXT;
1974     transformed_xml TEXT;
1975     xml_node    TEXT;
1976     xml_node_list   TEXT[];
1977     facet_text  TEXT;
1978     browse_text TEXT;
1979     sort_value  TEXT;
1980     raw_text    TEXT;
1981     curr_text   TEXT;
1982     joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
1983     authority_text TEXT;
1984     authority_link BIGINT;
1985     output_row  metabib.field_entry_template%ROWTYPE;
1986 BEGIN
1987
1988     -- Get the record
1989     SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
1990
1991     -- Loop over the indexing entries
1992     FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
1993
1994         SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
1995
1996         -- See if we can skip the XSLT ... it's expensive
1997         IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
1998             -- Can't skip the transform
1999             IF xfrm.xslt <> '---' THEN
2000                 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
2001             ELSE
2002                 transformed_xml := bib.marc;
2003             END IF;
2004
2005             prev_xfrm := xfrm.name;
2006         END IF;
2007
2008         xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2009
2010         raw_text := NULL;
2011         FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
2012             CONTINUE WHEN xml_node !~ E'^\\s*<';
2013
2014             curr_text := ARRAY_TO_STRING(
2015                 oils_xpath( '//text()',
2016                     REGEXP_REPLACE( -- This escapes all &s not followed by "amp;".  Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
2017                         REGEXP_REPLACE( -- This escapes embeded <s
2018                             xml_node,
2019                             $re$(>[^<]+)(<)([^>]+<)$re$,
2020                             E'\\1&lt;\\3',
2021                             'g'
2022                         ),
2023                         '&(?!amp;)',
2024                         '&amp;',
2025                         'g'
2026                     )
2027                 ),
2028                 ' '
2029             );
2030
2031             CONTINUE WHEN curr_text IS NULL OR curr_text = '';
2032
2033             IF raw_text IS NOT NULL THEN
2034                 raw_text := raw_text || joiner;
2035             END IF;
2036
2037             raw_text := COALESCE(raw_text,'') || curr_text;
2038
2039             -- autosuggest/metabib.browse_entry
2040             IF idx.browse_field THEN
2041
2042                 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
2043                     browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2044                 ELSE
2045                     browse_text := curr_text;
2046                 END IF;
2047
2048                 IF idx.browse_sort_xpath IS NOT NULL AND
2049                     idx.browse_sort_xpath <> '' THEN
2050
2051                     sort_value := oils_xpath_string(
2052                         idx.browse_sort_xpath, xml_node, joiner,
2053                         ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
2054                     );
2055                 ELSE
2056                     sort_value := browse_text;
2057                 END IF;
2058
2059                 output_row.field_class = idx.field_class;
2060                 output_row.field = idx.id;
2061                 output_row.source = rid;
2062                 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
2063                 output_row.sort_value :=
2064                     public.search_normalize(sort_value);
2065
2066                 output_row.authority := NULL;
2067
2068                 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
2069                     authority_text := oils_xpath_string(
2070                         idx.authority_xpath, xml_node, joiner,
2071                         ARRAY[
2072                             ARRAY[xfrm.prefix, xfrm.namespace_uri],
2073                             ARRAY['xlink','http://www.w3.org/1999/xlink']
2074                         ]
2075                     );
2076
2077                     IF authority_text ~ '^\d+$' THEN
2078                         authority_link := authority_text::BIGINT;
2079                         PERFORM * FROM authority.record_entry WHERE id = authority_link;
2080                         IF FOUND THEN
2081                             output_row.authority := authority_link;
2082                         END IF;
2083                     END IF;
2084
2085                 END IF;
2086
2087                 output_row.browse_field = TRUE;
2088                 RETURN NEXT output_row;
2089                 output_row.browse_field = FALSE;
2090                 output_row.sort_value := NULL;
2091             END IF;
2092
2093             -- insert raw node text for faceting
2094             IF idx.facet_field THEN
2095
2096                 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
2097                     facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2098                 ELSE
2099                     facet_text := curr_text;
2100                 END IF;
2101
2102                 output_row.field_class = idx.field_class;
2103                 output_row.field = -1 * idx.id;
2104                 output_row.source = rid;
2105                 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
2106
2107                 output_row.facet_field = TRUE;
2108                 RETURN NEXT output_row;
2109                 output_row.facet_field = FALSE;
2110             END IF;
2111
2112         END LOOP;
2113
2114         CONTINUE WHEN raw_text IS NULL OR raw_text = '';
2115
2116         -- insert combined node text for searching
2117         IF idx.search_field THEN
2118             output_row.field_class = idx.field_class;
2119             output_row.field = idx.id;
2120             output_row.source = rid;
2121             output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
2122
2123             output_row.search_field = TRUE;
2124             RETURN NEXT output_row;
2125             output_row.search_field = FALSE;
2126         END IF;
2127
2128     END LOOP;
2129
2130 END;
2131
2132 $func$ LANGUAGE PLPGSQL;
2133
2134
2135 -- 953.data.MODS32-xsl.sql
2136 UPDATE config.xml_transform SET xslt=$$<?xml version="1.0" encoding="UTF-8"?>
2137 <xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
2138         <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
2139 <!--
2140 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements 
2141   with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
2142
2143 Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28 tmee
2144         
2145 Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11 tmee
2146                 
2147 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
2148       2006/04/08  jrad
2149
2150 Revision 1.10 MODS 3.1 revisions to language and classification elements  
2151                                 (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
2152                                 2006/02/06  ggar
2153
2154 Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
2155
2156 Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
2157
2158 Revision 1.7 2004/03/25 08:29 jrad
2159
2160 Revision 1.6 various validation fixes 2004/02/20 ntra
2161
2162 Revision 1.5  2003/10/02 16:18:58  ntra
2163 MODS2 to MODS3 updates, language unstacking and 
2164 de-duping, chopPunctuation expanded
2165
2166 Revision 1.3  2003/04/03 00:07:19  ntra
2167 Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
2168
2169 Revision 1.2  2003/03/24 19:37:42  ckeith
2170 Added Log Comment
2171
2172 -->
2173         <xsl:template match="/">
2174                 <xsl:choose>
2175                         <xsl:when test="//marc:collection">
2176                                 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
2177                                         <xsl:for-each select="//marc:collection/marc:record">
2178                                                 <mods version="3.2">
2179                                                         <xsl:call-template name="marcRecord"/>
2180                                                 </mods>
2181                                         </xsl:for-each>
2182                                 </modsCollection>
2183                         </xsl:when>
2184                         <xsl:otherwise>
2185                                 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
2186                                         <xsl:for-each select="//marc:record">
2187                                                 <xsl:call-template name="marcRecord"/>
2188                                         </xsl:for-each>
2189                                 </mods>
2190                         </xsl:otherwise>
2191                 </xsl:choose>
2192         </xsl:template>
2193         <xsl:template name="marcRecord">
2194                 <xsl:variable name="leader" select="marc:leader"/>
2195                 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
2196                 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
2197                 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
2198                 <xsl:variable name="typeOf008">
2199                         <xsl:choose>
2200                                 <xsl:when test="$leader6='a'">
2201                                         <xsl:choose>
2202                                                 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
2203                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
2204                                         </xsl:choose>
2205                                 </xsl:when>
2206                                 <xsl:when test="$leader6='t'">BK</xsl:when>
2207                                 <xsl:when test="$leader6='p'">MM</xsl:when>
2208                                 <xsl:when test="$leader6='m'">CF</xsl:when>
2209                                 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
2210                                 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
2211                                 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
2212                         </xsl:choose>
2213                 </xsl:variable>
2214                 <xsl:for-each select="marc:datafield[@tag='245']">
2215                         <titleInfo>
2216                                 <xsl:variable name="title">
2217                                         <xsl:choose>
2218                                                 <xsl:when test="marc:subfield[@code='b']">
2219                                                         <xsl:call-template name="specialSubfieldSelect">
2220                                                                 <xsl:with-param name="axis">b</xsl:with-param>
2221                                                                 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
2222                                                         </xsl:call-template>
2223                                                 </xsl:when>
2224                                                 <xsl:otherwise>
2225                                                         <xsl:call-template name="subfieldSelect">
2226                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
2227                                                         </xsl:call-template>
2228                                                 </xsl:otherwise>
2229                                         </xsl:choose>
2230                                 </xsl:variable>
2231                                 <xsl:variable name="titleChop">
2232                                         <xsl:call-template name="chopPunctuation">
2233                                                 <xsl:with-param name="chopString">
2234                                                         <xsl:value-of select="$title"/>
2235                                                 </xsl:with-param>
2236                                         </xsl:call-template>
2237                                 </xsl:variable>
2238                                 <xsl:choose>
2239                                         <xsl:when test="@ind2>0">
2240                                                 <nonSort>
2241                                                         <xsl:value-of select="substring($titleChop,1,@ind2)"/>
2242                                                 </nonSort>
2243                                                 <title>
2244                                                         <xsl:value-of select="substring($titleChop,@ind2+1)"/>
2245                                                 </title>
2246                                         </xsl:when>
2247                                         <xsl:otherwise>
2248                                                 <title>
2249                                                         <xsl:value-of select="$titleChop"/>
2250                                                 </title>
2251                                         </xsl:otherwise>
2252                                 </xsl:choose>
2253                                 <xsl:if test="marc:subfield[@code='b']">
2254                                         <subTitle>
2255                                                 <xsl:call-template name="chopPunctuation">
2256                                                         <xsl:with-param name="chopString">
2257                                                                 <xsl:call-template name="specialSubfieldSelect">
2258                                                                         <xsl:with-param name="axis">b</xsl:with-param>
2259                                                                         <xsl:with-param name="anyCodes">b</xsl:with-param>
2260                                                                         <xsl:with-param name="afterCodes">afgk</xsl:with-param>
2261                                                                 </xsl:call-template>
2262                                                         </xsl:with-param>
2263                                                 </xsl:call-template>
2264                                         </subTitle>
2265                                 </xsl:if>
2266                                 <xsl:call-template name="part"></xsl:call-template>
2267                         </titleInfo>
2268                         <!-- A form of title that ignores non-filing characters; useful
2269                                  for not converting "L'Oreal" into "L' Oreal" at index time -->
2270                         <titleNonfiling>
2271                                 <xsl:variable name="title">
2272                                         <xsl:choose>
2273                                                 <xsl:when test="marc:subfield[@code='b']">
2274                                                         <xsl:call-template name="specialSubfieldSelect">
2275                                                                 <xsl:with-param name="axis">b</xsl:with-param>
2276                                                                 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
2277                                                         </xsl:call-template>
2278                                                 </xsl:when>
2279                                                 <xsl:otherwise>
2280                                                         <xsl:call-template name="subfieldSelect">
2281                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
2282                                                         </xsl:call-template>
2283                                                 </xsl:otherwise>
2284                                         </xsl:choose>
2285                                 </xsl:variable>
2286                                 <title>
2287                                         <xsl:value-of select="$title"/>
2288                                 </title>
2289                                 <xsl:if test="marc:subfield[@code='b']">
2290                                         <subTitle>
2291                                                 <xsl:call-template name="chopPunctuation">
2292                                                         <xsl:with-param name="chopString">
2293                                                                 <xsl:call-template name="specialSubfieldSelect">
2294                                                                         <xsl:with-param name="axis">b</xsl:with-param>
2295                                                                         <xsl:with-param name="anyCodes">b</xsl:with-param>
2296                                                                         <xsl:with-param name="afterCodes">afgk</xsl:with-param>
2297                                                                 </xsl:call-template>
2298                                                         </xsl:with-param>
2299                                                 </xsl:call-template>
2300                                         </subTitle>
2301                                 </xsl:if>
2302                                 <xsl:call-template name="part"></xsl:call-template>
2303                         </titleNonfiling>
2304                 </xsl:for-each>
2305                 <xsl:for-each select="marc:datafield[@tag='210']">
2306                         <titleInfo type="abbreviated">
2307                                 <title>
2308                                         <xsl:call-template name="chopPunctuation">
2309                                                 <xsl:with-param name="chopString">
2310                                                         <xsl:call-template name="subfieldSelect">
2311                                                                 <xsl:with-param name="codes">a</xsl:with-param>
2312                                                         </xsl:call-template>
2313                                                 </xsl:with-param>
2314                                         </xsl:call-template>
2315                                 </title>
2316                                 <xsl:call-template name="subtitle"/>
2317                         </titleInfo>
2318                 </xsl:for-each>
2319                 <xsl:for-each select="marc:datafield[@tag='242']">
2320                         <xsl:variable name="titleChop">
2321                                 <xsl:call-template name="chopPunctuation">
2322                                         <xsl:with-param name="chopString">
2323                                                 <xsl:call-template name="subfieldSelect">
2324                                                         <!-- 1/04 removed $h, b -->
2325                                                         <xsl:with-param name="codes">a</xsl:with-param>
2326                                                 </xsl:call-template>
2327                                         </xsl:with-param>
2328                                 </xsl:call-template>
2329                         </xsl:variable>
2330                         <titleInfo type="translated">
2331                                 <!--09/01/04 Added subfield $y-->
2332                                 <xsl:for-each select="marc:subfield[@code='y']">
2333                                         <xsl:attribute name="lang">
2334                                                 <xsl:value-of select="text()"/>
2335                                         </xsl:attribute>
2336                                 </xsl:for-each>
2337                                 <title>
2338                                         <xsl:value-of select="$titleChop" />
2339                                 </title>
2340                                 <!-- 1/04 fix -->
2341                                 <xsl:call-template name="subtitle"/>
2342                                 <xsl:call-template name="part"/>
2343                         </titleInfo>
2344                         <titleInfo type="translated-nfi">
2345                                 <xsl:for-each select="marc:subfield[@code='y']">
2346                                         <xsl:attribute name="lang">
2347                                                 <xsl:value-of select="text()"/>
2348                                         </xsl:attribute>
2349                                 </xsl:for-each>
2350                                 <xsl:choose>
2351                                         <xsl:when test="@ind2>0">
2352                                                 <nonSort>
2353                                                         <xsl:value-of select="substring($titleChop,1,@ind2)"/>
2354                                                 </nonSort>
2355                                                 <title>
2356                                                         <xsl:value-of select="substring($titleChop,@ind2+1)"/>
2357                                                 </title>
2358                                         </xsl:when>
2359                                         <xsl:otherwise>
2360                                                 <title>
2361                                                         <xsl:value-of select="$titleChop" />
2362                                                 </title>
2363                                         </xsl:otherwise>
2364                                 </xsl:choose>
2365                                 <xsl:call-template name="subtitle"/>
2366                                 <xsl:call-template name="part"/>
2367                         </titleInfo>
2368                 </xsl:for-each>
2369                 <xsl:for-each select="marc:datafield[@tag='246']">
2370                         <titleInfo type="alternative">
2371                                 <xsl:for-each select="marc:subfield[@code='i']">
2372                                         <xsl:attribute name="displayLabel">
2373                                                 <xsl:value-of select="text()"/>
2374                                         </xsl:attribute>
2375                                 </xsl:for-each>
2376                                 <title>
2377                                         <xsl:call-template name="chopPunctuation">
2378                                                 <xsl:with-param name="chopString">
2379                                                         <xsl:call-template name="subfieldSelect">
2380                                                                 <!-- 1/04 removed $h, $b -->
2381                                                                 <xsl:with-param name="codes">af</xsl:with-param>
2382                                                         </xsl:call-template>
2383                                                 </xsl:with-param>
2384                                         </xsl:call-template>
2385                                 </title>
2386                                 <xsl:call-template name="subtitle"/>
2387                                 <xsl:call-template name="part"/>
2388                         </titleInfo>
2389                 </xsl:for-each>
2390                 <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
2391                         <xsl:variable name="nfi">
2392                                 <xsl:choose>
2393                                         <xsl:when test="@tag='240'">
2394                                                 <xsl:value-of select="@ind2"/>
2395                                         </xsl:when>
2396                                         <xsl:otherwise>
2397                                                 <xsl:value-of select="@ind1"/>
2398                                         </xsl:otherwise>
2399                                 </xsl:choose>
2400                         </xsl:variable>
2401                         <xsl:variable name="titleChop">
2402                                 <xsl:call-template name="uri" />
2403                                 <xsl:variable name="str">
2404                                         <xsl:for-each select="marc:subfield">
2405                                                 <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
2406                                                         <xsl:value-of select="text()"/>
2407                                                         <xsl:text> </xsl:text>
2408                                                 </xsl:if>
2409                                         </xsl:for-each>
2410                                 </xsl:variable>
2411                                 <xsl:call-template name="chopPunctuation">
2412                                         <xsl:with-param name="chopString">
2413                                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
2414                                         </xsl:with-param>
2415                                 </xsl:call-template>
2416                         </xsl:variable>
2417                         <titleInfo type="uniform">
2418                                 <title>
2419                                         <xsl:value-of select="$titleChop"/>
2420                                 </title>
2421                                 <xsl:call-template name="part"/>
2422                         </titleInfo>
2423                         <titleInfo type="uniform-nfi">
2424                                 <xsl:choose>
2425                                         <xsl:when test="$nfi>0">
2426                                                 <nonSort>
2427                                                         <xsl:value-of select="substring($titleChop,1,$nfi)"/>
2428                                                 </nonSort>
2429                                                 <title>
2430                                                         <xsl:value-of select="substring($titleChop,$nfi+1)"/>
2431                                                 </title>
2432                                         </xsl:when>
2433                                         <xsl:otherwise>
2434                                                 <title>
2435                                                         <xsl:value-of select="$titleChop"/>
2436                                                 </title>
2437                                         </xsl:otherwise>
2438                                 </xsl:choose>
2439                                 <xsl:call-template name="part"/>
2440                         </titleInfo>
2441                 </xsl:for-each>
2442                 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
2443                         <xsl:variable name="titleChop">
2444                                 <xsl:call-template name="chopPunctuation">
2445                                         <xsl:with-param name="chopString">
2446                                                 <xsl:call-template name="subfieldSelect">
2447                                                         <xsl:with-param name="codes">ah</xsl:with-param>
2448                                                 </xsl:call-template>
2449                                         </xsl:with-param>
2450                                 </xsl:call-template>
2451                         </xsl:variable>
2452                         <titleInfo type="alternative">
2453                                 <title>
2454                                         <xsl:value-of select="$titleChop" />
2455                                 </title>
2456                                 <xsl:call-template name="part"/>
2457                         </titleInfo>
2458                         <titleInfo type="alternative-nfi">
2459                                 <xsl:choose>
2460                                         <xsl:when test="@ind1>0">
2461                                                 <nonSort>
2462                                                         <xsl:value-of select="substring($titleChop,1,@ind1)"/>
2463                                                 </nonSort>
2464                                                 <title>
2465                                                         <xsl:value-of select="substring($titleChop,@ind1+1)"/>
2466                                                 </title>
2467                                         </xsl:when>
2468                                         <xsl:otherwise>
2469                                                 <title>
2470                                                         <xsl:value-of select="$titleChop" />
2471                                                 </title>
2472                                         </xsl:otherwise>
2473                                 </xsl:choose>
2474                                 <xsl:call-template name="part"/>
2475                         </titleInfo>
2476                 </xsl:for-each>
2477                 <xsl:for-each select="marc:datafield[@tag='100']">
2478                         <name type="personal">
2479                                 <xsl:call-template name="uri" />
2480                                 <xsl:call-template name="nameABCDQ"/>
2481                                 <xsl:call-template name="affiliation"/>
2482                                 <role>
2483                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2484                                 </role>
2485                                 <xsl:call-template name="role"/>
2486                         </name>
2487                 </xsl:for-each>
2488                 <xsl:for-each select="marc:datafield[@tag='110']">
2489                         <name type="corporate">
2490                                 <xsl:call-template name="uri" />
2491                                 <xsl:call-template name="nameABCDN"/>
2492                                 <role>
2493                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2494                                 </role>
2495                                 <xsl:call-template name="role"/>
2496                         </name>
2497                 </xsl:for-each>
2498                 <xsl:for-each select="marc:datafield[@tag='111']">
2499                         <name type="conference">
2500                                 <xsl:call-template name="uri" />
2501                                 <xsl:call-template name="nameACDEQ"/>
2502                                 <role>
2503                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2504                                 </role>
2505                                 <xsl:call-template name="role"/>
2506                         </name>
2507                 </xsl:for-each>
2508                 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
2509                         <name type="personal">
2510                                 <xsl:call-template name="uri" />
2511                                 <xsl:call-template name="nameABCDQ"/>
2512                                 <xsl:call-template name="affiliation"/>
2513                                 <xsl:call-template name="role"/>
2514                         </name>
2515                 </xsl:for-each>
2516                 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
2517                         <name type="corporate">
2518                                 <xsl:call-template name="uri" />
2519                                 <xsl:call-template name="nameABCDN"/>
2520                                 <xsl:call-template name="role"/>
2521                         </name>
2522                 </xsl:for-each>
2523                 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
2524                         <name type="conference">
2525                                 <xsl:call-template name="uri" />
2526                                 <xsl:call-template name="nameACDEQ"/>
2527                                 <xsl:call-template name="role"/>
2528                         </name>
2529                 </xsl:for-each>
2530                 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
2531                         <name>
2532                                 <xsl:if test="@ind1=1">
2533                                         <xsl:attribute name="type">
2534                                                 <xsl:text>personal</xsl:text>
2535                                         </xsl:attribute>
2536                                 </xsl:if>
2537                                 <namePart>
2538                                         <xsl:value-of select="marc:subfield[@code='a']"/>
2539                                 </namePart>
2540                                 <xsl:call-template name="role"/>
2541                         </name>
2542                 </xsl:for-each>
2543                 <typeOfResource>
2544                         <xsl:if test="$leader7='c'">
2545                                 <xsl:attribute name="collection">yes</xsl:attribute>
2546                         </xsl:if>
2547                         <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
2548                                 <xsl:attribute name="manuscript">yes</xsl:attribute>
2549                         </xsl:if>
2550                         <xsl:choose>
2551                                 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
2552                                 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
2553                                 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
2554                                 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
2555                                 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
2556                                 <xsl:when test="$leader6='k'">still image</xsl:when>
2557                                 <xsl:when test="$leader6='g'">moving image</xsl:when>
2558                                 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
2559                                 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
2560                                 <xsl:when test="$leader6='p'">mixed material</xsl:when>
2561                         </xsl:choose>
2562                 </typeOfResource>
2563                 <xsl:if test="substring($controlField008,26,1)='d'">
2564                         <genre authority="marc">globe</genre>
2565                 </xsl:if>
2566                 <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
2567                         <genre authority="marc">remote sensing image</genre>
2568                 </xsl:if>
2569                 <xsl:if test="$typeOf008='MP'">
2570                         <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
2571                         <xsl:choose>
2572                                 <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
2573                                         <genre authority="marc">map</genre>
2574                                 </xsl:when>
2575                                 <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
2576                                         <genre authority="marc">atlas</genre>
2577                                 </xsl:when>
2578                         </xsl:choose>
2579                 </xsl:if>
2580                 <xsl:if test="$typeOf008='SE'">
2581                         <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
2582                         <xsl:choose>
2583                                 <xsl:when test="$controlField008-21='d'">
2584                                         <genre authority="marc">database</genre>
2585                                 </xsl:when>
2586                                 <xsl:when test="$controlField008-21='l'">
2587                                         <genre authority="marc">loose-leaf</genre>
2588                                 </xsl:when>
2589                                 <xsl:when test="$controlField008-21='m'">
2590                                         <genre authority="marc">series</genre>
2591                                 </xsl:when>
2592                                 <xsl:when test="$controlField008-21='n'">
2593                                         <genre authority="marc">newspaper</genre>
2594                                 </xsl:when>
2595                                 <xsl:when test="$controlField008-21='p'">
2596                                         <genre authority="marc">periodical</genre>
2597                                 </xsl:when>
2598                                 <xsl:when test="$controlField008-21='w'">
2599                                         <genre authority="marc">web site</genre>
2600                                 </xsl:when>
2601                         </xsl:choose>
2602                 </xsl:if>
2603                 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
2604                         <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
2605                         <xsl:choose>
2606                                 <xsl:when test="contains($controlField008-24,'a')">
2607                                         <genre authority="marc">abstract or summary</genre>
2608                                 </xsl:when>
2609                                 <xsl:when test="contains($controlField008-24,'b')">
2610                                         <genre authority="marc">bibliography</genre>
2611                                 </xsl:when>
2612                                 <xsl:when test="contains($controlField008-24,'c')">
2613                                         <genre authority="marc">catalog</genre>
2614                                 </xsl:when>
2615                                 <xsl:when test="contains($controlField008-24,'d')">
2616                                         <genre authority="marc">dictionary</genre>
2617                                 </xsl:when>
2618                                 <xsl:when test="contains($controlField008-24,'e')">
2619                                         <genre authority="marc">encyclopedia</genre>
2620                                 </xsl:when>
2621                                 <xsl:when test="contains($controlField008-24,'f')">
2622                                         <genre authority="marc">handbook</genre>
2623                                 </xsl:when>
2624                                 <xsl:when test="contains($controlField008-24,'g')">
2625                                         <genre authority="marc">legal article</genre>
2626                                 </xsl:when>
2627                                 <xsl:when test="contains($controlField008-24,'i')">
2628                                         <genre authority="marc">index</genre>
2629                                 </xsl:when>
2630                                 <xsl:when test="contains($controlField008-24,'k')">
2631                                         <genre authority="marc">discography</genre>
2632                                 </xsl:when>
2633                                 <xsl:when test="contains($controlField008-24,'l')">
2634                                         <genre authority="marc">legislation</genre>
2635                                 </xsl:when>
2636                                 <xsl:when test="contains($controlField008-24,'m')">
2637                                         <genre authority="marc">theses</genre>
2638                                 </xsl:when>
2639                                 <xsl:when test="contains($controlField008-24,'n')">
2640                                         <genre authority="marc">survey of literature</genre>
2641                                 </xsl:when>
2642                                 <xsl:when test="contains($controlField008-24,'o')">
2643                                         <genre authority="marc">review</genre>
2644                                 </xsl:when>
2645                                 <xsl:when test="contains($controlField008-24,'p')">
2646                                         <genre authority="marc">programmed text</genre>
2647                                 </xsl:when>
2648                                 <xsl:when test="contains($controlField008-24,'q')">
2649                                         <genre authority="marc">filmography</genre>
2650                                 </xsl:when>
2651                                 <xsl:when test="contains($controlField008-24,'r')">
2652                                         <genre authority="marc">directory</genre>
2653                                 </xsl:when>
2654                                 <xsl:when test="contains($controlField008-24,'s')">
2655                                         <genre authority="marc">statistics</genre>
2656                                 </xsl:when>
2657                                 <xsl:when test="contains($controlField008-24,'t')">
2658                                         <genre authority="marc">technical report</genre>
2659                                 </xsl:when>
2660                                 <xsl:when test="contains($controlField008-24,'v')">
2661                                         <genre authority="marc">legal case and case notes</genre>
2662                                 </xsl:when>
2663                                 <xsl:when test="contains($controlField008-24,'w')">
2664                                         <genre authority="marc">law report or digest</genre>
2665                                 </xsl:when>
2666                                 <xsl:when test="contains($controlField008-24,'z')">
2667                                         <genre authority="marc">treaty</genre>
2668                                 </xsl:when>
2669                         </xsl:choose>
2670                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
2671                         <xsl:choose>
2672                                 <xsl:when test="$controlField008-29='1'">
2673                                         <genre authority="marc">conference publication</genre>
2674                                 </xsl:when>
2675                         </xsl:choose>
2676                 </xsl:if>
2677                 <xsl:if test="$typeOf008='CF'">
2678                         <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
2679                         <xsl:choose>
2680                                 <xsl:when test="$controlField008-26='a'">
2681                                         <genre authority="marc">numeric data</genre>
2682                                 </xsl:when>
2683                                 <xsl:when test="$controlField008-26='e'">
2684                                         <genre authority="marc">database</genre>
2685                                 </xsl:when>
2686                                 <xsl:when test="$controlField008-26='f'">
2687                                         <genre authority="marc">font</genre>
2688                                 </xsl:when>
2689                                 <xsl:when test="$controlField008-26='g'">
2690                                         <genre authority="marc">game</genre>
2691                                 </xsl:when>
2692                         </xsl:choose>
2693                 </xsl:if>
2694                 <xsl:if test="$typeOf008='BK'">
2695                         <xsl:if test="substring($controlField008,25,1)='j'">
2696                                 <genre authority="marc">patent</genre>
2697                         </xsl:if>
2698                         <xsl:if test="substring($controlField008,31,1)='1'">
2699                                 <genre authority="marc">festschrift</genre>
2700                         </xsl:if>
2701                         <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
2702                         <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
2703                                 <genre authority="marc">biography</genre>
2704                         </xsl:if>
2705                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
2706                         <xsl:choose>
2707                                 <xsl:when test="$controlField008-33='e'">
2708                                         <genre authority="marc">essay</genre>
2709                                 </xsl:when>
2710                                 <xsl:when test="$controlField008-33='d'">
2711                                         <genre authority="marc">drama</genre>
2712                                 </xsl:when>
2713                                 <xsl:when test="$controlField008-33='c'">
2714                                         <genre authority="marc">comic strip</genre>
2715                                 </xsl:when>
2716                                 <xsl:when test="$controlField008-33='l'">
2717                                         <genre authority="marc">fiction</genre>
2718                                 </xsl:when>
2719                                 <xsl:when test="$controlField008-33='h'">
2720                                         <genre authority="marc">humor, satire</genre>
2721                                 </xsl:when>
2722                                 <xsl:when test="$controlField008-33='i'">
2723                                         <genre authority="marc">letter</genre>
2724                                 </xsl:when>
2725                                 <xsl:when test="$controlField008-33='f'">
2726                                         <genre authority="marc">novel</genre>
2727                                 </xsl:when>
2728                                 <xsl:when test="$controlField008-33='j'">
2729                                         <genre authority="marc">short story</genre>
2730                                 </xsl:when>
2731                                 <xsl:when test="$controlField008-33='s'">
2732                                         <genre authority="marc">speech</genre>
2733                                 </xsl:when>
2734                         </xsl:choose>
2735                 </xsl:if>
2736                 <xsl:if test="$typeOf008='MU'">
2737                         <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
2738                         <xsl:if test="contains($controlField008-30-31,'b')">
2739                                 <genre authority="marc">biography</genre>
2740                         </xsl:if>
2741                         <xsl:if test="contains($controlField008-30-31,'c')">
2742                                 <genre authority="marc">conference publication</genre>
2743                         </xsl:if>
2744                         <xsl:if test="contains($controlField008-30-31,'d')">
2745                                 <genre authority="marc">drama</genre>
2746                         </xsl:if>
2747                         <xsl:if test="contains($controlField008-30-31,'e')">
2748                                 <genre authority="marc">essay</genre>
2749                         </xsl:if>
2750                         <xsl:if test="contains($controlField008-30-31,'f')">
2751                                 <genre authority="marc">fiction</genre>
2752                         </xsl:if>
2753                         <xsl:if test="contains($controlField008-30-31,'o')">
2754                                 <genre authority="marc">folktale</genre>
2755                         </xsl:if>
2756                         <xsl:if test="contains($controlField008-30-31,'h')">
2757                                 <genre authority="marc">history</genre>
2758                         </xsl:if>
2759                         <xsl:if test="contains($controlField008-30-31,'k')">
2760                                 <genre authority="marc">humor, satire</genre>
2761                         </xsl:if>
2762                         <xsl:if test="contains($controlField008-30-31,'m')">
2763                                 <genre authority="marc">memoir</genre>
2764                         </xsl:if>
2765                         <xsl:if test="contains($controlField008-30-31,'p')">
2766                                 <genre authority="marc">poetry</genre>
2767                         </xsl:if>
2768                         <xsl:if test="contains($controlField008-30-31,'r')">
2769                                 <genre authority="marc">rehearsal</genre>
2770                         </xsl:if>
2771                         <xsl:if test="contains($controlField008-30-31,'g')">
2772                                 <genre authority="marc">reporting</genre>
2773                         </xsl:if>
2774                         <xsl:if test="contains($controlField008-30-31,'s')">
2775                                 <genre authority="marc">sound</genre>
2776                         </xsl:if>
2777                         <xsl:if test="contains($controlField008-30-31,'l')">
2778                                 <genre authority="marc">speech</genre>
2779                         </xsl:if>
2780                 </xsl:if>
2781                 <xsl:if test="$typeOf008='VM'">
2782                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
2783                         <xsl:choose>
2784                                 <xsl:when test="$controlField008-33='a'">
2785                                         <genre authority="marc">art original</genre>
2786                                 </xsl:when>
2787                                 <xsl:when test="$controlField008-33='b'">
2788                                         <genre authority="marc">kit</genre>
2789                                 </xsl:when>
2790                                 <xsl:when test="$controlField008-33='c'">
2791                                         <genre authority="marc">art reproduction</genre>
2792                                 </xsl:when>
2793                                 <xsl:when test="$controlField008-33='d'">
2794                                         <genre authority="marc">diorama</genre>
2795                                 </xsl:when>
2796                                 <xsl:when test="$controlField008-33='f'">
2797                                         <genre authority="marc">filmstrip</genre>
2798                                 </xsl:when>
2799                                 <xsl:when test="$controlField008-33='g'">
2800                                         <genre authority="marc">legal article</genre>
2801                                 </xsl:when>
2802                                 <xsl:when test="$controlField008-33='i'">
2803                                         <genre authority="marc">picture</genre>
2804                                 </xsl:when>
2805                                 <xsl:when test="$controlField008-33='k'">
2806                                         <genre authority="marc">graphic</genre>
2807                                 </xsl:when>
2808                                 <xsl:when test="$controlField008-33='l'">
2809                                         <genre authority="marc">technical drawing</genre>
2810                                 </xsl:when>
2811                                 <xsl:when test="$controlField008-33='m'">
2812                                         <genre authority="marc">motion picture</genre>
2813                                 </xsl:when>
2814                                 <xsl:when test="$controlField008-33='n'">
2815                                         <genre authority="marc">chart</genre>
2816                                 </xsl:when>
2817                                 <xsl:when test="$controlField008-33='o'">
2818                                         <genre authority="marc">flash card</genre>
2819                                 </xsl:when>
2820                                 <xsl:when test="$controlField008-33='p'">
2821                                         <genre authority="marc">microscope slide</genre>
2822                                 </xsl:when>
2823                                 <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
2824                                         <genre authority="marc">model</genre>
2825                                 </xsl:when>
2826                                 <xsl:when test="$controlField008-33='r'">
2827                                         <genre authority="marc">realia</genre>
2828                                 </xsl:when>
2829                                 <xsl:when test="$controlField008-33='s'">
2830                                         <genre authority="marc">slide</genre>
2831                                 </xsl:when>
2832                                 <xsl:when test="$controlField008-33='t'">
2833                                         <genre authority="marc">transparency</genre>
2834                                 </xsl:when>
2835                                 <xsl:when test="$controlField008-33='v'">
2836                                         <genre authority="marc">videorecording</genre>
2837                                 </xsl:when>
2838                                 <xsl:when test="$controlField008-33='w'">
2839                                         <genre authority="marc">toy</genre>
2840                                 </xsl:when>
2841                         </xsl:choose>
2842                 </xsl:if>
2843                 <xsl:for-each select="marc:datafield[@tag=655]">
2844                         <genre authority="marc">
2845                                 <xsl:attribute name="authority">
2846                                         <xsl:value-of select="marc:subfield[@code='2']"/>
2847                                 </xsl:attribute>
2848                                 <xsl:call-template name="subfieldSelect">
2849                                         <xsl:with-param name="codes">abvxyz</xsl:with-param>
2850                                         <xsl:with-param name="delimeter">-</xsl:with-param>
2851                                 </xsl:call-template>
2852                         </genre>
2853                 </xsl:for-each>
2854                 <originInfo>
2855                         <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
2856                         <xsl:if test="translate($MARCpublicationCode,'|','')">
2857                                 <place>
2858                                         <placeTerm>
2859                                                 <xsl:attribute name="type">code</xsl:attribute>
2860                                                 <xsl:attribute name="authority">marccountry</xsl:attribute>
2861                                                 <xsl:value-of select="$MARCpublicationCode"/>
2862                                         </placeTerm>
2863                                 </place>
2864                         </xsl:if>
2865                         <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
2866                                 <place>
2867                                         <placeTerm>
2868                                                 <xsl:attribute name="type">code</xsl:attribute>
2869                                                 <xsl:attribute name="authority">iso3166</xsl:attribute>
2870                                                 <xsl:value-of select="."/>
2871                                         </placeTerm>
2872                                 </place>
2873                         </xsl:for-each>
2874                         <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
2875                                 <place>
2876                                         <placeTerm>
2877                                                 <xsl:attribute name="type">text</xsl:attribute>
2878                                                 <xsl:call-template name="chopPunctuationFront">
2879                                                         <xsl:with-param name="chopString">
2880                                                                 <xsl:call-template name="chopPunctuation">
2881                                                                         <xsl:with-param name="chopString" select="."/>
2882                                                                 </xsl:call-template>
2883                                                         </xsl:with-param>
2884                                                 </xsl:call-template>
2885                                         </placeTerm>
2886                                 </place>
2887                         </xsl:for-each>
2888                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
2889                                 <dateValid point="start">
2890                                         <xsl:value-of select="."/>
2891                                 </dateValid>
2892                         </xsl:for-each>
2893                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
2894                                 <dateValid point="end">
2895                                         <xsl:value-of select="."/>
2896                                 </dateValid>
2897                         </xsl:for-each>
2898                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
2899                                 <dateModified>
2900                                         <xsl:value-of select="."/>
2901                                 </dateModified>
2902                         </xsl:for-each>
2903                         <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
2904                                 <xsl:choose>
2905                                         <xsl:when test="@code='b'">
2906                                                 <publisher>
2907                                                         <xsl:call-template name="chopPunctuation">
2908                                                                 <xsl:with-param name="chopString" select="."/>
2909                                                                 <xsl:with-param name="punctuation">
2910                                                                         <xsl:text>:,;/ </xsl:text>
2911                                                                 </xsl:with-param>
2912                                                         </xsl:call-template>
2913                                                 </publisher>
2914                                         </xsl:when>
2915                                         <xsl:when test="@code='c'">
2916                                                 <dateIssued>
2917                                                         <xsl:call-template name="chopPunctuation">
2918                                                                 <xsl:with-param name="chopString" select="."/>
2919                                                         </xsl:call-template>
2920                                                 </dateIssued>
2921                                         </xsl:when>
2922                                         <xsl:when test="@code='g'">
2923                                                 <dateCreated>
2924                                                         <xsl:value-of select="."/>
2925                                                 </dateCreated>
2926                                         </xsl:when>
2927                                 </xsl:choose>
2928                         </xsl:for-each>
2929                         <xsl:variable name="dataField260c">
2930                                 <xsl:call-template name="chopPunctuation">
2931                                         <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
2932                                 </xsl:call-template>
2933                         </xsl:variable>
2934                         <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
2935                         <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
2936                         <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
2937                         <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
2938                                 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
2939                                         <dateIssued encoding="marc">
2940                                                 <xsl:value-of select="$controlField008-7-10"/>
2941                                         </dateIssued>
2942                                 </xsl:if>
2943                         </xsl:if>
2944                         <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
2945                                 <xsl:if test="$controlField008-7-10">
2946                                         <dateIssued encoding="marc" point="start">
2947                                                 <xsl:value-of select="$controlField008-7-10"/>
2948                                         </dateIssued>
2949                                 </xsl:if>
2950                         </xsl:if>
2951                         <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
2952                                 <xsl:if test="$controlField008-11-14">
2953                                         <dateIssued encoding="marc" point="end">
2954                                                 <xsl:value-of select="$controlField008-11-14"/>
2955                                         </dateIssued>
2956                                 </xsl:if>
2957                         </xsl:if>
2958                         <xsl:if test="$controlField008-6='q'">
2959                                 <xsl:if test="$controlField008-7-10">
2960                                         <dateIssued encoding="marc" point="start" qualifier="questionable">
2961                                                 <xsl:value-of select="$controlField008-7-10"/>
2962                                         </dateIssued>
2963                                 </xsl:if>
2964                         </xsl:if>
2965                         <xsl:if test="$controlField008-6='q'">
2966                                 <xsl:if test="$controlField008-11-14">
2967                                         <dateIssued encoding="marc" point="end" qualifier="questionable">
2968                                                 <xsl:value-of select="$controlField008-11-14"/>
2969                                         </dateIssued>
2970                                 </xsl:if>
2971                         </xsl:if>
2972                         <xsl:if test="$controlField008-6='t'">
2973                                 <xsl:if test="$controlField008-11-14">
2974                                         <copyrightDate encoding="marc">
2975                                                 <xsl:value-of select="$controlField008-11-14"/>
2976                                         </copyrightDate>
2977                                 </xsl:if>
2978                         </xsl:if>
2979                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
2980                                 <dateCaptured encoding="iso8601">
2981                                         <xsl:value-of select="."/>
2982                                 </dateCaptured>
2983                         </xsl:for-each>
2984                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
2985                                 <dateCaptured encoding="iso8601" point="start">
2986                                         <xsl:value-of select="."/>
2987                                 </dateCaptured>
2988                         </xsl:for-each>
2989                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
2990                                 <dateCaptured encoding="iso8601" point="end">
2991                                         <xsl:value-of select="."/>
2992                                 </dateCaptured>
2993                         </xsl:for-each>
2994                         <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
2995                                 <edition>
2996                                         <xsl:value-of select="."/>
2997                                 </edition>
2998                         </xsl:for-each>
2999                         <xsl:for-each select="marc:leader">
3000                                 <issuance>
3001                                         <xsl:choose>
3002                                                 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
3003                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
3004                                         </xsl:choose>
3005                                 </issuance>
3006                         </xsl:for-each>
3007                         <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
3008                                 <frequency>
3009                                         <xsl:call-template name="subfieldSelect">
3010                                                 <xsl:with-param name="codes">ab</xsl:with-param>
3011                                         </xsl:call-template>
3012                                 </frequency>
3013                         </xsl:for-each>
3014                 </originInfo>
3015                 <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
3016                 <xsl:if test="$controlField008-35-37">
3017                         <language>
3018                                 <languageTerm authority="iso639-2b" type="code">
3019                                         <xsl:value-of select="substring($controlField008,36,3)"/>
3020                                 </languageTerm>
3021                         </language>
3022                 </xsl:if>
3023                 <xsl:for-each select="marc:datafield[@tag=041]">
3024                         <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
3025                                 <xsl:variable name="langCodes" select="."/>
3026                                 <xsl:choose>
3027                                         <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
3028                                                 <!-- not stacked but could be repeated -->
3029                                                 <xsl:call-template name="rfcLanguages">
3030                                                         <xsl:with-param name="nodeNum">
3031                                                                 <xsl:value-of select="1"/>
3032                                                         </xsl:with-param>
3033                                                         <xsl:with-param name="usedLanguages">
3034                                                                 <xsl:text></xsl:text>
3035                                                         </xsl:with-param>
3036                                                         <xsl:with-param name="controlField008-35-37">
3037                                                                 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
3038                                                         </xsl:with-param>
3039                                                 </xsl:call-template>
3040                                         </xsl:when>
3041                                         <xsl:otherwise>
3042                                                 <!-- iso -->
3043                                                 <xsl:variable name="allLanguages">
3044                                                         <xsl:copy-of select="$langCodes"></xsl:copy-of>
3045                                                 </xsl:variable>
3046                                                 <xsl:variable name="currentLanguage">
3047                                                         <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
3048                                                 </xsl:variable>
3049                                                 <xsl:call-template name="isoLanguage">
3050                                                         <xsl:with-param name="currentLanguage">
3051                                                                 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
3052                                                         </xsl:with-param>
3053                                                         <xsl:with-param name="remainingLanguages">
3054                                                                 <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
3055                                                         </xsl:with-param>
3056                                                         <xsl:with-param name="usedLanguages">
3057                                                                 <xsl:if test="$controlField008-35-37">
3058                                                                         <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
3059                                                                 </xsl:if>
3060                                                         </xsl:with-param>
3061                                                 </xsl:call-template>
3062                                         </xsl:otherwise>
3063                                 </xsl:choose>
3064                         </xsl:for-each>
3065                 </xsl:for-each>
3066                 <xsl:variable name="physicalDescription">
3067                         <!--3.2 change tmee 007/11 -->
3068                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
3069                                 <digitalOrigin>reformatted digital</digitalOrigin>
3070                         </xsl:if>
3071                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
3072                                 <digitalOrigin>digitized microfilm</digitalOrigin>
3073                         </xsl:if>
3074                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
3075                                 <digitalOrigin>digitized other analog</digitalOrigin>
3076                         </xsl:if>
3077                         <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
3078                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
3079                         <xsl:variable name="check008-23">
3080                                 <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
3081                                         <xsl:value-of select="true()"></xsl:value-of>
3082                                 </xsl:if>
3083                         </xsl:variable>
3084                         <xsl:variable name="check008-29">
3085                                 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
3086                                         <xsl:value-of select="true()"></xsl:value-of>
3087                                 </xsl:if>
3088                         </xsl:variable>
3089                         <xsl:choose>
3090                                 <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
3091                                         <form authority="marcform">braille</form>
3092                                 </xsl:when>
3093                                 <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
3094                                         <form authority="marcform">print</form>
3095                                 </xsl:when>
3096                                 <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
3097                                         <form authority="marcform">electronic</form>
3098                                 </xsl:when>
3099                                 <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
3100                                         <form authority="marcform">microfiche</form>
3101                                 </xsl:when>
3102                                 <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
3103                                         <form authority="marcform">microfilm</form>
3104                                 </xsl:when>
3105                         </xsl:choose>
3106                         <!-- 1/04 fix -->
3107                         <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
3108                                 <form authority="gmd">
3109                                         <xsl:call-template name="chopBrackets">
3110                                                 <xsl:with-param name="chopString">
3111                                                         <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
3112                                                 </xsl:with-param>
3113                                         </xsl:call-template>
3114                                 </form>
3115                         </xsl:if>
3116                         <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
3117                                 <form authority="gmd">
3118                                         <xsl:call-template name="chopBrackets">
3119                                                 <xsl:with-param name="chopString">
3120                                                         <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
3121                                                 </xsl:with-param>
3122                                         </xsl:call-template>
3123                                 </form>
3124                         </xsl:if>
3125                         <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
3126                                 <form authority="gmd">
3127                                         <xsl:call-template name="chopBrackets">
3128                                                 <xsl:with-param name="chopString">
3129                                                         <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
3130                                                 </xsl:with-param>
3131                                         </xsl:call-template>
3132                                 </form>
3133                         </xsl:if>
3134                         <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
3135                                 <form authority="gmd">
3136                                         <xsl:call-template name="chopBrackets">
3137                                                 <xsl:with-param name="chopString">
3138                                                         <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
3139                                                 </xsl:with-param>
3140                                         </xsl:call-template>
3141                                 </form>
3142                         </xsl:if>
3143                         <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
3144                                 <form authority="gmd">
3145                                         <xsl:call-template name="chopBrackets">
3146                                                 <xsl:with-param name="chopString">
3147                                                         <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
3148                                                 </xsl:with-param>
3149                                         </xsl:call-template>
3150                                 </form>
3151                         </xsl:if>
3152                         <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
3153                                 <form authority="gmd">
3154                                         <xsl:call-template name="chopBrackets">
3155                                                 <xsl:with-param name="chopString">
3156                                                         <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
3157                                                 </xsl:with-param>
3158                                         </xsl:call-template>
3159                                 </form>
3160                         </xsl:if>
3161                         <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
3162                                 <form>
3163                                         <xsl:value-of select="."></xsl:value-of>
3164                                 </form>
3165                         </xsl:for-each>
3166                         <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
3167                                 <xsl:choose>
3168                                         <xsl:when test="substring(text(),14,1)='a'">
3169                                                 <reformattingQuality>access</reformattingQuality>
3170                                         </xsl:when>
3171                                         <xsl:when test="substring(text(),14,1)='p'">
3172                                                 <reformattingQuality>preservation</reformattingQuality>
3173                                         </xsl:when>
3174                                         <xsl:when test="substring(text(),14,1)='r'">
3175                                                 <reformattingQuality>replacement</reformattingQuality>
3176                                         </xsl:when>
3177                                 </xsl:choose>
3178                         </xsl:for-each>
3179                         <!--3.2 change tmee 007/01 -->
3180                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
3181                                 <form authority="smd">chip cartridge</form>
3182                         </xsl:if>
3183                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
3184                                 <form authority="smd">computer optical disc cartridge</form>
3185                         </xsl:if>
3186                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
3187                                 <form authority="smd">magnetic disc</form>
3188                         </xsl:if>
3189                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
3190                                 <form authority="smd">magneto-optical disc</form>
3191                         </xsl:if>
3192                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
3193                                 <form authority="smd">optical disc</form>
3194                         </xsl:if>
3195                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
3196                                 <form authority="smd">remote</form>
3197                         </xsl:if>
3198                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
3199                                 <form authority="smd">tape cartridge</form>
3200                         </xsl:if>
3201                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
3202                                 <form authority="smd">tape cassette</form>
3203                         </xsl:if>
3204                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
3205                                 <form authority="smd">tape reel</form>
3206                         </xsl:if>
3207                         
3208                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
3209                                 <form authority="smd">celestial globe</form>
3210                         </xsl:if>
3211                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
3212                                 <form authority="smd">earth moon globe</form>
3213                         </xsl:if>
3214                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
3215                                 <form authority="smd">planetary or lunar globe</form>
3216                         </xsl:if>
3217                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
3218                                 <form authority="smd">terrestrial globe</form>
3219                         </xsl:if>
3220                         
3221                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
3222                                 <form authority="smd">kit</form>
3223                         </xsl:if>
3224                         
3225                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
3226                                 <form authority="smd">atlas</form>
3227                         </xsl:if>
3228                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
3229                                 <form authority="smd">diagram</form>
3230                         </xsl:if>
3231                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
3232                                 <form authority="smd">map</form>
3233                         </xsl:if>
3234                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
3235                                 <form authority="smd">model</form>
3236                         </xsl:if>
3237                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
3238                                 <form authority="smd">profile</form>
3239                         </xsl:if>
3240                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
3241                                 <form authority="smd">remote-sensing image</form>
3242                         </xsl:if>
3243                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
3244                                 <form authority="smd">section</form>
3245                         </xsl:if>
3246                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
3247                                 <form authority="smd">view</form>
3248                         </xsl:if>
3249                         
3250                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
3251                                 <form authority="smd">aperture card</form>
3252                         </xsl:if>
3253                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
3254                                 <form authority="smd">microfiche</form>
3255                         </xsl:if>
3256                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
3257                                 <form authority="smd">microfiche cassette</form>
3258                         </xsl:if>
3259                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
3260                                 <form authority="smd">microfilm cartridge</form>
3261                         </xsl:if>
3262                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
3263                                 <form authority="smd">microfilm cassette</form>
3264                         </xsl:if>
3265                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
3266                                 <form authority="smd">microfilm reel</form>
3267                         </xsl:if>
3268                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
3269                                 <form authority="smd">microopaque</form>
3270                         </xsl:if>
3271                         
3272                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
3273                                 <form authority="smd">film cartridge</form>
3274                         </xsl:if>
3275                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
3276                                 <form authority="smd">film cassette</form>
3277                         </xsl:if>
3278                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
3279                                 <form authority="smd">film reel</form>
3280                         </xsl:if>
3281                         
3282                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
3283                                 <form authority="smd">chart</form>
3284                         </xsl:if>
3285                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
3286                                 <form authority="smd">collage</form>
3287                         </xsl:if>
3288                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
3289                                 <form authority="smd">drawing</form>
3290                         </xsl:if>
3291                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
3292                                 <form authority="smd">flash card</form>
3293                         </xsl:if>
3294                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
3295                                 <form authority="smd">painting</form>
3296                         </xsl:if>
3297                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
3298                                 <form authority="smd">photomechanical print</form>
3299                         </xsl:if>
3300                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
3301                                 <form authority="smd">photonegative</form>
3302                         </xsl:if>
3303                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
3304                                 <form authority="smd">photoprint</form>
3305                         </xsl:if>
3306                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
3307                                 <form authority="smd">picture</form>
3308                         </xsl:if>
3309                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
3310                                 <form authority="smd">print</form>
3311                         </xsl:if>
3312                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
3313                                 <form authority="smd">technical drawing</form>
3314                         </xsl:if>
3315                         
3316                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
3317                                 <form authority="smd">notated music</form>
3318                         </xsl:if>
3319                         
3320                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
3321                                 <form authority="smd">filmslip</form>
3322                         </xsl:if>
3323                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
3324                                 <form authority="smd">filmstrip cartridge</form>
3325                         </xsl:if>
3326                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
3327                                 <form authority="smd">filmstrip roll</form>
3328                         </xsl:if>
3329                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
3330                                 <form authority="smd">other filmstrip type</form>
3331                         </xsl:if>
3332                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
3333                                 <form authority="smd">slide</form>
3334                         </xsl:if>
3335                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
3336                                 <form authority="smd">transparency</form>
3337                         </xsl:if>
3338                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
3339                                 <form authority="smd">remote-sensing image</form>
3340                         </xsl:if>
3341                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
3342                                 <form authority="smd">cylinder</form>
3343                         </xsl:if>
3344                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
3345                                 <form authority="smd">roll</form>
3346                         </xsl:if>
3347                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
3348                                 <form authority="smd">sound cartridge</form>
3349                         </xsl:if>
3350                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
3351                                 <form authority="smd">sound cassette</form>
3352                         </xsl:if>
3353                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
3354                                 <form authority="smd">sound disc</form>
3355                         </xsl:if>
3356                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
3357                                 <form authority="smd">sound-tape reel</form>
3358                         </xsl:if>
3359                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
3360                                 <form authority="smd">sound-track film</form>
3361                         </xsl:if>
3362                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
3363                                 <form authority="smd">wire recording</form>
3364                         </xsl:if>
3365                         
3366                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
3367                                 <form authority="smd">braille</form>
3368                         </xsl:if>
3369                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
3370                                 <form authority="smd">combination</form>
3371                         </xsl:if>
3372                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
3373                                 <form authority="smd">moon</form>
3374                         </xsl:if>
3375                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
3376                                 <form authority="smd">tactile, with no writing system</form>
3377                         </xsl:if>
3378                         
3379                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
3380                                 <form authority="smd">braille</form>
3381                         </xsl:if>
3382                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
3383                                 <form authority="smd">large print</form>
3384                         </xsl:if>
3385                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
3386                                 <form authority="smd">regular print</form>
3387                         </xsl:if>
3388                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
3389                                 <form authority="smd">text in looseleaf binder</form>
3390                         </xsl:if>
3391                         
3392                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
3393                                 <form authority="smd">videocartridge</form>
3394                         </xsl:if>
3395                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
3396                                 <form authority="smd">videocassette</form>
3397                         </xsl:if>
3398                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
3399                                 <form authority="smd">videodisc</form>
3400                         </xsl:if>
3401                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
3402                                 <form authority="smd">videoreel</form>
3403                         </xsl:if>
3404                         
3405                         <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
3406                                 <internetMediaType>
3407                                         <xsl:value-of select="."></xsl:value-of>
3408                                 </internetMediaType>
3409                         </xsl:for-each>
3410                         <xsl:for-each select="marc:datafield[@tag=300]">
3411                                 <extent>
3412                                         <xsl:call-template name="subfieldSelect">
3413                                                 <xsl:with-param name="codes">abce</xsl:with-param>
3414                                         </xsl:call-template>
3415                                 </extent>
3416                         </xsl:for-each>
3417                 </xsl:variable>
3418                 <xsl:if test="string-length(normalize-space($physicalDescription))">
3419                         <physicalDescription>
3420                                 <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
3421                         </physicalDescription>
3422                 </xsl:if>
3423                 <xsl:for-each select="marc:datafield[@tag=520]">
3424                         <abstract>
3425                                 <xsl:call-template name="uri"></xsl:call-template>
3426                                 <xsl:call-template name="subfieldSelect">
3427                                         <xsl:with-param name="codes">ab</xsl:with-param>
3428                                 </xsl:call-template>
3429                         </abstract>
3430                 </xsl:for-each>
3431                 <xsl:for-each select="marc:datafield[@tag=505]">
3432                         <tableOfContents>
3433                                 <xsl:call-template name="uri"></xsl:call-template>
3434                                 <xsl:call-template name="subfieldSelect">
3435                                         <xsl:with-param name="codes">agrt</xsl:with-param>
3436                                 </xsl:call-template>
3437                         </tableOfContents>
3438                 </xsl:for-each>
3439                 <xsl:for-each select="marc:datafield[@tag=521]">
3440                         <targetAudience>
3441                                 <xsl:call-template name="subfieldSelect">
3442                                         <xsl:with-param name="codes">ab</xsl:with-param>
3443                                 </xsl:call-template>
3444                         </targetAudience>
3445                 </xsl:for-each>
3446                 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
3447                         <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
3448                         <xsl:choose>
3449                                 <!-- 01/04 fix -->
3450                                 <xsl:when test="$controlField008-22='d'">
3451                                         <targetAudience authority="marctarget">adolescent</targetAudience>
3452                                 </xsl:when>
3453                                 <xsl:when test="$controlField008-22='e'">
3454                                         <targetAudience authority="marctarget">adult</targetAudience>
3455                                 </xsl:when>
3456                                 <xsl:when test="$controlField008-22='g'">
3457                                         <targetAudience authority="marctarget">general</targetAudience>
3458                                 </xsl:when>
3459                                 <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
3460                                         <targetAudience authority="marctarget">juvenile</targetAudience>
3461                                 </xsl:when>
3462                                 <xsl:when test="$controlField008-22='a'">
3463                                         <targetAudience authority="marctarget">preschool</targetAudience>
3464                                 </xsl:when>
3465                                 <xsl:when test="$controlField008-22='f'">
3466                                         <targetAudience authority="marctarget">specialized</targetAudience>
3467                                 </xsl:when>
3468                         </xsl:choose>
3469                 </xsl:if>
3470                 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
3471                         <note type="statement of responsibility">
3472                                 <xsl:value-of select="."></xsl:value-of>
3473                         </note>
3474                 </xsl:for-each>
3475                 <xsl:for-each select="marc:datafield[@tag=500]">
3476                         <note>
3477                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3478                                 <xsl:call-template name="uri"></xsl:call-template>
3479                         </note>
3480                 </xsl:for-each>
3481                 
3482                 <!--3.2 change tmee additional note fields-->
3483                 
3484                 <xsl:for-each select="marc:datafield[@tag=506]">
3485                         <note type="restrictions">
3486                                 <xsl:call-template name="uri"></xsl:call-template>
3487                                 <xsl:variable name="str">
3488                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3489                                                 <xsl:value-of select="."></xsl:value-of>
3490                                                 <xsl:text> </xsl:text>
3491                                         </xsl:for-each>
3492                                 </xsl:variable>
3493                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3494                         </note>
3495                 </xsl:for-each>
3496                 
3497                 <xsl:for-each select="marc:datafield[@tag=510]">
3498                         <note  type="citation/reference">
3499                                 <xsl:call-template name="uri"></xsl:call-template>
3500                                 <xsl:variable name="str">
3501                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3502                                                 <xsl:value-of select="."></xsl:value-of>
3503                                                 <xsl:text> </xsl:text>
3504                                         </xsl:for-each>
3505                                 </xsl:variable>
3506                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3507                         </note>
3508                 </xsl:for-each>
3509                 
3510                         
3511                 <xsl:for-each select="marc:datafield[@tag=511]">
3512                         <note type="performers">
3513                                 <xsl:call-template name="uri"></xsl:call-template>
3514                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3515                         </note>
3516                 </xsl:for-each>
3517                 <xsl:for-each select="marc:datafield[@tag=518]">
3518                         <note type="venue">
3519                                 <xsl:call-template name="uri"></xsl:call-template>
3520                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3521                         </note>
3522                 </xsl:for-each>
3523                 
3524                 <xsl:for-each select="marc:datafield[@tag=530]">
3525                         <note  type="additional physical form">
3526                                 <xsl:call-template name="uri"></xsl:call-template>
3527                                 <xsl:variable name="str">
3528                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3529                                                 <xsl:value-of select="."></xsl:value-of>
3530                                                 <xsl:text> </xsl:text>
3531                                         </xsl:for-each>
3532                                 </xsl:variable>
3533                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3534                         </note>
3535                 </xsl:for-each>
3536                 
3537                 <xsl:for-each select="marc:datafield[@tag=533]">
3538                         <note  type="reproduction">
3539                                 <xsl:call-template name="uri"></xsl:call-template>
3540                                 <xsl:variable name="str">
3541                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3542                                                 <xsl:value-of select="."></xsl:value-of>
3543                                                 <xsl:text> </xsl:text>
3544                                         </xsl:for-each>
3545                                 </xsl:variable>
3546                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3547                         </note>
3548                 </xsl:for-each>
3549                 
3550                 <xsl:for-each select="marc:datafield[@tag=534]">
3551                         <note  type="original version">
3552                                 <xsl:call-template name="uri"></xsl:call-template>
3553                                 <xsl:variable name="str">
3554                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3555                                                 <xsl:value-of select="."></xsl:value-of>
3556                                                 <xsl:text> </xsl:text>
3557                                         </xsl:for-each>
3558                                 </xsl:variable>
3559                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3560                         </note>
3561                 </xsl:for-each>
3562                 
3563                 <xsl:for-each select="marc:datafield[@tag=538]">
3564                         <note  type="system details">
3565                                 <xsl:call-template name="uri"></xsl:call-template>
3566                                 <xsl:variable name="str">
3567                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3568                                                 <xsl:value-of select="."></xsl:value-of>
3569                                                 <xsl:text> </xsl:text>
3570                                         </xsl:for-each>
3571                                 </xsl:variable>
3572                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3573                         </note>
3574                 </xsl:for-each>
3575                 
3576                 <xsl:for-each select="marc:datafield[@tag=583]">
3577                         <note type="action">
3578                                 <xsl:call-template name="uri"></xsl:call-template>
3579                                 <xsl:variable name="str">
3580                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3581                                                 <xsl:value-of select="."></xsl:value-of>
3582                                                 <xsl:text> </xsl:text>
3583                                         </xsl:for-each>
3584                                 </xsl:variable>
3585                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3586                         </note>
3587                 </xsl:for-each>
3588                 
3589
3590                 
3591                 
3592                 
3593                 <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or  @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
3594                         <note>
3595                                 <xsl:call-template name="uri"></xsl:call-template>
3596                                 <xsl:variable name="str">
3597                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3598                                                 <xsl:value-of select="."></xsl:value-of>
3599                                                 <xsl:text> </xsl:text>
3600                                         </xsl:for-each>
3601                                 </xsl:variable>
3602                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3603                         </note>
3604                 </xsl:for-each>
3605                 <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
3606                         <subject>
3607                                 <cartographics>
3608                                         <coordinates>
3609                                                 <xsl:call-template name="subfieldSelect">
3610                                                         <xsl:with-param name="codes">defg</xsl:with-param>
3611                                                 </xsl:call-template>
3612                                         </coordinates>
3613                                 </cartographics>
3614                         </subject>
3615                 </xsl:for-each>
3616                 <xsl:for-each select="marc:datafield[@tag=043]">
3617                         <subject>
3618                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
3619                                         <geographicCode>
3620                                                 <xsl:attribute name="authority">
3621                                                         <xsl:if test="@code='a'">
3622                                                                 <xsl:text>marcgac</xsl:text>
3623                                                         </xsl:if>
3624                                                         <xsl:if test="@code='b'">
3625                                                                 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
3626                                                         </xsl:if>
3627                                                         <xsl:if test="@code='c'">
3628                                                                 <xsl:text>iso3166</xsl:text>
3629                                                         </xsl:if>
3630                                                 </xsl:attribute>
3631                                                 <xsl:value-of select="self::marc:subfield"></xsl:value-of>
3632                                         </geographicCode>
3633                                 </xsl:for-each>
3634                         </subject>
3635                 </xsl:for-each>
3636                 <!-- tmee 2006/11/27 -->
3637                 <xsl:for-each select="marc:datafield[@tag=255]">
3638                         <subject>
3639                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
3640                                 <cartographics>
3641                                         <xsl:if test="@code='a'">
3642                                                 <scale>
3643                                                         <xsl:value-of select="."></xsl:value-of>
3644                                                 </scale>
3645                                         </xsl:if>
3646                                         <xsl:if test="@code='b'">
3647                                                 <projection>
3648                                                         <xsl:value-of select="."></xsl:value-of>
3649                                                 </projection>
3650                                         </xsl:if>
3651                                         <xsl:if test="@code='c'">
3652                                                 <coordinates>
3653                                                         <xsl:value-of select="."></xsl:value-of>
3654                                                 </coordinates>
3655                                         </xsl:if>
3656                                 </cartographics>
3657                                 </xsl:for-each>
3658                         </subject>
3659                 </xsl:for-each>
3660                                 
3661                 <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
3662                 <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
3663                 <xsl:for-each select="marc:datafield[@tag=752]">
3664                         <subject>
3665                                 <hierarchicalGeographic>
3666                                         <xsl:for-each select="marc:subfield[@code='a']">
3667                                                 <country>
3668                                                         <xsl:call-template name="chopPunctuation">
3669                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
3670                                                         </xsl:call-template>
3671                                                 </country>
3672                                         </xsl:for-each>
3673                                         <xsl:for-each select="marc:subfield[@code='b']">
3674                                                 <state>
3675                                                         <xsl:call-template name="chopPunctuation">
3676                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
3677                                                         </xsl:call-template>
3678                                                 </state>
3679                                         </xsl:for-each>
3680                                         <xsl:for-each select="marc:subfield[@code='c']">
3681                                                 <county>
3682                                                         <xsl:call-template name="chopPunctuation">
3683                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
3684                                                         </xsl:call-template>
3685                                                 </county>
3686                                         </xsl:for-each>
3687                                         <xsl:for-each select="marc:subfield[@code='d']">
3688                                                 <city>
3689                                                         <xsl:call-template name="chopPunctuation">
3690                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
3691                                                         </xsl:call-template>
3692                                                 </city>
3693                                         </xsl:for-each>
3694                                 </hierarchicalGeographic>
3695                         </subject>
3696                 </xsl:for-each>
3697                 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
3698                         <subject>
3699                                 <xsl:choose>
3700                                         <xsl:when test="@ind1=2">
3701                                                 <temporal encoding="iso8601" point="start">
3702                                                         <xsl:call-template name="chopPunctuation">
3703                                                                 <xsl:with-param name="chopString">
3704                                                                         <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
3705                                                                 </xsl:with-param>
3706                                                         </xsl:call-template>
3707                                                 </temporal>
3708                                                 <temporal encoding="iso8601" point="end">
3709                                                         <xsl:call-template name="chopPunctuation">
3710                                                                 <xsl:with-param name="chopString">
3711                                                                         <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
3712                                                                 </xsl:with-param>
3713                                                         </xsl:call-template>
3714                                                 </temporal>
3715                                         </xsl:when>
3716                                         <xsl:otherwise>
3717                                                 <xsl:for-each select="marc:subfield[@code='b']">
3718                                                         <temporal encoding="iso8601">
3719                                                                 <xsl:call-template name="chopPunctuation">
3720                                                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
3721                                                                 </xsl:call-template>
3722                                                         </temporal>
3723                                                 </xsl:for-each>
3724                                         </xsl:otherwise>
3725                                 </xsl:choose>
3726                         </subject>
3727                 </xsl:for-each>
3728                 <xsl:for-each select="marc:datafield[@tag=050]">
3729                         <xsl:for-each select="marc:subfield[@code='b']">
3730                                 <classification authority="lcc">
3731                                         <xsl:if test="../marc:subfield[@code='3']">
3732                                                 <xsl:attribute name="displayLabel">
3733                                                         <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
3734                                                 </xsl:attribute>
3735                                         </xsl:if>
3736                                         <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
3737                                         <xsl:text> </xsl:text>
3738                                         <xsl:value-of select="text()"></xsl:value-of>
3739                                 </classification>
3740                         </xsl:for-each>
3741                         <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
3742                                 <classification authority="lcc">
3743                                         <xsl:if test="../marc:subfield[@code='3']">
3744                                                 <xsl:attribute name="displayLabel">
3745                                                         <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
3746                                                 </xsl:attribute>
3747                                         </xsl:if>
3748                                         <xsl:value-of select="text()"></xsl:value-of>
3749                                 </classification>
3750                         </xsl:for-each>
3751                 </xsl:for-each>
3752                 <xsl:for-each select="marc:datafield[@tag=082]">
3753                         <classification authority="ddc">
3754                                 <xsl:if test="marc:subfield[@code='2']">
3755                                         <xsl:attribute name="edition">
3756                                                 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3757                                         </xsl:attribute>
3758                                 </xsl:if>
3759                                 <xsl:call-template name="subfieldSelect">
3760                                         <xsl:with-param name="codes">ab</xsl:with-param>
3761                                 </xsl:call-template>
3762                         </classification>
3763                 </xsl:for-each>
3764                 <xsl:for-each select="marc:datafield[@tag=080]">
3765                         <classification authority="udc">
3766                                 <xsl:call-template name="subfieldSelect">
3767                                         <xsl:with-param name="codes">abx</xsl:with-param>
3768                                 </xsl:call-template>
3769                         </classification>
3770                 </xsl:for-each>
3771                 <xsl:for-each select="marc:datafield[@tag=060]">
3772                         <classification authority="nlm">
3773                                 <xsl:call-template name="subfieldSelect">
3774                                         <xsl:with-param name="codes">ab</xsl:with-param>
3775                                 </xsl:call-template>
3776                         </classification>
3777                 </xsl:for-each>
3778                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
3779                         <classification authority="sudocs">
3780                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3781                         </classification>
3782                 </xsl:for-each>
3783                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
3784                         <classification authority="candoc">
3785                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3786                         </classification>
3787                 </xsl:for-each>
3788                 <xsl:for-each select="marc:datafield[@tag=086]">
3789                         <classification>
3790                                 <xsl:attribute name="authority">
3791                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3792                                 </xsl:attribute>
3793                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3794                         </classification>
3795                 </xsl:for-each>
3796                 <xsl:for-each select="marc:datafield[@tag=084]">
3797                         <classification>
3798                                 <xsl:attribute name="authority">
3799                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3800                                 </xsl:attribute>
3801                                 <xsl:call-template name="subfieldSelect">
3802                                         <xsl:with-param name="codes">ab</xsl:with-param>
3803                                 </xsl:call-template>
3804                         </classification>
3805                 </xsl:for-each>
3806                 <xsl:for-each select="marc:datafield[@tag=440]">
3807                         <relatedItem type="series">
3808                                 <xsl:variable name="titleChop">
3809                                         <xsl:call-template name="chopPunctuation">
3810                                                 <xsl:with-param name="chopString">
3811                                                         <xsl:call-template name="subfieldSelect">
3812                                                                 <xsl:with-param name="codes">av</xsl:with-param>
3813                                                         </xsl:call-template>
3814                                                 </xsl:with-param>
3815                                         </xsl:call-template>
3816                                 </xsl:variable>
3817                                 <titleInfo>
3818                                         <title>
3819                                                 <xsl:value-of select="$titleChop" />
3820                                         </title>
3821                                         <xsl:call-template name="part"></xsl:call-template>
3822                                 </titleInfo>
3823                                 <titleInfo type="nfi">
3824                                         <xsl:choose>
3825                                                 <xsl:when test="@ind2>0">
3826                                                         <nonSort>
3827                                                                 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
3828                                                         </nonSort>
3829                                                         <title>
3830                                                                 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
3831                                                         </title>
3832                                                         <xsl:call-template name="part"/>
3833                                                 </xsl:when>
3834                                                 <xsl:otherwise>
3835                                                         <title>
3836                                                                 <xsl:value-of select="$titleChop" />
3837                                                         </title>
3838                                                 </xsl:otherwise>
3839                                         </xsl:choose>
3840                                         <xsl:call-template name="part"></xsl:call-template>
3841                                 </titleInfo>
3842                         </relatedItem>
3843                 </xsl:for-each>
3844                 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
3845                         <relatedItem type="series">
3846                                 <titleInfo>
3847                                         <title>
3848                                                 <xsl:call-template name="chopPunctuation">
3849                                                         <xsl:with-param name="chopString">
3850                                                                 <xsl:call-template name="subfieldSelect">
3851                                                                         <xsl:with-param name="codes">av</xsl:with-param>
3852                                                                 </xsl:call-template>
3853                                                         </xsl:with-param>
3854                                                 </xsl:call-template>
3855                                         </title>
3856                                         <xsl:call-template name="part"></xsl:call-template>
3857                                 </titleInfo>
3858                         </relatedItem>
3859                 </xsl:for-each>
3860                 <xsl:for-each select="marc:datafield[@tag=510]">
3861                         <relatedItem type="isReferencedBy">
3862                                 <note>
3863                                         <xsl:call-template name="subfieldSelect">
3864                                                 <xsl:with-param name="codes">abcx3</xsl:with-param>
3865                                         </xsl:call-template>
3866                                 </note>
3867                         </relatedItem>
3868                 </xsl:for-each>
3869                 <xsl:for-each select="marc:datafield[@tag=534]">
3870                         <relatedItem type="original">
3871                                 <xsl:call-template name="relatedTitle"></xsl:call-template>
3872                                 <xsl:call-template name="relatedName"></xsl:call-template>
3873                                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
3874                                         <originInfo>
3875                                                 <xsl:for-each select="marc:subfield[@code='c']">
3876                                                         <publisher>
3877                                                                 <xsl:value-of select="."></xsl:value-of>
3878                                                         </publisher>
3879                                                 </xsl:for-each>
3880                                                 <xsl:for-each select="marc:subfield[@code='b']">
3881                                                         <edition>
3882                                                                 <xsl:value-of select="."></xsl:value-of>
3883                                                         </edition>
3884                                                 </xsl:for-each>
3885                                         </originInfo>
3886                                 </xsl:if>
3887                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
3888                                 <xsl:for-each select="marc:subfield[@code='z']">
3889                                         <identifier type="isbn">
3890                                                 <xsl:value-of select="."></xsl:value-of>
3891                                         </identifier>
3892                                 </xsl:for-each>
3893                                 <xsl:call-template name="relatedNote"></xsl:call-template>
3894                         </relatedItem>
3895                 </xsl:for-each>
3896                 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
3897                         <relatedItem>
3898                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
3899                                 <titleInfo>
3900                                         <title>
3901                                                 <xsl:call-template name="chopPunctuation">
3902                                                         <xsl:with-param name="chopString">
3903                                                                 <xsl:call-template name="specialSubfieldSelect">
3904                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
3905                                                                         <xsl:with-param name="axis">t</xsl:with-param>
3906                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
3907                                                                 </xsl:call-template>
3908                                                         </xsl:with-param>
3909                                                 </xsl:call-template>
3910                                         </title>
3911                                         <xsl:call-template name="part"></xsl:call-template>
3912                                 </titleInfo>
3913                                 <name type="personal">
3914                                         <namePart>
3915                                                 <xsl:call-template name="specialSubfieldSelect">
3916                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
3917                                                         <xsl:with-param name="axis">t</xsl:with-param>
3918                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
3919                                                 </xsl:call-template>
3920                                         </namePart>
3921                                         <xsl:call-template name="termsOfAddress"></xsl:call-template>
3922                                         <xsl:call-template name="nameDate"></xsl:call-template>
3923                                         <xsl:call-template name="role"></xsl:call-template>
3924                                 </name>
3925                                 <xsl:call-template name="relatedForm"></xsl:call-template>
3926                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
3927                         </relatedItem>
3928                 </xsl:for-each>
3929                 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
3930                         <relatedItem>
3931                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
3932                                 <titleInfo>
3933                                         <title>
3934                                                 <xsl:call-template name="chopPunctuation">
3935                                                         <xsl:with-param name="chopString">
3936                                                                 <xsl:call-template name="specialSubfieldSelect">
3937                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
3938                                                                         <xsl:with-param name="axis">t</xsl:with-param>
3939                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
3940                                                                 </xsl:call-template>
3941                                                         </xsl:with-param>
3942                                                 </xsl:call-template>
3943                                         </title>
3944                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
3945                                 </titleInfo>
3946                                 <name type="corporate">
3947                                         <xsl:for-each select="marc:subfield[@code='a']">
3948                                                 <namePart>
3949                                                         <xsl:value-of select="."></xsl:value-of>
3950                                                 </namePart>
3951                                         </xsl:for-each>
3952                                         <xsl:for-each select="marc:subfield[@code='b']">
3953                                                 <namePart>
3954                                                         <xsl:value-of select="."></xsl:value-of>
3955                                                 </namePart>
3956                                         </xsl:for-each>
3957                                         <xsl:variable name="tempNamePart">
3958                                                 <xsl:call-template name="specialSubfieldSelect">
3959                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
3960                                                         <xsl:with-param name="axis">t</xsl:with-param>
3961                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
3962                                                 </xsl:call-template>
3963                                         </xsl:variable>
3964                                         <xsl:if test="normalize-space($tempNamePart)">
3965                                                 <namePart>
3966                                                         <xsl:value-of select="$tempNamePart"></xsl:value-of>
3967                                                 </namePart>
3968                                         </xsl:if>
3969                                         <xsl:call-template name="role"></xsl:call-template>
3970                                 </name>
3971                                 <xsl:call-template name="relatedForm"></xsl:call-template>
3972                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
3973                         </relatedItem>
3974                 </xsl:for-each>
3975                 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
3976                         <relatedItem>
3977                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
3978                                 <titleInfo>
3979                                         <title>
3980                                                 <xsl:call-template name="chopPunctuation">
3981                                                         <xsl:with-param name="chopString">
3982                                                                 <xsl:call-template name="specialSubfieldSelect">
3983                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
3984                                                                         <xsl:with-param name="axis">t</xsl:with-param>
3985                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
3986                                                                 </xsl:call-template>
3987                                                         </xsl:with-param>
3988                                                 </xsl:call-template>
3989                                         </title>
3990                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
3991                                 </titleInfo>
3992                                 <name type="conference">
3993                                         <namePart>
3994                                                 <xsl:call-template name="specialSubfieldSelect">
3995                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
3996                                                         <xsl:with-param name="axis">t</xsl:with-param>
3997                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
3998                                                 </xsl:call-template>
3999                                         </namePart>
4000                                 </name>
4001                                 <xsl:call-template name="relatedForm"></xsl:call-template>
4002                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4003                         </relatedItem>
4004                 </xsl:for-each>
4005                 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
4006                         <relatedItem>
4007                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
4008                                 <titleInfo>
4009                                         <title>
4010                                                 <xsl:call-template name="chopPunctuation">
4011                                                         <xsl:with-param name="chopString">
4012                                                                 <xsl:call-template name="subfieldSelect">
4013                                                                         <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
4014                                                                 </xsl:call-template>
4015                                                         </xsl:with-param>
4016                                                 </xsl:call-template>
4017                                         </title>
4018                                         <xsl:call-template name="part"></xsl:call-template>
4019                                 </titleInfo>
4020                                 <xsl:call-template name="relatedForm"></xsl:call-template>
4021                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4022                         </relatedItem>
4023                 </xsl:for-each>
4024                 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
4025                         <relatedItem>
4026                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
4027                                 <xsl:variable name="titleChop">
4028                                         <xsl:call-template name="chopPunctuation">
4029                                                 <xsl:with-param name="chopString">
4030                                                         <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
4031                                                 </xsl:with-param>
4032                                         </xsl:call-template>
4033                                 </xsl:variable>
4034                                 <titleInfo>
4035                                         <title>
4036                                                 <xsl:value-of select="$titleChop" />
4037                                         </title>
4038                                         <xsl:call-template name="part"></xsl:call-template>
4039                                 </titleInfo>
4040                                 <titleInfo type="nfi">
4041                                         <xsl:choose>
4042                                                 <xsl:when test="@ind1>0">
4043                                                         <nonSort>
4044                                                                 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
4045                                                         </nonSort>
4046                                                         <title>
4047                                                                 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
4048                                                         </title>
4049                                                 </xsl:when>
4050                                                 <xsl:otherwise>
4051                                                         <title>
4052                                                                 <xsl:value-of select="$titleChop" />
4053                                                         </title>
4054                                                 </xsl:otherwise>
4055                                         </xsl:choose>
4056                                         <xsl:call-template name="part"></xsl:call-template>
4057                                 </titleInfo>
4058                                 <xsl:call-template name="relatedForm"></xsl:call-template>
4059                         </relatedItem>
4060                 </xsl:for-each>
4061                 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
4062                         <relatedItem type="series">
4063                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4064                         </relatedItem>
4065                 </xsl:for-each>
4066                 <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
4067                         <relatedItem>
4068                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4069                         </relatedItem>
4070                 </xsl:for-each>
4071                 <xsl:for-each select="marc:datafield[@tag=775]">
4072                         <relatedItem type="otherVersion">
4073                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4074                         </relatedItem>
4075                 </xsl:for-each>
4076                 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
4077                         <relatedItem type="constituent">
4078                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4079                         </relatedItem>
4080                 </xsl:for-each>
4081                 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
4082                         <relatedItem type="host">
4083                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4084                         </relatedItem>
4085                 </xsl:for-each>
4086                 <xsl:for-each select="marc:datafield[@tag=776]">
4087                         <relatedItem type="otherFormat">
4088                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4089                         </relatedItem>
4090                 </xsl:for-each>
4091                 <xsl:for-each select="marc:datafield[@tag=780]">
4092                         <relatedItem type="preceding">
4093                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4094                         </relatedItem>
4095                 </xsl:for-each>
4096                 <xsl:for-each select="marc:datafield[@tag=785]">
4097                         <relatedItem type="succeeding">
4098                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4099                         </relatedItem>
4100                 </xsl:for-each>
4101                 <xsl:for-each select="marc:datafield[@tag=786]">
4102                         <relatedItem type="original">
4103                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4104                         </relatedItem>
4105                 </xsl:for-each>
4106                 <xsl:for-each select="marc:datafield[@tag=800]">
4107                         <relatedItem type="series">
4108                                 <titleInfo>
4109                                         <title>
4110                                                 <xsl:call-template name="chopPunctuation">
4111                                                         <xsl:with-param name="chopString">
4112                                                                 <xsl:call-template name="specialSubfieldSelect">
4113                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
4114                                                                         <xsl:with-param name="axis">t</xsl:with-param>
4115                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
4116                                                                 </xsl:call-template>
4117                                                         </xsl:with-param>
4118                                                 </xsl:call-template>
4119                                         </title>
4120                                         <xsl:call-template name="part"></xsl:call-template>
4121                                 </titleInfo>
4122                                 <name type="personal">
4123                                         <namePart>
4124                                                 <xsl:call-template name="chopPunctuation">
4125                                                         <xsl:with-param name="chopString">
4126                                                                 <xsl:call-template name="specialSubfieldSelect">
4127                                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
4128                                                                         <xsl:with-param name="axis">t</xsl:with-param>
4129                                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
4130                                                                 </xsl:call-template>
4131                                                         </xsl:with-param>
4132                                                 </xsl:call-template>
4133                                         </namePart>
4134                                         <xsl:call-template name="termsOfAddress"></xsl:call-template>
4135                                         <xsl:call-template name="nameDate"></xsl:call-template>
4136                                         <xsl:call-template name="role"></xsl:call-template>
4137                                 </name>
4138                                 <xsl:call-template name="relatedForm"></xsl:call-template>
4139                         </relatedItem>
4140                 </xsl:for-each>
4141                 <xsl:for-each select="marc:datafield[@tag=810]">
4142                         <relatedItem type="series">
4143                                 <titleInfo>
4144                                         <title>
4145                                                 <xsl:call-template name="chopPunctuation">
4146                                                         <xsl:with-param name="chopString">
4147                                                                 <xsl:call-template name="specialSubfieldSelect">
4148                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
4149                                                                         <xsl:with-param name="axis">t</xsl:with-param>
4150                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
4151                                                                 </xsl:call-template>
4152                                                         </xsl:with-param>
4153                                                 </xsl:call-template>
4154                                         </title>
4155                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4156                                 </titleInfo>
4157                                 <name type="corporate">
4158                                         <xsl:for-each select="marc:subfield[@code='a']">
4159                                                 <namePart>
4160                                                         <xsl:value-of select="."></xsl:value-of>
4161                                                 </namePart>
4162                                         </xsl:for-each>
4163                                         <xsl:for-each select="marc:subfield[@code='b']">
4164                                                 <namePart>
4165                                                         <xsl:value-of select="."></xsl:value-of>
4166                                                 </namePart>
4167                                         </xsl:for-each>
4168                                         <namePart>
4169                                                 <xsl:call-template name="specialSubfieldSelect">
4170                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
4171                                                         <xsl:with-param name="axis">t</xsl:with-param>
4172                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
4173                                                 </xsl:call-template>
4174                                         </namePart>
4175                                         <xsl:call-template name="role"></xsl:call-template>
4176                                 </name>
4177                                 <xsl:call-template name="relatedForm"></xsl:call-template>
4178                         </relatedItem>
4179                 </xsl:for-each>
4180                 <xsl:for-each select="marc:datafield[@tag=811]">
4181                         <relatedItem type="series">
4182                                 <titleInfo>
4183                                         <title>
4184                                                 <xsl:call-template name="chopPunctuation">
4185                                                         <xsl:with-param name="chopString">
4186                                                                 <xsl:call-template name="specialSubfieldSelect">
4187                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
4188                                                                         <xsl:with-param name="axis">t</xsl:with-param>
4189                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
4190                                                                 </xsl:call-template>
4191                                                         </xsl:with-param>
4192                                                 </xsl:call-template>
4193                                         </title>
4194                                         <xsl:call-template name="relatedPartNumName"/>
4195                                 </titleInfo>
4196                                 <name type="conference">
4197                                         <namePart>
4198                                                 <xsl:call-template name="specialSubfieldSelect">
4199                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
4200                                                         <xsl:with-param name="axis">t</xsl:with-param>
4201                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
4202                                                 </xsl:call-template>
4203                                         </namePart>
4204                                         <xsl:call-template name="role"/>
4205                                 </name>
4206                                 <xsl:call-template name="relatedForm"/>
4207                         </relatedItem>
4208                 </xsl:for-each>
4209                 <xsl:for-each select="marc:datafield[@tag='830']">
4210                         <relatedItem type="series">
4211                                 <xsl:variable name="titleChop">
4212                                         <xsl:call-template name="chopPunctuation">
4213                                                 <xsl:with-param name="chopString">
4214                                                         <xsl:call-template name="subfieldSelect">
4215                                                                 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
4216                                                         </xsl:call-template>
4217                                                 </xsl:with-param>
4218                                         </xsl:call-template>
4219                                 </xsl:variable>
4220                                 <titleInfo>
4221                                         <title>
4222                                                 <xsl:value-of select="$titleChop" />
4223                                         </title>
4224                                         <xsl:call-template name="part"/>
4225                                 </titleInfo>
4226                                 <titleInfo type="nfi">
4227                                         <xsl:choose>
4228                                                 <xsl:when test="@ind2>0">
4229                                                         <nonSort>
4230                                                                 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
4231                                                         </nonSort>
4232                                                         <title>
4233                                                                 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
4234                                                         </title>
4235                                                 </xsl:when>
4236                                                 <xsl:otherwise>
4237                                                         <title>
4238                                                                 <xsl:value-of select="$titleChop" />
4239                                                         </title>
4240                                                 </xsl:otherwise>
4241                                         </xsl:choose>
4242                                         <xsl:call-template name="part"/>
4243                                 </titleInfo>
4244                                 <xsl:call-template name="relatedForm"/>
4245                         </relatedItem>
4246                 </xsl:for-each>
4247                 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
4248                         <relatedItem>
4249                                 <internetMediaType>
4250                                         <xsl:value-of select="."/>
4251                                 </internetMediaType>
4252                         </relatedItem>
4253                 </xsl:for-each>
4254                 <xsl:for-each select="marc:datafield[@tag='020']">
4255                         <xsl:call-template name="isInvalid">
4256                                 <xsl:with-param name="type">isbn</xsl:with-param>
4257                         </xsl:call-template>
4258                         <xsl:if test="marc:subfield[@code='a']">
4259                                 <identifier type="isbn">
4260                                         <xsl:value-of select="marc:subfield[@code='a']"/>
4261                                 </identifier>
4262                         </xsl:if>
4263                 </xsl:for-each>
4264                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
4265                         <xsl:call-template name="isInvalid">
4266                                 <xsl:with-param name="type">isrc</xsl:with-param>
4267                         </xsl:call-template>
4268                         <xsl:if test="marc:subfield[@code='a']">
4269                                 <identifier type="isrc">
4270                                         <xsl:value-of select="marc:subfield[@code='a']"/>
4271                                 </identifier>
4272                         </xsl:if>
4273                 </xsl:for-each>
4274                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
4275                         <xsl:call-template name="isInvalid">
4276                                 <xsl:with-param name="type">ismn</xsl:with-param>
4277                         </xsl:call-template>
4278                         <xsl:if test="marc:subfield[@code='a']">
4279                                 <identifier type="ismn">
4280                                         <xsl:value-of select="marc:subfield[@code='a']"/>
4281                                 </identifier>
4282                         </xsl:if>
4283                 </xsl:for-each>
4284                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
4285                         <xsl:call-template name="isInvalid">
4286                                 <xsl:with-param name="type">sici</xsl:with-param>
4287                         </xsl:call-template>
4288                         <identifier type="sici">
4289                                 <xsl:call-template name="subfieldSelect">
4290                                         <xsl:with-param name="codes">ab</xsl:with-param>
4291                                 </xsl:call-template>
4292                         </identifier>
4293                 </xsl:for-each>
4294                 <xsl:for-each select="marc:datafield[@tag='022']">
4295                         <xsl:call-template name="isInvalid">
4296                                 <xsl:with-param name="type">issn</xsl:with-param>
4297                         </xsl:call-template>
4298                         <identifier type="issn">
4299                                 <xsl:value-of select="marc:subfield[@code='a']"/>
4300                         </identifier>
4301                 </xsl:for-each>
4302                 <xsl:for-each select="marc:datafield[@tag='010']">
4303                         <xsl:call-template name="isInvalid">
4304                                 <xsl:with-param name="type">lccn</xsl:with-param>
4305                         </xsl:call-template>
4306                         <identifier type="lccn">
4307                                 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
4308                         </identifier>
4309                 </xsl:for-each>
4310                 <xsl:for-each select="marc:datafield[@tag='028']">
4311                         <identifier>
4312                                 <xsl:attribute name="type">
4313                                         <xsl:choose>
4314                                                 <xsl:when test="@ind1='0'">issue number</xsl:when>
4315                                                 <xsl:when test="@ind1='1'">matrix number</xsl:when>
4316                                                 <xsl:when test="@ind1='2'">music plate</xsl:when>
4317                                                 <xsl:when test="@ind1='3'">music publisher</xsl:when>
4318                                                 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
4319                                         </xsl:choose>
4320                                 </xsl:attribute>
4321                                 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
4322                                 <xsl:call-template name="subfieldSelect">
4323                                         <xsl:with-param name="codes">
4324                                                 <xsl:choose>
4325                                                         <xsl:when test="@ind1='0'">ba</xsl:when>
4326                                                         <xsl:otherwise>ab</xsl:otherwise>
4327                                                 </xsl:choose>
4328                                         </xsl:with-param>
4329                                 </xsl:call-template>
4330                         </identifier>
4331                 </xsl:for-each>
4332                 <xsl:for-each select="marc:datafield[@tag='037']">
4333                         <identifier type="stock number">
4334                                 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
4335                                 <xsl:call-template name="subfieldSelect">
4336                                         <xsl:with-param name="codes">ab</xsl:with-param>
4337                                 </xsl:call-template>
4338                         </identifier>
4339                 </xsl:for-each>
4340                 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
4341                         <identifier>
4342                                 <xsl:attribute name="type">
4343                                         <xsl:choose>
4344                                                 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
4345                                                 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
4346                                                 <xsl:otherwise>uri</xsl:otherwise>
4347                                         </xsl:choose>
4348                                 </xsl:attribute>
4349                                 <xsl:choose>
4350                                         <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
4351                                                 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
4352                                         </xsl:when>
4353                                         <xsl:otherwise>
4354                                                 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
4355                                         </xsl:otherwise>
4356                                 </xsl:choose>
4357                         </identifier>
4358                         <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
4359                                 <identifier type="hdl">
4360                                         <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
4361                                                 <xsl:attribute name="displayLabel">
4362                                                         <xsl:call-template name="subfieldSelect">
4363                                                                 <xsl:with-param name="codes">y3z</xsl:with-param>
4364                                                         </xsl:call-template>
4365                                                 </xsl:attribute>
4366                                         </xsl:if>
4367                                         <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
4368                                 </identifier>
4369                         </xsl:if>
4370                 </xsl:for-each>
4371                 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
4372                         <identifier type="upc">
4373                                 <xsl:call-template name="isInvalid"/>
4374                                 <xsl:value-of select="marc:subfield[@code='a']"/>
4375                         </identifier>
4376                 </xsl:for-each>
4377                 <!-- 1/04 fix added $y -->
4378                 <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
4379                         <location>
4380                                 <url>
4381                                         <xsl:if test="marc:subfield[@code='y' or @code='3']">
4382                                                 <xsl:attribute name="displayLabel">
4383                                                         <xsl:call-template name="subfieldSelect">
4384                                                                 <xsl:with-param name="codes">y3</xsl:with-param>
4385                                                         </xsl:call-template>
4386                                                 </xsl:attribute>
4387                                         </xsl:if>
4388                                         <xsl:if test="marc:subfield[@code='z' ]">
4389                                                 <xsl:attribute name="note">
4390                                                         <xsl:call-template name="subfieldSelect">
4391                                                                 <xsl:with-param name="codes">z</xsl:with-param>
4392                                                         </xsl:call-template>
4393                                                 </xsl:attribute>
4394                                         </xsl:if>
4395                                         <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
4396
4397                                 </url>
4398                         </location>
4399                 </xsl:for-each>
4400                         
4401                         <!-- 3.2 change tmee 856z  -->
4402
4403                 
4404                 <xsl:for-each select="marc:datafield[@tag=852]">
4405                         <location>
4406                                 <physicalLocation>
4407                                         <xsl:call-template name="displayLabel"></xsl:call-template>
4408                                         <xsl:call-template name="subfieldSelect">
4409                                                 <xsl:with-param name="codes">abje</xsl:with-param>
4410                                         </xsl:call-template>
4411                                 </physicalLocation>
4412                         </location>
4413                 </xsl:for-each>
4414                 <xsl:for-each select="marc:datafield[@tag=506]">
4415                         <accessCondition type="restrictionOnAccess">
4416                                 <xsl:call-template name="subfieldSelect">
4417                                         <xsl:with-param name="codes">abcd35</xsl:with-param>
4418                                 </xsl:call-template>
4419                         </accessCondition>
4420                 </xsl:for-each>
4421                 <xsl:for-each select="marc:datafield[@tag=540]">
4422                         <accessCondition type="useAndReproduction">
4423                                 <xsl:call-template name="subfieldSelect">
4424                                         <xsl:with-param name="codes">abcde35</xsl:with-param>
4425                                 </xsl:call-template>
4426                         </accessCondition>
4427                 </xsl:for-each>
4428                 <recordInfo>
4429                         <xsl:for-each select="marc:datafield[@tag=040]">
4430                                 <recordContentSource authority="marcorg">
4431                                         <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
4432                                 </recordContentSource>
4433                         </xsl:for-each>
4434                         <xsl:for-each select="marc:controlfield[@tag=008]">
4435                                 <recordCreationDate encoding="marc">
4436                                         <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
4437                                 </recordCreationDate>
4438                         </xsl:for-each>
4439                         <xsl:for-each select="marc:controlfield[@tag=005]">
4440                                 <recordChangeDate encoding="iso8601">
4441                                         <xsl:value-of select="."></xsl:value-of>
4442                                 </recordChangeDate>
4443                         </xsl:for-each>
4444                         <xsl:for-each select="marc:controlfield[@tag=001]">
4445                                 <recordIdentifier>
4446                                         <xsl:if test="../marc:controlfield[@tag=003]">
4447                                                 <xsl:attribute name="source">
4448                                                         <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
4449                                                 </xsl:attribute>
4450                                         </xsl:if>
4451                                         <xsl:value-of select="."></xsl:value-of>
4452                                 </recordIdentifier>
4453                         </xsl:for-each>
4454                         <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
4455                                 <languageOfCataloging>
4456                                         <languageTerm authority="iso639-2b" type="code">
4457                                                 <xsl:value-of select="."></xsl:value-of>
4458                                         </languageTerm>
4459                                 </languageOfCataloging>
4460                         </xsl:for-each>
4461                 </recordInfo>
4462         </xsl:template>
4463         <xsl:template name="displayForm">
4464                 <xsl:for-each select="marc:subfield[@code='c']">
4465                         <displayForm>
4466                                 <xsl:value-of select="."></xsl:value-of>
4467                         </displayForm>
4468                 </xsl:for-each>
4469         </xsl:template>
4470         <xsl:template name="affiliation">
4471                 <xsl:for-each select="marc:subfield[@code='u']">
4472                         <affiliation>
4473                                 <xsl:value-of select="."></xsl:value-of>
4474                         </affiliation>
4475                 </xsl:for-each>
4476         </xsl:template>
4477         <xsl:template name="uri">
4478                 <xsl:for-each select="marc:subfield[@code='u']">
4479                         <xsl:attribute name="xlink:href">
4480                                 <xsl:value-of select="."></xsl:value-of>
4481                         </xsl:attribute>
4482                 </xsl:for-each>
4483                 <xsl:for-each select="marc:subfield[@code='0']">
4484                         <xsl:choose>
4485                                 <xsl:when test="contains(text(), ')')">
4486                                         <xsl:attribute name="xlink:href">
4487                                                 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
4488                                         </xsl:attribute>
4489                                 </xsl:when>
4490                                 <xsl:otherwise>
4491                                         <xsl:attribute name="xlink:href">
4492                                                 <xsl:value-of select="."></xsl:value-of>
4493                                         </xsl:attribute>
4494                                 </xsl:otherwise>
4495                         </xsl:choose>
4496                 </xsl:for-each>
4497         </xsl:template>
4498         <xsl:template name="role">
4499                 <xsl:for-each select="marc:subfield[@code='e']">
4500                         <role>
4501                                 <roleTerm type="text">
4502                                         <xsl:value-of select="."></xsl:value-of>
4503                                 </roleTerm>
4504                         </role>
4505                 </xsl:for-each>
4506                 <xsl:for-each select="marc:subfield[@code='4']">
4507                         <role>
4508                                 <roleTerm authority="marcrelator" type="code">
4509                                         <xsl:value-of select="."></xsl:value-of>
4510                                 </roleTerm>
4511                         </role>
4512                 </xsl:for-each>
4513         </xsl:template>
4514         <xsl:template name="part">
4515                 <xsl:variable name="partNumber">
4516                         <xsl:call-template name="specialSubfieldSelect">
4517                                 <xsl:with-param name="axis">n</xsl:with-param>
4518                                 <xsl:with-param name="anyCodes">n</xsl:with-param>
4519                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4520                         </xsl:call-template>
4521                 </xsl:variable>
4522                 <xsl:variable name="partName">
4523                         <xsl:call-template name="specialSubfieldSelect">
4524                                 <xsl:with-param name="axis">p</xsl:with-param>
4525                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
4526                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4527                         </xsl:call-template>
4528                 </xsl:variable>
4529                 <xsl:if test="string-length(normalize-space($partNumber))">
4530                         <partNumber>
4531                                 <xsl:call-template name="chopPunctuation">
4532                                         <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
4533                                 </xsl:call-template>
4534                         </partNumber>
4535                 </xsl:if>
4536                 <xsl:if test="string-length(normalize-space($partName))">
4537                         <partName>
4538                                 <xsl:call-template name="chopPunctuation">
4539                                         <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
4540                                 </xsl:call-template>
4541                         </partName>
4542                 </xsl:if>
4543         </xsl:template>
4544         <xsl:template name="relatedPart">
4545                 <xsl:if test="@tag=773">
4546                         <xsl:for-each select="marc:subfield[@code='g']">
4547                                 <part>
4548                                         <text>
4549                                                 <xsl:value-of select="."></xsl:value-of>
4550                                         </text>
4551                                 </part>
4552                         </xsl:for-each>
4553                         <xsl:for-each select="marc:subfield[@code='q']">
4554                                 <part>
4555                                         <xsl:call-template name="parsePart"></xsl:call-template>
4556                                 </part>
4557                         </xsl:for-each>
4558                 </xsl:if>
4559         </xsl:template>
4560         <xsl:template name="relatedPartNumName">
4561                 <xsl:variable name="partNumber">
4562                         <xsl:call-template name="specialSubfieldSelect">
4563                                 <xsl:with-param name="axis">g</xsl:with-param>
4564                                 <xsl:with-param name="anyCodes">g</xsl:with-param>
4565                                 <xsl:with-param name="afterCodes">pst</xsl:with-param>
4566                         </xsl:call-template>
4567                 </xsl:variable>
4568                 <xsl:variable name="partName">
4569                         <xsl:call-template name="specialSubfieldSelect">
4570                                 <xsl:with-param name="axis">p</xsl:with-param>
4571                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
4572                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4573                         </xsl:call-template>
4574                 </xsl:variable>
4575                 <xsl:if test="string-length(normalize-space($partNumber))">
4576                         <partNumber>
4577                                 <xsl:value-of select="$partNumber"></xsl:value-of>
4578                         </partNumber>
4579                 </xsl:if>
4580                 <xsl:if test="string-length(normalize-space($partName))">
4581                         <partName>
4582                                 <xsl:value-of select="$partName"></xsl:value-of>
4583                         </partName>
4584                 </xsl:if>
4585         </xsl:template>
4586         <xsl:template name="relatedName">
4587                 <xsl:for-each select="marc:subfield[@code='a']">
4588                         <name>
4589                                 <namePart>
4590                                         <xsl:value-of select="."></xsl:value-of>
4591                                 </namePart>
4592                         </name>
4593                 </xsl:for-each>
4594         </xsl:template>
4595         <xsl:template name="relatedForm">
4596                 <xsl:for-each select="marc:subfield[@code='h']">
4597                         <physicalDescription>
4598                                 <form>
4599                                         <xsl:value-of select="."></xsl:value-of>
4600                                 </form>
4601                         </physicalDescription>
4602                 </xsl:for-each>
4603         </xsl:template>
4604         <xsl:template name="relatedExtent">
4605                 <xsl:for-each select="marc:subfield[@code='h']">
4606                         <physicalDescription>
4607                                 <extent>
4608                                         <xsl:value-of select="."></xsl:value-of>
4609                                 </extent>
4610                         </physicalDescription>
4611                 </xsl:for-each>
4612         </xsl:template>
4613         <xsl:template name="relatedNote">
4614                 <xsl:for-each select="marc:subfield[@code='n']">
4615                         <note>
4616                                 <xsl:value-of select="."></xsl:value-of>
4617                         </note>
4618                 </xsl:for-each>
4619         </xsl:template>
4620         <xsl:template name="relatedSubject">
4621                 <xsl:for-each select="marc:subfield[@code='j']">
4622                         <subject>
4623                                 <temporal encoding="iso8601">
4624                                         <xsl:call-template name="chopPunctuation">
4625                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
4626                                         </xsl:call-template>
4627                                 </temporal>
4628                         </subject>
4629                 </xsl:for-each>
4630         </xsl:template>
4631         <xsl:template name="relatedIdentifierISSN">
4632                 <xsl:for-each select="marc:subfield[@code='x']">
4633                         <identifier type="issn">
4634                                 <xsl:value-of select="."></xsl:value-of>
4635                         </identifier>
4636                 </xsl:for-each>
4637         </xsl:template>
4638         <xsl:template name="relatedIdentifierLocal">
4639                 <xsl:for-each select="marc:subfield[@code='w']">
4640                         <identifier type="local">
4641                                 <xsl:value-of select="."></xsl:value-of>
4642                         </identifier>
4643                 </xsl:for-each>
4644         </xsl:template>
4645         <xsl:template name="relatedIdentifier">
4646                 <xsl:for-each select="marc:subfield[@code='o']">
4647                         <identifier>
4648                                 <xsl:value-of select="."></xsl:value-of>
4649                         </identifier>
4650                 </xsl:for-each>
4651         </xsl:template>
4652         <xsl:template name="relatedItem76X-78X">
4653                 <xsl:call-template name="displayLabel"></xsl:call-template>
4654                 <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
4655                 <xsl:call-template name="relatedName"></xsl:call-template>
4656                 <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
4657                 <xsl:call-template name="relatedLanguage"></xsl:call-template>
4658                 <xsl:call-template name="relatedExtent"></xsl:call-template>
4659                 <xsl:call-template name="relatedNote"></xsl:call-template>
4660                 <xsl:call-template name="relatedSubject"></xsl:call-template>
4661                 <xsl:call-template name="relatedIdentifier"></xsl:call-template>
4662                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4663                 <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
4664                 <xsl:call-template name="relatedPart"></xsl:call-template>
4665         </xsl:template>
4666         <xsl:template name="subjectGeographicZ">
4667                 <geographic>
4668                         <xsl:call-template name="chopPunctuation">
4669                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
4670                         </xsl:call-template>
4671                 </geographic>
4672         </xsl:template>
4673         <xsl:template name="subjectTemporalY">
4674                 <temporal>
4675                         <xsl:call-template name="chopPunctuation">
4676                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
4677                         </xsl:call-template>
4678                 </temporal>
4679         </xsl:template>
4680         <xsl:template name="subjectTopic">
4681                 <topic>
4682                         <xsl:call-template name="chopPunctuation">
4683                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
4684                         </xsl:call-template>
4685                 </topic>
4686         </xsl:template> 
4687         <!-- 3.2 change tmee 6xx $v genre -->
4688         <xsl:template name="subjectGenre">
4689                 <genre>
4690                         <xsl:call-template name="chopPunctuation">
4691                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
4692                         </xsl:call-template>
4693                 </genre>
4694         </xsl:template>
4695         
4696         <xsl:template name="nameABCDN">
4697                 <xsl:for-each select="marc:subfield[@code='a']">
4698                         <namePart>
4699                                 <xsl:call-template name="chopPunctuation">
4700                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
4701                                 </xsl:call-template>
4702                         </namePart>
4703                 </xsl:for-each>
4704                 <xsl:for-each select="marc:subfield[@code='b']">
4705                         <namePart>
4706                                 <xsl:value-of select="."></xsl:value-of>
4707                         </namePart>
4708                 </xsl:for-each>
4709                 <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
4710                         <namePart>
4711                                 <xsl:call-template name="subfieldSelect">
4712                                         <xsl:with-param name="codes">cdn</xsl:with-param>
4713                                 </xsl:call-template>
4714                         </namePart>
4715                 </xsl:if>
4716         </xsl:template>
4717         <xsl:template name="nameABCDQ">
4718                 <namePart>
4719                         <xsl:call-template name="chopPunctuation">
4720                                 <xsl:with-param name="chopString">
4721                                         <xsl:call-template name="subfieldSelect">
4722                                                 <xsl:with-param name="codes">aq</xsl:with-param>
4723                                         </xsl:call-template>
4724                                 </xsl:with-param>
4725                                 <xsl:with-param name="punctuation">
4726                                         <xsl:text>:,;/ </xsl:text>
4727                                 </xsl:with-param>
4728                         </xsl:call-template>
4729                 </namePart>
4730                 <xsl:call-template name="termsOfAddress"></xsl:call-template>
4731                 <xsl:call-template name="nameDate"></xsl:call-template>
4732         </xsl:template>
4733         <xsl:template name="nameACDEQ">
4734                 <namePart>
4735                         <xsl:call-template name="subfieldSelect">
4736                                 <xsl:with-param name="codes">acdeq</xsl:with-param>
4737                         </xsl:call-template>
4738                 </namePart>
4739         </xsl:template>
4740         <xsl:template name="constituentOrRelatedType">
4741                 <xsl:if test="@ind2=2">
4742                         <xsl:attribute name="type">constituent</xsl:attribute>
4743                 </xsl:if>
4744         </xsl:template>
4745         <xsl:template name="relatedTitle">
4746                 <xsl:for-each select="marc:subfield[@code='t']">
4747                         <titleInfo>
4748                                 <title>
4749                                         <xsl:call-template name="chopPunctuation">
4750                                                 <xsl:with-param name="chopString">
4751                                                         <xsl:value-of select="."></xsl:value-of>
4752                                                 </xsl:with-param>
4753                                         </xsl:call-template>
4754                                 </title>
4755                         </titleInfo>
4756                 </xsl:for-each>
4757         </xsl:template>
4758         <xsl:template name="relatedTitle76X-78X">
4759                 <xsl:for-each select="marc:subfield[@code='t']">
4760                         <titleInfo>
4761                                 <title>
4762                                         <xsl:call-template name="chopPunctuation">
4763                                                 <xsl:with-param name="chopString">
4764                                                         <xsl:value-of select="."></xsl:value-of>
4765                                                 </xsl:with-param>
4766                                         </xsl:call-template>
4767                                 </title>
4768                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4769                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4770                                 </xsl:if>
4771                         </titleInfo>
4772                 </xsl:for-each>
4773                 <xsl:for-each select="marc:subfield[@code='p']">
4774                         <titleInfo type="abbreviated">
4775                                 <title>
4776                                         <xsl:call-template name="chopPunctuation">
4777                                                 <xsl:with-param name="chopString">
4778                                                         <xsl:value-of select="."></xsl:value-of>
4779                                                 </xsl:with-param>
4780                                         </xsl:call-template>
4781                                 </title>
4782                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4783                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4784                                 </xsl:if>
4785                         </titleInfo>
4786                 </xsl:for-each>
4787                 <xsl:for-each select="marc:subfield[@code='s']">
4788                         <titleInfo type="uniform">
4789                                 <title>
4790                                         <xsl:call-template name="chopPunctuation">
4791                                                 <xsl:with-param name="chopString">
4792                                                         <xsl:value-of select="."></xsl:value-of>
4793                                                 </xsl:with-param>
4794                                         </xsl:call-template>
4795                                 </title>
4796                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4797                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4798                                 </xsl:if>
4799                         </titleInfo>
4800                 </xsl:for-each>
4801         </xsl:template>
4802         <xsl:template name="relatedOriginInfo">
4803                 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
4804                         <originInfo>
4805                                 <xsl:if test="@tag=775">
4806                                         <xsl:for-each select="marc:subfield[@code='f']">
4807                                                 <place>
4808                                                         <placeTerm>
4809                                                                 <xsl:attribute name="type">code</xsl:attribute>
4810                                                                 <xsl:attribute name="authority">marcgac</xsl:attribute>
4811                                                                 <xsl:value-of select="."></xsl:value-of>
4812                                                         </placeTerm>
4813                                                 </place>
4814                                         </xsl:for-each>
4815                                 </xsl:if>
4816                                 <xsl:for-each select="marc:subfield[@code='d']">
4817                                         <publisher>
4818                                                 <xsl:value-of select="."></xsl:value-of>
4819                                         </publisher>
4820                                 </xsl:for-each>
4821                                 <xsl:for-each select="marc:subfield[@code='b']">
4822                                         <edition>
4823                                                 <xsl:value-of select="."></xsl:value-of>
4824                                         </edition>
4825                                 </xsl:for-each>
4826                         </originInfo>
4827                 </xsl:if>
4828         </xsl:template>
4829         <xsl:template name="relatedLanguage">
4830                 <xsl:for-each select="marc:subfield[@code='e']">
4831                         <xsl:call-template name="getLanguage">
4832                                 <xsl:with-param name="langString">
4833                                         <xsl:value-of select="."></xsl:value-of>
4834                                 </xsl:with-param>
4835                         </xsl:call-template>
4836                 </xsl:for-each>
4837         </xsl:template>
4838         <xsl:template name="nameDate">
4839                 <xsl:for-each select="marc:subfield[@code='d']">
4840                         <namePart type="date">
4841                                 <xsl:call-template name="chopPunctuation">
4842                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
4843                                 </xsl:call-template>
4844                         </namePart>
4845                 </xsl:for-each>
4846         </xsl:template>
4847         <xsl:template name="subjectAuthority">
4848                 <xsl:if test="@ind2!=4">
4849                         <xsl:if test="@ind2!=' '">
4850                                 <xsl:if test="@ind2!=8">
4851                                         <xsl:if test="@ind2!=9">
4852                                                 <xsl:attribute name="authority">
4853                                                         <xsl:choose>
4854                                                                 <xsl:when test="@ind2=0">lcsh</xsl:when>
4855                                                                 <xsl:when test="@ind2=1">lcshac</xsl:when>
4856                                                                 <xsl:when test="@ind2=2">mesh</xsl:when>
4857                                                                 <!-- 1/04 fix -->
4858                                                                 <xsl:when test="@ind2=3">nal</xsl:when>
4859                                                                 <xsl:when test="@ind2=5">csh</xsl:when>
4860                                                                 <xsl:when test="@ind2=6">rvm</xsl:when>
4861                                                                 <xsl:when test="@ind2=7">
4862                                                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
4863                                                                 </xsl:when>
4864                                                         </xsl:choose>
4865                                                 </xsl:attribute>
4866                                         </xsl:if>
4867                                 </xsl:if>
4868                         </xsl:if>
4869                 </xsl:if>
4870         </xsl:template>
4871         <xsl:template name="subjectAnyOrder">
4872                 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
4873                         <xsl:choose>
4874                                 <xsl:when test="@code='v'">
4875                                         <xsl:call-template name="subjectGenre"></xsl:call-template>
4876                                 </xsl:when>
4877                                 <xsl:when test="@code='x'">
4878                                         <xsl:call-template name="subjectTopic"></xsl:call-template>
4879                                 </xsl:when>
4880                                 <xsl:when test="@code='y'">
4881                                         <xsl:call-template name="subjectTemporalY"></xsl:call-template>
4882                                 </xsl:when>
4883                                 <xsl:when test="@code='z'">
4884                                         <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
4885                                 </xsl:when>
4886                         </xsl:choose>
4887                 </xsl:for-each>
4888         </xsl:template>
4889         <xsl:template name="specialSubfieldSelect">
4890                 <xsl:param name="anyCodes"></xsl:param>
4891                 <xsl:param name="axis"></xsl:param>
4892                 <xsl:param name="beforeCodes"></xsl:param>
4893                 <xsl:param name="afterCodes"></xsl:param>
4894                 <xsl:variable name="str">
4895                         <xsl:for-each select="marc:subfield">
4896                                 <xsl:if test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
4897                                         <xsl:value-of select="text()"></xsl:value-of>
4898                                         <xsl:text> </xsl:text>
4899                                 </xsl:if>
4900                         </xsl:for-each>
4901                 </xsl:variable>
4902                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
4903         </xsl:template>
4904         
4905         <!-- 3.2 change tmee 6xx $v genre -->
4906         <xsl:template match="marc:datafield[@tag=600]">
4907                 <subject>
4908                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
4909                         <name type="personal">
4910                                 <xsl:call-template name="uri" />
4911                                 <xsl:call-template name="termsOfAddress"></xsl:call-template>
4912                                 <namePart>
4913                                         <xsl:call-template name="chopPunctuation">
4914                                                 <xsl:with-param name="chopString">
4915                                                         <xsl:call-template name="subfieldSelect">
4916                                                                 <xsl:with-param name="codes">aq</xsl:with-param>
4917                                                         </xsl:call-template>
4918                                                 </xsl:with-param>
4919                                         </xsl:call-template>
4920                                 </namePart>
4921                                 <xsl:call-template name="nameDate"></xsl:call-template>
4922                                 <xsl:call-template name="affiliation"></xsl:call-template>
4923                                 <xsl:call-template name="role"></xsl:call-template>
4924                         </name>
4925                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
4926                 </subject>
4927         </xsl:template>
4928         <xsl:template match="marc:datafield[@tag=610]">
4929                 <subject>
4930                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
4931                         <name type="corporate">
4932                                 <xsl:call-template name="uri" />
4933                                 <xsl:for-each select="marc:subfield[@code='a']">
4934                                         <namePart>
4935                                                 <xsl:value-of select="."></xsl:value-of>
4936                                         </namePart>
4937                                 </xsl:for-each>
4938                                 <xsl:for-each select="marc:subfield[@code='b']">
4939                                         <namePart>
4940                                                 <xsl:value-of select="."></xsl:value-of>
4941                                         </namePart>
4942                                 </xsl:for-each>
4943                                 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
4944                                         <namePart>
4945                                                 <xsl:call-template name="subfieldSelect">
4946                                                         <xsl:with-param name="codes">cdnp</xsl:with-param>
4947                                                 </xsl:call-template>
4948                                         </namePart>
4949                                 </xsl:if>
4950                                 <xsl:call-template name="role"></xsl:call-template>
4951                         </name>
4952                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
4953                 </subject>
4954         </xsl:template>
4955         <xsl:template match="marc:datafield[@tag=611]">
4956                 <subject>
4957                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
4958                         <name type="conference">
4959                                 <xsl:call-template name="uri" />
4960                                 <namePart>
4961                                         <xsl:call-template name="subfieldSelect">
4962                                                 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
4963                                         </xsl:call-template>
4964                                 </namePart>
4965                                 <xsl:for-each select="marc:subfield[@code='4']">
4966                                         <role>
4967                                                 <roleTerm authority="marcrelator" type="code">
4968                                                         <xsl:value-of select="."></xsl:value-of>
4969                                                 </roleTerm>
4970                                         </role>
4971                                 </xsl:for-each>
4972                         </name>
4973                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
4974                 </subject>
4975         </xsl:template>
4976         <xsl:template match="marc:datafield[@tag=630]">
4977                 <subject>
4978                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
4979                         <xsl:variable name="titleChop">
4980                                 <xsl:call-template name="chopPunctuation">
4981                                         <xsl:with-param name="chopString">
4982                                                 <xsl:call-template name="subfieldSelect">
4983                                                         <xsl:with-param name="codes">adfhklor</xsl:with-param>
4984                                                 </xsl:call-template>
4985                                         </xsl:with-param>
4986                                 </xsl:call-template>
4987                         </xsl:variable>
4988                         <titleInfo>
4989                                 <title>
4990                                         <xsl:value-of select="$titleChop" />
4991                                 </title>
4992                                 <xsl:call-template name="part"></xsl:call-template>
4993                         </titleInfo>
4994                         <titleInfo type="nfi">
4995                                 <xsl:choose>
4996                                         <xsl:when test="@ind1>0">
4997                                                 <nonSort>
4998                                                         <xsl:value-of select="substring($titleChop,1,@ind1)"/>
4999                                                 </nonSort>
5000                                                 <title>
5001                                                         <xsl:value-of select="substring($titleChop,@ind1+1)"/>
5002                                                 </title>
5003                                                 <xsl:call-template name="part"/>
5004                                         </xsl:when>
5005                                         <xsl:otherwise>
5006                                                 <title>
5007                                                         <xsl:value-of select="$titleChop" />
5008                                                 </title>
5009                                         </xsl:otherwise>
5010                                 </xsl:choose>
5011                                 <xsl:call-template name="part"></xsl:call-template>
5012                         </titleInfo>
5013                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5014                 </subject>
5015         </xsl:template>
5016         <xsl:template match="marc:datafield[@tag=650]">
5017                 <subject>
5018                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
5019                         <topic>
5020                                 <xsl:call-template name="uri" />
5021                                 <xsl:call-template name="chopPunctuation">
5022                                         <xsl:with-param name="chopString">
5023                                                 <xsl:call-template name="subfieldSelect">
5024                                                         <xsl:with-param name="codes">abcd</xsl:with-param>
5025                                                 </xsl:call-template>
5026                                         </xsl:with-param>
5027                                 </xsl:call-template>
5028                         </topic>
5029                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5030                 </subject>
5031         </xsl:template>
5032         <xsl:template match="marc:datafield[@tag=651]">
5033                 <subject>
5034                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
5035                         <xsl:for-each select="marc:subfield[@code='a']">
5036                                 <geographic>
5037                                         <xsl:call-template name="uri" />
5038                                         <xsl:call-template name="chopPunctuation">
5039                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
5040                                         </xsl:call-template>
5041                                 </geographic>
5042                         </xsl:for-each>
5043                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5044                 </subject>
5045         </xsl:template>
5046         <xsl:template match="marc:datafield[@tag=653]">
5047                 <subject>
5048                         <xsl:for-each select="marc:subfield[@code='a']">
5049                                 <topic>
5050                                         <xsl:call-template name="uri" />
5051                                         <xsl:value-of select="."></xsl:value-of>
5052                                 </topic>
5053                         </xsl:for-each>
5054                 </subject>
5055         </xsl:template>
5056         <xsl:template match="marc:datafield[@tag=656]">
5057                 <subject>
5058                         <xsl:if test="marc:subfield[@code=2]">
5059                                 <xsl:attribute name="authority">
5060                                         <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
5061                                 </xsl:attribute>
5062                         </xsl:if>
5063                         <occupation>
5064                                 <xsl:call-template name="uri" />
5065                                 <xsl:call-template name="chopPunctuation">
5066                                         <xsl:with-param name="chopString">
5067                                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
5068                                         </xsl:with-param>
5069                                 </xsl:call-template>
5070                         </occupation>
5071                 </subject>
5072         </xsl:template>
5073         <xsl:template name="termsOfAddress">
5074                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
5075                         <namePart type="termsOfAddress">
5076                                 <xsl:call-template name="chopPunctuation">
5077                                         <xsl:with-param name="chopString">
5078                                                 <xsl:call-template name="subfieldSelect">
5079                                                         <xsl:with-param name="codes">bc</xsl:with-param>
5080                                                 </xsl:call-template>
5081                                         </xsl:with-param>
5082                                 </xsl:call-template>
5083                         </namePart>
5084                 </xsl:if>
5085         </xsl:template>
5086         <xsl:template name="displayLabel">
5087                 <xsl:if test="marc:subfield[@code='i']">
5088                         <xsl:attribute name="displayLabel">
5089                                 <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
5090                         </xsl:attribute>
5091                 </xsl:if>
5092                 <xsl:if test="marc:subfield[@code='3']">
5093                         <xsl:attribute name="displayLabel">
5094                                 <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
5095                         </xsl:attribute>
5096                 </xsl:if>
5097         </xsl:template>
5098         <xsl:template name="isInvalid">
5099                 <xsl:param name="type"/>
5100                 <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
5101                         <identifier>
5102                                 <xsl:attribute name="type">
5103                                         <xsl:value-of select="$type"/>
5104                                 </xsl:attribute>
5105                                 <xsl:attribute name="invalid">
5106                                         <xsl:text>yes</xsl:text>
5107                                 </xsl:attribute>
5108                                 <xsl:if test="marc:subfield[@code='z']">
5109                                         <xsl:value-of select="marc:subfield[@code='z']"/>
5110                                 </xsl:if>
5111                                 <xsl:if test="marc:subfield[@code='y']">
5112                                         <xsl:value-of select="marc:subfield[@code='y']"/>
5113                                 </xsl:if>
5114                         </identifier>
5115                 </xsl:if>
5116         </xsl:template>
5117         <xsl:template name="subtitle">
5118                 <xsl:if test="marc:subfield[@code='b']">
5119                         <subTitle>
5120                                 <xsl:call-template name="chopPunctuation">
5121                                         <xsl:with-param name="chopString">
5122                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
5123                                                 <!--<xsl:call-template name="subfieldSelect">
5124                                                         <xsl:with-param name="codes">b</xsl:with-param>                                                                 
5125                                                 </xsl:call-template>-->
5126                                         </xsl:with-param>
5127                                 </xsl:call-template>
5128                         </subTitle>
5129                 </xsl:if>
5130         </xsl:template>
5131         <xsl:template name="script">
5132                 <xsl:param name="scriptCode"></xsl:param>
5133                 <xsl:attribute name="script">
5134                         <xsl:choose>
5135                                 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
5136                                 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
5137                                 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
5138                                 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
5139                                 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
5140                                 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
5141                         </xsl:choose>
5142                 </xsl:attribute>
5143         </xsl:template>
5144         <xsl:template name="parsePart">
5145                 <!-- assumes 773$q= 1:2:3<4
5146                      with up to 3 levels and one optional start page
5147                 -->
5148                 <xsl:variable name="level1">
5149                         <xsl:choose>
5150                                 <xsl:when test="contains(text(),':')">
5151                                         <!-- 1:2 -->
5152                                         <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
5153                                 </xsl:when>
5154                                 <xsl:when test="not(contains(text(),':'))">
5155                                         <!-- 1 or 1<3 -->
5156                                         <xsl:if test="contains(text(),'&lt;')">
5157                                                 <!-- 1<3 -->
5158                                                 <xsl:value-of select="substring-before(text(),'&lt;')"></xsl:value-of>
5159                                         </xsl:if>
5160                                         <xsl:if test="not(contains(text(),'&lt;'))">
5161                                                 <!-- 1 -->
5162                                                 <xsl:value-of select="text()"></xsl:value-of>
5163                                         </xsl:if>
5164                                 </xsl:when>
5165                         </xsl:choose>
5166                 </xsl:variable>
5167                 <xsl:variable name="sici2">
5168                         <xsl:choose>
5169                                 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
5170                                         <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
5171                                 </xsl:when>
5172                                 <xsl:otherwise>
5173                                         <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
5174                                 </xsl:otherwise>
5175                         </xsl:choose>
5176                 </xsl:variable>
5177                 <xsl:variable name="level2">
5178                         <xsl:choose>
5179                                 <xsl:when test="contains($sici2,':')">
5180                                         <!--  2:3<4  -->
5181                                         <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
5182                                 </xsl:when>
5183                                 <xsl:when test="contains($sici2,'&lt;')">
5184                                         <!-- 1: 2<4 -->
5185                                         <xsl:value-of select="substring-before($sici2,'&lt;')"></xsl:value-of>
5186                                 </xsl:when>
5187                                 <xsl:otherwise>
5188                                         <xsl:value-of select="$sici2"></xsl:value-of>
5189                                         <!-- 1:2 -->
5190                                 </xsl:otherwise>
5191                         </xsl:choose>
5192                 </xsl:variable>
5193                 <xsl:variable name="sici3">
5194                         <xsl:choose>
5195                                 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
5196                                         <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
5197                                 </xsl:when>
5198                                 <xsl:otherwise>
5199                                         <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
5200                                 </xsl:otherwise>
5201                         </xsl:choose>
5202                 </xsl:variable>
5203                 <xsl:variable name="level3">
5204                         <xsl:choose>
5205                                 <xsl:when test="contains($sici3,'&lt;')">
5206                                         <!-- 2<4 -->
5207                                         <xsl:value-of select="substring-before($sici3,'&lt;')"></xsl:value-of>
5208                                 </xsl:when>
5209                                 <xsl:otherwise>
5210                                         <xsl:value-of select="$sici3"></xsl:value-of>
5211                                         <!-- 3 -->
5212                                 </xsl:otherwise>
5213                         </xsl:choose>
5214                 </xsl:variable>
5215                 <xsl:variable name="page">
5216                         <xsl:if test="contains(text(),'&lt;')">
5217                                 <xsl:value-of select="substring-after(text(),'&lt;')"></xsl:value-of>
5218                         </xsl:if>
5219                 </xsl:variable>
5220                 <xsl:if test="$level1">
5221                         <detail level="1">
5222                                 <number>
5223                                         <xsl:value-of select="$level1"></xsl:value-of>
5224                                 </number>
5225                         </detail>
5226                 </xsl:if>
5227                 <xsl:if test="$level2">
5228                         <detail level="2">
5229                                 <number>
5230                                         <xsl:value-of select="$level2"></xsl:value-of>
5231                                 </number>
5232                         </detail>
5233                 </xsl:if>
5234                 <xsl:if test="$level3">
5235                         <detail level="3">
5236                                 <number>
5237                                         <xsl:value-of select="$level3"></xsl:value-of>
5238                                 </number>
5239                         </detail>
5240                 </xsl:if>
5241                 <xsl:if test="$page">
5242                         <extent unit="page">
5243                                 <start>
5244                                         <xsl:value-of select="$page"></xsl:value-of>
5245                                 </start>
5246                         </extent>
5247                 </xsl:if>
5248         </xsl:template>
5249         <xsl:template name="getLanguage">
5250                 <xsl:param name="langString"></xsl:param>
5251                 <xsl:param name="controlField008-35-37"></xsl:param>
5252                 <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
5253                 <xsl:choose>
5254                         <xsl:when test="$length=0"></xsl:when>
5255                         <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
5256                                 <xsl:call-template name="getLanguage">
5257                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
5258                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
5259                                 </xsl:call-template>
5260                         </xsl:when>
5261                         <xsl:otherwise>
5262                                 <language>
5263                                         <languageTerm authority="iso639-2b" type="code">
5264                                                 <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
5265                                         </languageTerm>
5266                                 </language>
5267                                 <xsl:call-template name="getLanguage">
5268                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
5269                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
5270                                 </xsl:call-template>
5271                         </xsl:otherwise>
5272                 </xsl:choose>
5273         </xsl:template>
5274         <xsl:template name="isoLanguage">
5275                 <xsl:param name="currentLanguage"></xsl:param>
5276                 <xsl:param name="usedLanguages"></xsl:param>
5277                 <xsl:param name="remainingLanguages"></xsl:param>
5278                 <xsl:choose>
5279                         <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
5280                         <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
5281                                 <language>
5282                                         <xsl:if test="@code!='a'">
5283                                                 <xsl:attribute name="objectPart">
5284                                                         <xsl:choose>
5285                                                                 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
5286                                                                 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
5287                                                                 <xsl:when test="@code='e'">libretto</xsl:when>
5288                                                                 <xsl:when test="@code='f'">table of contents</xsl:when>
5289                                                                 <xsl:when test="@code='g'">accompanying material</xsl:when>
5290                                                                 <xsl:when test="@code='h'">translation</xsl:when>
5291                                                         </xsl:choose>
5292                                                 </xsl:attribute>
5293                                         </xsl:if>
5294                                         <languageTerm authority="iso639-2b" type="code">
5295                                                 <xsl:value-of select="$currentLanguage"></xsl:value-of>
5296                                         </languageTerm>
5297                                 </language>
5298                                 <xsl:call-template name="isoLanguage">
5299                                         <xsl:with-param name="currentLanguage">
5300                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
5301                                         </xsl:with-param>
5302                                         <xsl:with-param name="usedLanguages">
5303                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
5304                                         </xsl:with-param>
5305                                         <xsl:with-param name="remainingLanguages">
5306                                                 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
5307                                         </xsl:with-param>
5308                                 </xsl:call-template>
5309                         </xsl:when>
5310                         <xsl:otherwise>
5311                                 <xsl:call-template name="isoLanguage">
5312                                         <xsl:with-param name="currentLanguage">
5313                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
5314                                         </xsl:with-param>
5315                                         <xsl:with-param name="usedLanguages">
5316                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
5317                                         </xsl:with-param>
5318                                         <xsl:with-param name="remainingLanguages">
5319                                                 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
5320                                         </xsl:with-param>
5321                                 </xsl:call-template>
5322                         </xsl:otherwise>
5323                 </xsl:choose>
5324         </xsl:template>
5325         <xsl:template name="chopBrackets">
5326                 <xsl:param name="chopString"></xsl:param>
5327                 <xsl:variable name="string">
5328                         <xsl:call-template name="chopPunctuation">
5329                                 <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
5330                         </xsl:call-template>
5331                 </xsl:variable>
5332                 <xsl:if test="substring($string, 1,1)='['">
5333                         <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
5334                 </xsl:if>
5335                 <xsl:if test="substring($string, 1,1)!='['">
5336                         <xsl:value-of select="$string"></xsl:value-of>
5337                 </xsl:if>
5338         </xsl:template>
5339         <xsl:template name="rfcLanguages">
5340                 <xsl:param name="nodeNum"></xsl:param>
5341                 <xsl:param name="usedLanguages"></xsl:param>
5342                 <xsl:param name="controlField008-35-37"></xsl:param>
5343                 <xsl:variable name="currentLanguage" select="."></xsl:variable>
5344                 <xsl:choose>
5345                         <xsl:when test="not($currentLanguage)"></xsl:when>
5346                         <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
5347                                 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
5348                                         <language>
5349                                                 <xsl:if test="@code!='a'">
5350                                                         <xsl:attribute name="objectPart">
5351                                                                 <xsl:choose>
5352                                                                         <xsl:when test="@code='b'">summary or subtitle</xsl:when>
5353                                                                         <xsl:when test="@code='d'">sung or spoken text</xsl:when>
5354                                                                         <xsl:when test="@code='e'">libretto</xsl:when>
5355                                                                         <xsl:when test="@code='f'">table of contents</xsl:when>
5356                                                                         <xsl:when test="@code='g'">accompanying material</xsl:when>
5357                                                                         <xsl:when test="@code='h'">translation</xsl:when>
5358                                                                 </xsl:choose>
5359                                                         </xsl:attribute>
5360                                                 </xsl:if>
5361                                                 <languageTerm authority="rfc3066" type="code">
5362                                                         <xsl:value-of select="$currentLanguage"/>
5363                                                 </languageTerm>
5364                                         </language>
5365                                 </xsl:if>
5366                         </xsl:when>
5367                         <xsl:otherwise>
5368                         </xsl:otherwise>
5369                 </xsl:choose>
5370         </xsl:template>
5371         <xsl:template name="datafield">
5372                 <xsl:param name="tag"/>
5373                 <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
5374                 <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
5375                 <xsl:param name="subfields"/>
5376                 <xsl:element name="marc:datafield">
5377                         <xsl:attribute name="tag">
5378                                 <xsl:value-of select="$tag"/>
5379                         </xsl:attribute>
5380                         <xsl:attribute name="ind1">
5381                                 <xsl:value-of select="$ind1"/>
5382                         </xsl:attribute>
5383                         <xsl:attribute name="ind2">
5384                                 <xsl:value-of select="$ind2"/>
5385                         </xsl:attribute>
5386                         <xsl:copy-of select="$subfields"/>
5387                 </xsl:element>
5388         </xsl:template>
5389
5390         <xsl:template name="subfieldSelect">
5391                 <xsl:param name="codes"/>
5392                 <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
5393                 <xsl:variable name="str">
5394                         <xsl:for-each select="marc:subfield">
5395                                 <xsl:if test="contains($codes, @code)">
5396                                         <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
5397                                 </xsl:if>
5398                         </xsl:for-each>
5399                 </xsl:variable>
5400                 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
5401         </xsl:template>
5402
5403         <xsl:template name="buildSpaces">
5404                 <xsl:param name="spaces"/>
5405                 <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
5406                 <xsl:if test="$spaces>0">
5407                         <xsl:value-of select="$char"/>
5408                         <xsl:call-template name="buildSpaces">
5409                                 <xsl:with-param name="spaces" select="$spaces - 1"/>
5410                                 <xsl:with-param name="char" select="$char"/>
5411                         </xsl:call-template>
5412                 </xsl:if>
5413         </xsl:template>
5414
5415         <xsl:template name="chopPunctuation">
5416                 <xsl:param name="chopString"/>
5417                 <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
5418                 <xsl:variable name="length" select="string-length($chopString)"/>
5419                 <xsl:choose>
5420                         <xsl:when test="$length=0"/>
5421                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
5422                                 <xsl:call-template name="chopPunctuation">
5423                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
5424                                         <xsl:with-param name="punctuation" select="$punctuation"/>
5425                                 </xsl:call-template>
5426                         </xsl:when>
5427                         <xsl:when test="not($chopString)"/>
5428                         <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
5429                 </xsl:choose>
5430         </xsl:template>
5431
5432         <xsl:template name="chopPunctuationFront">
5433                 <xsl:param name="chopString"/>
5434                 <xsl:variable name="length" select="string-length($chopString)"/>
5435                 <xsl:choose>
5436                         <xsl:when test="$length=0"/>
5437                         <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
5438                                 <xsl:call-template name="chopPunctuationFront">
5439                                         <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
5440                                 </xsl:call-template>
5441                         </xsl:when>
5442                         <xsl:when test="not($chopString)"/>
5443                         <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
5444                 </xsl:choose>
5445         </xsl:template>
5446 </xsl:stylesheet>$$ WHERE name = 'mods32';
5447
5448
5449 -- 954.data.MODS33-xsl.sql
5450 UPDATE config.xml_transform SET xslt=$$<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim"
5451         xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5452         exclude-result-prefixes="xlink marc" version="1.0">
5453         <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
5454
5455         <xsl:variable name="ascii">
5456                 <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
5457         </xsl:variable>
5458
5459         <xsl:variable name="latin1">
5460                 <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
5461         </xsl:variable>
5462         <!-- Characters that usually don't need to be escaped -->
5463         <xsl:variable name="safe">
5464                 <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
5465         </xsl:variable>
5466
5467         <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
5468
5469     <!-- Evergreen specific: revert Revision 1.23, so we can have those authority xlink attributes back. -->
5470
5471         <!--MARC21slim2MODS3-3.xsl
5472 Revision 1.27 - Mapped 648 to <subject> 2009/03/13 tmee
5473 Revision 1.26 - Added subfield $s mapping for 130/240/730  2008/10/16 tmee
5474 Revision 1.25 - Mapped 040e to <descriptiveStandard> and Leader/18 to <descriptive standard>aacr2  2008/09/18 tmee
5475 Revision 1.24 - Mapped 852 subfields $h, $i, $j, $k, $l, $m, $t to <shelfLocation> and 852 subfield $u to <physicalLocation> with @xlink 2008/09/17 tmee
5476 Revision 1.23 - Commented out xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711 as these are currently unactionable  2008/09/17  tmee
5477 Revision 1.22 - Mapped 022 subfield $l to type "issn-l" subfield $m to output identifier element with corresponding @type and @invalid eq 'yes'2008/09/17  tmee
5478 Revision 1.21 - Mapped 856 ind2=1 or ind2=2 to <relatedItem><location><url>  2008/07/03  tmee
5479 Revision 1.20 - Added genre w/@auth="contents of 2" and type= "musical composition"  2008/07/01  tmee
5480 Revision 1.19 - Added genre offprint for 008/24+ BK code 2  2008/07/01  tmee
5481 Revision 1.18 - Added xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711  2008/06/26  tmee
5482 Revision 1.17 - Added mapping of 662 2008/05/14 tmee    
5483 Revision 1.16 - Changed @authority from "marc" to "marcgt" for 007 and 008 codes mapped to a term in <genre> 2007/07/10  tmee
5484 Revision 1.15 - For field 630, moved call to part template outside title element  2007/07/10  tmee
5485 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
5486 Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28  tmee
5487 Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11  tmee
5488 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>  2006/04/08  jrad
5489 Revision 1.10 - MODS 3.1 revisions to language and classification elements  (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)  2006/02/06  ggar
5490 Revision 1.9 - Subfield $y was added to field 242 2004/09/02 10:57 jrad
5491 Revision 1.8 - Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
5492 Revision 1.7 - 2004/03/25 08:29 jrad
5493 Revision 1.6 - Various validation fixes 2004/02/20 ntra
5494 Revision 1.5 - MODS2 to MODS3 updates, language unstacking and de-duping, chopPunctuation expanded  2003/10/02 16:18:58  ntra
5495 Revision 1.3 - Additional Changes not related to MODS Version 2.0 by ntra
5496 Revision 1.2 - Added Log Comment  2003/03/24 19:37:42  ckeith
5497 -->
5498         <xsl:template match="/">
5499                 <xsl:choose>
5500                         <xsl:when test="//marc:collection">
5501                                 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5502                                         xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
5503                                         <xsl:for-each select="//marc:collection/marc:record">
5504                                                 <mods version="3.3">
5505                                                         <xsl:call-template name="marcRecord"/>
5506                                                 </mods>
5507                                         </xsl:for-each>
5508                                 </modsCollection>
5509                         </xsl:when>
5510                         <xsl:otherwise>
5511                                 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
5512                                         xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
5513                                         <xsl:for-each select="//marc:record">
5514                                                 <xsl:call-template name="marcRecord"/>
5515                                         </xsl:for-each>
5516                                 </mods>
5517                         </xsl:otherwise>
5518                 </xsl:choose>
5519         </xsl:template>
5520         <xsl:template name="marcRecord">
5521                 <xsl:variable name="leader" select="marc:leader"/>
5522                 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
5523                 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
5524                 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
5525                 <xsl:variable name="typeOf008">
5526                         <xsl:choose>
5527                                 <xsl:when test="$leader6='a'">
5528                                         <xsl:choose>
5529                                                 <xsl:when
5530                                                         test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
5531                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
5532                                         </xsl:choose>
5533                                 </xsl:when>
5534                                 <xsl:when test="$leader6='t'">BK</xsl:when>
5535                                 <xsl:when test="$leader6='p'">MM</xsl:when>
5536                                 <xsl:when test="$leader6='m'">CF</xsl:when>
5537                                 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
5538                                 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
5539                                 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'"
5540                                 >MU</xsl:when>
5541                         </xsl:choose>
5542                 </xsl:variable>
5543                 <xsl:for-each select="marc:datafield[@tag='245']">
5544                         <titleInfo>
5545                                 <xsl:variable name="title">
5546                                         <xsl:choose>
5547                                                 <xsl:when test="marc:subfield[@code='b']">
5548                                                         <xsl:call-template name="specialSubfieldSelect">
5549                                                                 <xsl:with-param name="axis">b</xsl:with-param>
5550                                                                 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
5551                                                         </xsl:call-template>
5552                                                 </xsl:when>
5553                                                 <xsl:otherwise>
5554                                                         <xsl:call-template name="subfieldSelect">
5555                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
5556                                                         </xsl:call-template>
5557                                                 </xsl:otherwise>
5558                                         </xsl:choose>
5559                                 </xsl:variable>
5560                                 <xsl:variable name="titleChop">
5561                                         <xsl:call-template name="chopPunctuation">
5562                                                 <xsl:with-param name="chopString">
5563                                                         <xsl:value-of select="$title"/>
5564                                                 </xsl:with-param>
5565                                         </xsl:call-template>
5566                                 </xsl:variable>
5567                                 <xsl:choose>
5568                                         <xsl:when test="@ind2&gt;0">
5569                                                 <nonSort>
5570                                                         <xsl:value-of select="substring($titleChop,1,@ind2)"/>
5571                                                 </nonSort>
5572                                                 <title>
5573                                                         <xsl:value-of select="substring($titleChop,@ind2+1)"/>
5574                                                 </title>
5575                                         </xsl:when>
5576                                         <xsl:otherwise>
5577                                                 <title>
5578                                                         <xsl:value-of select="$titleChop"/>
5579                                                 </title>
5580                                         </xsl:otherwise>
5581                                 </xsl:choose>
5582                                 <xsl:if test="marc:subfield[@code='b']">
5583                                         <subTitle>
5584                                                 <xsl:call-template name="chopPunctuation">
5585                                                         <xsl:with-param name="chopString">
5586                                                                 <xsl:call-template name="specialSubfieldSelect">
5587                                                                         <xsl:with-param name="axis">b</xsl:with-param>
5588                                                                         <xsl:with-param name="anyCodes">b</xsl:with-param>
5589                                                                         <xsl:with-param name="afterCodes">afgk</xsl:with-param>
5590                                                                 </xsl:call-template>
5591                                                         </xsl:with-param>
5592                                                 </xsl:call-template>
5593                                         </subTitle>
5594                                 </xsl:if>
5595                                 <xsl:call-template name="part"/>
5596                         </titleInfo>
5597                 </xsl:for-each>
5598                 <xsl:for-each select="marc:datafield[@tag='210']">
5599                         <titleInfo type="abbreviated">
5600                                 <title>
5601                                         <xsl:call-template name="chopPunctuation">
5602                                                 <xsl:with-param name="chopString">
5603                                                         <xsl:call-template name="subfieldSelect">
5604                                                                 <xsl:with-param name="codes">a</xsl:with-param>
5605                                                         </xsl:call-template>
5606                                                 </xsl:with-param>
5607                                         </xsl:call-template>
5608                                 </title>
5609                                 <xsl:call-template name="subtitle"/>
5610                         </titleInfo>
5611                 </xsl:for-each>
5612                 <xsl:for-each select="marc:datafield[@tag='242']">
5613                         <titleInfo type="translated">
5614                                 <!--09/01/04 Added subfield $y-->
5615                                 <xsl:for-each select="marc:subfield[@code='y']">
5616                                         <xsl:attribute name="lang">
5617                                                 <xsl:value-of select="text()"/>
5618                                         </xsl:attribute>
5619                                 </xsl:for-each>
5620                                 <xsl:for-each select="marc:subfield[@code='i']">
5621                                         <xsl:attribute name="displayLabel">
5622                                                 <xsl:value-of select="text()"/>
5623                                         </xsl:attribute>
5624                                 </xsl:for-each>
5625                                 <title>
5626                                         <xsl:call-template name="chopPunctuation">
5627                                                 <xsl:with-param name="chopString">
5628                                                         <xsl:call-template name="subfieldSelect">
5629                                                                 <!-- 1/04 removed $h, b -->
5630                                                                 <xsl:with-param name="codes">a</xsl:with-param>
5631                                                         </xsl:call-template>
5632                                                 </xsl:with-param>
5633                                         </xsl:call-template>
5634                                 </title>
5635                                 <!-- 1/04 fix -->
5636                                 <xsl:call-template name="subtitle"/>
5637                                 <xsl:call-template name="part"/>
5638                         </titleInfo>
5639                 </xsl:for-each>
5640                 <xsl:for-each select="marc:datafield[@tag='246']">
5641                         <titleInfo type="alternative">
5642                                 <xsl:for-each select="marc:subfield[@code='i']">
5643                                         <xsl:attribute name="displayLabel">
5644                                                 <xsl:value-of select="text()"/>
5645                                         </xsl:attribute>
5646                                 </xsl:for-each>
5647                                 <title>
5648                                         <xsl:call-template name="chopPunctuation">
5649                                                 <xsl:with-param name="chopString">
5650                                                         <xsl:call-template name="subfieldSelect">
5651                                                                 <!-- 1/04 removed $h, $b -->
5652                                                                 <xsl:with-param name="codes">af</xsl:with-param>
5653                                                         </xsl:call-template>
5654                                                 </xsl:with-param>
5655                                         </xsl:call-template>
5656                                 </title>
5657                                 <xsl:call-template name="subtitle"/>
5658                                 <xsl:call-template name="part"/>
5659                         </titleInfo>
5660                 </xsl:for-each>
5661                 <xsl:for-each
5662                         select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
5663                         <titleInfo type="uniform">
5664                                 <title>
5665                                                 <xsl:call-template name="uri"/>
5666
5667                                         <xsl:variable name="str">
5668                                                 <xsl:for-each select="marc:subfield">
5669                                                         <xsl:if
5670                                                                 test="(contains('adfklmors',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
5671                                                                 <xsl:value-of select="text()"/>
5672                                                                 <xsl:text> </xsl:text>
5673                                                         </xsl:if>
5674                                                 </xsl:for-each>
5675                                         </xsl:variable>
5676                                         <xsl:call-template name="chopPunctuation">
5677                                                 <xsl:with-param name="chopString">
5678                                                         <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
5679                                                 </xsl:with-param>
5680                                         </xsl:call-template>
5681                                 </title>
5682                                 <xsl:call-template name="part"/>
5683                         </titleInfo>
5684                 </xsl:for-each>
5685                 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
5686                         <titleInfo type="alternative">
5687                                 <title>
5688                                         <xsl:call-template name="chopPunctuation">
5689                                                 <xsl:with-param name="chopString">
5690                                                         <xsl:call-template name="subfieldSelect">
5691                                                                 <xsl:with-param name="codes">ah</xsl:with-param>
5692                                                         </xsl:call-template>
5693                                                 </xsl:with-param>
5694                                         </xsl:call-template>
5695                                 </title>
5696                                 <xsl:call-template name="part"/>
5697                         </titleInfo>
5698                 </xsl:for-each>
5699                 <xsl:for-each select="marc:datafield[@tag='100']">
5700                         <name type="personal">
5701
5702                                 <xsl:call-template name="uri"/>
5703
5704                                 <xsl:call-template name="nameABCDQ"/>
5705                                 <xsl:call-template name="affiliation"/>
5706                                 <role>
5707                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5708                                 </role>
5709                                 <xsl:call-template name="role"/>
5710                         </name>
5711                 </xsl:for-each>
5712                 <xsl:for-each select="marc:datafield[@tag='110']">
5713                         <name type="corporate">
5714
5715                                         <xsl:call-template name="uri"/>
5716
5717                                 <xsl:call-template name="nameABCDN"/>
5718                                 <role>
5719                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5720                                 </role>
5721                                 <xsl:call-template name="role"/>
5722                         </name>
5723                 </xsl:for-each>
5724                 <xsl:for-each select="marc:datafield[@tag='111']">
5725                         <name type="conference">
5726
5727                                         <xsl:call-template name="uri"/>
5728
5729                                 <xsl:call-template name="nameACDEQ"/>
5730                                 <role>
5731                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5732                                 </role>
5733                                 <xsl:call-template name="role"/>
5734                         </name>
5735                 </xsl:for-each>
5736                 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
5737                         <name type="personal">
5738
5739                                         <xsl:call-template name="uri"/>
5740
5741                                 <xsl:call-template name="nameABCDQ"/>
5742                                 <xsl:call-template name="affiliation"/>
5743                                 <xsl:call-template name="role"/>
5744                         </name>
5745                 </xsl:for-each>
5746                 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
5747                         <name type="corporate">
5748
5749                                         <xsl:call-template name="uri"/>
5750
5751                                 <xsl:call-template name="nameABCDN"/>
5752                                 <xsl:call-template name="role"/>
5753                         </name>
5754                 </xsl:for-each>
5755                 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
5756                         <name type="conference">
5757
5758                                         <xsl:call-template name="uri"/>
5759
5760                                 <xsl:call-template name="nameACDEQ"/>
5761                                 <xsl:call-template name="role"/>
5762                         </name>
5763                 </xsl:for-each>
5764                 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
5765                         <name>
5766                                 <xsl:if test="@ind1=1">
5767                                         <xsl:attribute name="type">
5768                                                 <xsl:text>personal</xsl:text>
5769                                         </xsl:attribute>
5770                                 </xsl:if>
5771                                 <namePart>
5772                                         <xsl:value-of select="marc:subfield[@code='a']"/>
5773                                 </namePart>
5774                                 <xsl:call-template name="role"/>
5775                         </name>
5776                 </xsl:for-each>
5777                 <typeOfResource>
5778                         <xsl:if test="$leader7='c'">
5779                                 <xsl:attribute name="collection">yes</xsl:attribute>
5780                         </xsl:if>
5781                         <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
5782                                 <xsl:attribute name="manuscript">yes</xsl:attribute>
5783                         </xsl:if>
5784                         <xsl:choose>
5785                                 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
5786                                 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
5787                                 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
5788                                 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
5789                                 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
5790                                 <xsl:when test="$leader6='k'">still image</xsl:when>
5791                                 <xsl:when test="$leader6='g'">moving image</xsl:when>
5792                                 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
5793                                 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
5794                                 <xsl:when test="$leader6='p'">mixed material</xsl:when>
5795                         </xsl:choose>
5796                 </typeOfResource>
5797                 <xsl:if test="substring($controlField008,26,1)='d'">
5798                         <genre authority="marcgt">globe</genre>
5799                 </xsl:if>
5800                 <xsl:if
5801                         test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
5802                         <genre authority="marcgt">remote-sensing image</genre>
5803                 </xsl:if>
5804                 <xsl:if test="$typeOf008='MP'">
5805                         <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
5806                         <xsl:choose>
5807                                 <xsl:when
5808                                         test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
5809                                         <genre authority="marcgt">map</genre>
5810                                 </xsl:when>
5811                                 <xsl:when
5812                                         test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
5813                                         <genre authority="marcgt">atlas</genre>
5814                                 </xsl:when>
5815                         </xsl:choose>
5816                 </xsl:if>
5817                 <xsl:if test="$typeOf008='SE'">
5818                         <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
5819                         <xsl:choose>
5820                                 <xsl:when test="$controlField008-21='d'">
5821                                         <genre authority="marcgt">database</genre>
5822                                 </xsl:when>
5823                                 <xsl:when test="$controlField008-21='l'">
5824                                         <genre authority="marcgt">loose-leaf</genre>
5825                                 </xsl:when>
5826                                 <xsl:when test="$controlField008-21='m'">
5827                                         <genre authority="marcgt">series</genre>
5828                                 </xsl:when>
5829                                 <xsl:when test="$controlField008-21='n'">
5830                                         <genre authority="marcgt">newspaper</genre>
5831                                 </xsl:when>
5832                                 <xsl:when test="$controlField008-21='p'">
5833                                         <genre authority="marcgt">periodical</genre>
5834                                 </xsl:when>
5835                                 <xsl:when test="$controlField008-21='w'">
5836                                         <genre authority="marcgt">web site</genre>
5837                                 </xsl:when>
5838                         </xsl:choose>
5839                 </xsl:if>
5840                 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
5841                         <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
5842                         <xsl:choose>
5843                                 <xsl:when test="contains($controlField008-24,'a')">
5844                                         <genre authority="marcgt">abstract or summary</genre>
5845                                 </xsl:when>
5846                                 <xsl:when test="contains($controlField008-24,'b')">
5847                                         <genre authority="marcgt">bibliography</genre>
5848                                 </xsl:when>
5849                                 <xsl:when test="contains($controlField008-24,'c')">
5850                                         <genre authority="marcgt">catalog</genre>
5851                                 </xsl:when>
5852                                 <xsl:when test="contains($controlField008-24,'d')">
5853                                         <genre authority="marcgt">dictionary</genre>
5854                                 </xsl:when>
5855                                 <xsl:when test="contains($controlField008-24,'e')">
5856                                         <genre authority="marcgt">encyclopedia</genre>
5857                                 </xsl:when>
5858                                 <xsl:when test="contains($controlField008-24,'f')">
5859                                         <genre authority="marcgt">handbook</genre>
5860                                 </xsl:when>
5861                                 <xsl:when test="contains($controlField008-24,'g')">
5862                                         <genre authority="marcgt">legal article</genre>
5863                                 </xsl:when>
5864                                 <xsl:when test="contains($controlField008-24,'i')">
5865                                         <genre authority="marcgt">index</genre>
5866                                 </xsl:when>
5867                                 <xsl:when test="contains($controlField008-24,'k')">
5868                                         <genre authority="marcgt">discography</genre>
5869                                 </xsl:when>
5870                                 <xsl:when test="contains($controlField008-24,'l')">
5871                                         <genre authority="marcgt">legislation</genre>
5872                                 </xsl:when>
5873                                 <xsl:when test="contains($controlField008-24,'m')">
5874                                         <genre authority="marcgt">theses</genre>
5875                                 </xsl:when>
5876                                 <xsl:when test="contains($controlField008-24,'n')">
5877                                         <genre authority="marcgt">survey of literature</genre>
5878                                 </xsl:when>
5879                                 <xsl:when test="contains($controlField008-24,'o')">
5880                                         <genre authority="marcgt">review</genre>
5881                                 </xsl:when>
5882                                 <xsl:when test="contains($controlField008-24,'p')">
5883                                         <genre authority="marcgt">programmed text</genre>
5884                                 </xsl:when>
5885                                 <xsl:when test="contains($controlField008-24,'q')">
5886                                         <genre authority="marcgt">filmography</genre>
5887                                 </xsl:when>
5888                                 <xsl:when test="contains($controlField008-24,'r')">
5889                                         <genre authority="marcgt">directory</genre>
5890                                 </xsl:when>
5891                                 <xsl:when test="contains($controlField008-24,'s')">
5892                                         <genre authority="marcgt">statistics</genre>
5893                                 </xsl:when>
5894                                 <xsl:when test="contains($controlField008-24,'t')">
5895                                         <genre authority="marcgt">technical report</genre>
5896                                 </xsl:when>
5897                                 <xsl:when test="contains($controlField008-24,'v')">
5898                                         <genre authority="marcgt">legal case and case notes</genre>
5899                                 </xsl:when>
5900                                 <xsl:when test="contains($controlField008-24,'w')">
5901                                         <genre authority="marcgt">law report or digest</genre>
5902                                 </xsl:when>
5903                                 <xsl:when test="contains($controlField008-24,'z')">
5904                                         <genre authority="marcgt">treaty</genre>
5905                                 </xsl:when>
5906                         </xsl:choose>
5907                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
5908                         <xsl:choose>
5909                                 <xsl:when test="$controlField008-29='1'">
5910                                         <genre authority="marcgt">conference publication</genre>
5911                                 </xsl:when>
5912                         </xsl:choose>
5913                 </xsl:if>
5914                 <xsl:if test="$typeOf008='CF'">
5915                         <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
5916                         <xsl:choose>
5917                                 <xsl:when test="$controlField008-26='a'">
5918                                         <genre authority="marcgt">numeric data</genre>
5919                                 </xsl:when>
5920                                 <xsl:when test="$controlField008-26='e'">
5921                                         <genre authority="marcgt">database</genre>
5922                                 </xsl:when>
5923                                 <xsl:when test="$controlField008-26='f'">
5924                                         <genre authority="marcgt">font</genre>
5925                                 </xsl:when>
5926                                 <xsl:when test="$controlField008-26='g'">
5927                                         <genre authority="marcgt">game</genre>
5928                                 </xsl:when>
5929                         </xsl:choose>
5930                 </xsl:if>
5931                 <xsl:if test="$typeOf008='BK'">
5932                         <xsl:if test="substring($controlField008,25,1)='j'">
5933                                 <genre authority="marcgt">patent</genre>
5934                         </xsl:if>
5935                         <xsl:if test="substring($controlField008,25,1)='2'">
5936                                 <genre authority="marcgt">offprint</genre>
5937                         </xsl:if>
5938                         <xsl:if test="substring($controlField008,31,1)='1'">
5939                                 <genre authority="marcgt">festschrift</genre>
5940                         </xsl:if>
5941                         <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
5942                         <xsl:if
5943                                 test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
5944                                 <genre authority="marcgt">biography</genre>
5945                         </xsl:if>
5946                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
5947                         <xsl:choose>
5948                                 <xsl:when test="$controlField008-33='e'">
5949                                         <genre authority="marcgt">essay</genre>
5950                                 </xsl:when>
5951                                 <xsl:when test="$controlField008-33='d'">
5952                                         <genre authority="marcgt">drama</genre>
5953                                 </xsl:when>
5954                                 <xsl:when test="$controlField008-33='c'">
5955                                         <genre authority="marcgt">comic strip</genre>
5956                                 </xsl:when>
5957                                 <xsl:when test="$controlField008-33='l'">
5958                                         <genre authority="marcgt">fiction</genre>
5959                                 </xsl:when>
5960                                 <xsl:when test="$controlField008-33='h'">
5961                                         <genre authority="marcgt">humor, satire</genre>
5962                                 </xsl:when>
5963                                 <xsl:when test="$controlField008-33='i'">
5964                                         <genre authority="marcgt">letter</genre>
5965                                 </xsl:when>
5966                                 <xsl:when test="$controlField008-33='f'">
5967                                         <genre authority="marcgt">novel</genre>
5968                                 </xsl:when>
5969                                 <xsl:when test="$controlField008-33='j'">
5970                                         <genre authority="marcgt">short story</genre>
5971                                 </xsl:when>
5972                                 <xsl:when test="$controlField008-33='s'">
5973                                         <genre authority="marcgt">speech</genre>
5974                                 </xsl:when>
5975                         </xsl:choose>
5976                 </xsl:if>
5977                 <xsl:if test="$typeOf008='MU'">
5978                         <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
5979                         <xsl:if test="contains($controlField008-30-31,'b')">
5980                                 <genre authority="marcgt">biography</genre>
5981                         </xsl:if>
5982                         <xsl:if test="contains($controlField008-30-31,'c')">
5983                                 <genre authority="marcgt">conference publication</genre>
5984                         </xsl:if>
5985                         <xsl:if test="contains($controlField008-30-31,'d')">
5986                                 <genre authority="marcgt">drama</genre>
5987                         </xsl:if>
5988                         <xsl:if test="contains($controlField008-30-31,'e')">
5989                                 <genre authority="marcgt">essay</genre>
5990                         </xsl:if>
5991                         <xsl:if test="contains($controlField008-30-31,'f')">
5992                                 <genre authority="marcgt">fiction</genre>
5993                         </xsl:if>
5994                         <xsl:if test="contains($controlField008-30-31,'o')">
5995                                 <genre authority="marcgt">folktale</genre>
5996                         </xsl:if>
5997                         <xsl:if test="contains($controlField008-30-31,'h')">
5998                                 <genre authority="marcgt">history</genre>
5999                         </xsl:if>
6000                         <xsl:if test="contains($controlField008-30-31,'k')">
6001                                 <genre authority="marcgt">humor, satire</genre>
6002                         </xsl:if>
6003                         <xsl:if test="contains($controlField008-30-31,'m')">
6004                                 <genre authority="marcgt">memoir</genre>
6005                         </xsl:if>
6006                         <xsl:if test="contains($controlField008-30-31,'p')">
6007                                 <genre authority="marcgt">poetry</genre>
6008                         </xsl:if>
6009                         <xsl:if test="contains($controlField008-30-31,'r')">
6010                                 <genre authority="marcgt">rehearsal</genre>
6011                         </xsl:if>
6012                         <xsl:if test="contains($controlField008-30-31,'g')">
6013                                 <genre authority="marcgt">reporting</genre>
6014                         </xsl:if>
6015                         <xsl:if test="contains($controlField008-30-31,'s')">
6016                                 <genre authority="marcgt">sound</genre>
6017                         </xsl:if>
6018                         <xsl:if test="contains($controlField008-30-31,'l')">
6019                                 <genre authority="marcgt">speech</genre>
6020                         </xsl:if>
6021                 </xsl:if>
6022                 <xsl:if test="$typeOf008='VM'">
6023                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
6024                         <xsl:choose>
6025                                 <xsl:when test="$controlField008-33='a'">
6026                                         <genre authority="marcgt">art original</genre>
6027                                 </xsl:when>
6028                                 <xsl:when test="$controlField008-33='b'">
6029                                         <genre authority="marcgt">kit</genre>
6030                                 </xsl:when>
6031                                 <xsl:when test="$controlField008-33='c'">
6032                                         <genre authority="marcgt">art reproduction</genre>
6033                                 </xsl:when>
6034                                 <xsl:when test="$controlField008-33='d'">
6035                                         <genre authority="marcgt">diorama</genre>
6036                                 </xsl:when>
6037                                 <xsl:when test="$controlField008-33='f'">
6038                                         <genre authority="marcgt">filmstrip</genre>
6039                                 </xsl:when>
6040                                 <xsl:when test="$controlField008-33='g'">
6041                                         <genre authority="marcgt">legal article</genre>
6042                                 </xsl:when>
6043                                 <xsl:when test="$controlField008-33='i'">
6044                                         <genre authority="marcgt">picture</genre>
6045                                 </xsl:when>
6046                                 <xsl:when test="$controlField008-33='k'">
6047                                         <genre authority="marcgt">graphic</genre>
6048                                 </xsl:when>
6049                                 <xsl:when test="$controlField008-33='l'">
6050                                         <genre authority="marcgt">technical drawing</genre>
6051                                 </xsl:when>
6052                                 <xsl:when test="$controlField008-33='m'">
6053                                         <genre authority="marcgt">motion picture</genre>
6054                                 </xsl:when>
6055                                 <xsl:when test="$controlField008-33='n'">
6056                                         <genre authority="marcgt">chart</genre>
6057                                 </xsl:when>
6058                                 <xsl:when test="$controlField008-33='o'">
6059                                         <genre authority="marcgt">flash card</genre>
6060                                 </xsl:when>
6061                                 <xsl:when test="$controlField008-33='p'">
6062                                         <genre authority="marcgt">microscope slide</genre>
6063                                 </xsl:when>
6064                                 <xsl:when
6065                                         test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
6066                                         <genre authority="marcgt">model</genre>
6067                                 </xsl:when>
6068                                 <xsl:when test="$controlField008-33='r'">
6069                                         <genre authority="marcgt">realia</genre>
6070                                 </xsl:when>
6071                                 <xsl:when test="$controlField008-33='s'">
6072                                         <genre authority="marcgt">slide</genre>
6073                                 </xsl:when>
6074                                 <xsl:when test="$controlField008-33='t'">
6075                                         <genre authority="marcgt">transparency</genre>
6076                                 </xsl:when>
6077                                 <xsl:when test="$controlField008-33='v'">
6078                                         <genre authority="marcgt">videorecording</genre>
6079                                 </xsl:when>
6080                                 <xsl:when test="$controlField008-33='w'">
6081                                         <genre authority="marcgt">toy</genre>
6082                                 </xsl:when>
6083                         </xsl:choose>
6084                 </xsl:if>
6085
6086                 <!-- 1.20 047 genre tmee-->
6087
6088                 <xsl:for-each select="marc:datafield[@tag=047]">
6089                         <genre authority="marcgt">
6090                                 <xsl:attribute name="authority">
6091                                         <xsl:value-of select="marc:subfield[@code='2']"/>
6092                                 </xsl:attribute>
6093                                 <xsl:call-template name="subfieldSelect">
6094                                         <xsl:with-param name="codes">abcdef</xsl:with-param>
6095                                         <xsl:with-param name="delimeter">-</xsl:with-param>
6096                                 </xsl:call-template>
6097                         </genre>
6098                 </xsl:for-each>
6099                 <xsl:for-each select="marc:datafield[@tag=655]">
6100                         <genre authority="marcgt">
6101                                 <xsl:attribute name="authority">
6102                                         <xsl:value-of select="marc:subfield[@code='2']"/>
6103                                 </xsl:attribute>
6104                                 <xsl:call-template name="subfieldSelect">
6105                                         <xsl:with-param name="codes">abvxyz</xsl:with-param>
6106                                         <xsl:with-param name="delimeter">-</xsl:with-param>
6107                                 </xsl:call-template>
6108                         </genre>
6109                 </xsl:for-each>
6110                 <originInfo>
6111                         <xsl:variable name="MARCpublicationCode"
6112                                 select="normalize-space(substring($controlField008,16,3))"/>
6113                         <xsl:if test="translate($MARCpublicationCode,'|','')">
6114                                 <place>
6115                                         <placeTerm>
6116                                                 <xsl:attribute name="type">code</xsl:attribute>
6117                                                 <xsl:attribute name="authority">marccountry</xsl:attribute>
6118                                                 <xsl:value-of select="$MARCpublicationCode"/>
6119                                         </placeTerm>
6120                                 </place>
6121                         </xsl:if>
6122                         <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
6123                                 <place>
6124                                         <placeTerm>
6125                                                 <xsl:attribute name="type">code</xsl:attribute>
6126                                                 <xsl:attribute name="authority">iso3166</xsl:attribute>
6127                                                 <xsl:value-of select="."/>
6128                                         </placeTerm>
6129                                 </place>
6130                         </xsl:for-each>
6131                         <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
6132                                 <place>
6133                                         <placeTerm>
6134                                                 <xsl:attribute name="type">text</xsl:attribute>
6135                                                 <xsl:call-template name="chopPunctuationFront">
6136                                                         <xsl:with-param name="chopString">
6137                                                                 <xsl:call-template name="chopPunctuation">
6138                                                                         <xsl:with-param name="chopString" select="."/>
6139                                                                 </xsl:call-template>
6140                                                         </xsl:with-param>
6141                                                 </xsl:call-template>
6142                                         </placeTerm>
6143                                 </place>
6144                         </xsl:for-each>
6145                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
6146                                 <dateValid point="start">
6147                                         <xsl:value-of select="."/>
6148                                 </dateValid>
6149                         </xsl:for-each>
6150                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
6151                                 <dateValid point="end">
6152                                         <xsl:value-of select="."/>
6153                                 </dateValid>
6154                         </xsl:for-each>
6155                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
6156                                 <dateModified>
6157                                         <xsl:value-of select="."/>
6158                                 </dateModified>
6159                         </xsl:for-each>
6160                         <xsl:for-each
6161                                 select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
6162                                 <xsl:choose>
6163                                         <xsl:when test="@code='b'">
6164                                                 <publisher>
6165                                                         <xsl:call-template name="chopPunctuation">
6166                                                                 <xsl:with-param name="chopString" select="."/>
6167                                                                 <xsl:with-param name="punctuation">
6168                                                                         <xsl:text>:,;/ </xsl:text>
6169                                                                 </xsl:with-param>
6170                                                         </xsl:call-template>
6171                                                 </publisher>
6172                                         </xsl:when>
6173                                         <xsl:when test="@code='c'">
6174                                                 <dateIssued>
6175                                                         <xsl:call-template name="chopPunctuation">
6176                                                                 <xsl:with-param name="chopString" select="."/>
6177                                                         </xsl:call-template>
6178                                                 </dateIssued>
6179                                         </xsl:when>
6180                                         <xsl:when test="@code='g'">
6181                                                 <dateCreated>
6182                                                         <xsl:value-of select="."/>
6183                                                 </dateCreated>
6184                                         </xsl:when>
6185                                 </xsl:choose>
6186                         </xsl:for-each>
6187                         <xsl:variable name="dataField260c">
6188                                 <xsl:call-template name="chopPunctuation">
6189                                         <xsl:with-param name="chopString"
6190                                                 select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
6191                                 </xsl:call-template>
6192                         </xsl:variable>
6193                         <xsl:variable name="controlField008-7-10"
6194                                 select="normalize-space(substring($controlField008, 8, 4))"/>
6195                         <xsl:variable name="controlField008-11-14"
6196                                 select="normalize-space(substring($controlField008, 12, 4))"/>
6197                         <xsl:variable name="controlField008-6"
6198                                 select="normalize-space(substring($controlField008, 7, 1))"/>
6199                         <xsl:if
6200                                 test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
6201                                 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
6202                                         <dateIssued encoding="marc">
6203                                                 <xsl:value-of select="$controlField008-7-10"/>
6204                                         </dateIssued>
6205                                 </xsl:if>
6206                         </xsl:if>
6207                         <xsl:if
6208                                 test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
6209                                 <xsl:if test="$controlField008-7-10">
6210                                         <dateIssued encoding="marc" point="start">
6211                                                 <xsl:value-of select="$controlField008-7-10"/>
6212                                         </dateIssued>
6213                                 </xsl:if>
6214                         </xsl:if>
6215                         <xsl:if
6216                                 test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
6217                                 <xsl:if test="$controlField008-11-14">
6218                                         <dateIssued encoding="marc" point="end">
6219                                                 <xsl:value-of select="$controlField008-11-14"/>
6220                                         </dateIssued>
6221                                 </xsl:if>
6222                         </xsl:if>
6223                         <xsl:if test="$controlField008-6='q'">
6224                                 <xsl:if test="$controlField008-7-10">
6225                                         <dateIssued encoding="marc" point="start" qualifier="questionable">
6226                                                 <xsl:value-of select="$controlField008-7-10"/>
6227                                         </dateIssued>
6228                                 </xsl:if>
6229                         </xsl:if>
6230                         <xsl:if test="$controlField008-6='q'">
6231                                 <xsl:if test="$controlField008-11-14">
6232                                         <dateIssued encoding="marc" point="end" qualifier="questionable">
6233                                                 <xsl:value-of select="$controlField008-11-14"/>
6234                                         </dateIssued>
6235                                 </xsl:if>
6236                         </xsl:if>
6237                         <xsl:if test="$controlField008-6='t'">
6238                                 <xsl:if test="$controlField008-11-14">
6239                                         <copyrightDate encoding="marc">
6240                                                 <xsl:value-of select="$controlField008-11-14"/>
6241                                         </copyrightDate>
6242                                 </xsl:if>
6243                         </xsl:if>
6244                         <xsl:for-each
6245                                 select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
6246                                 <dateCaptured encoding="iso8601">
6247                                         <xsl:value-of select="."/>
6248                                 </dateCaptured>
6249                         </xsl:for-each>
6250                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
6251                                 <dateCaptured encoding="iso8601" point="start">
6252                                         <xsl:value-of select="."/>
6253                                 </dateCaptured>
6254                         </xsl:for-each>
6255                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
6256                                 <dateCaptured encoding="iso8601" point="end">
6257                                         <xsl:value-of select="."/>
6258                                 </dateCaptured>
6259                         </xsl:for-each>
6260                         <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
6261                                 <edition>
6262                                         <xsl:value-of select="."/>
6263                                 </edition>
6264                         </xsl:for-each>
6265                         <xsl:for-each select="marc:leader">
6266                                 <issuance>
6267                                         <xsl:choose>
6268                                                 <xsl:when
6269                                                         test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'"
6270                                                         >monographic</xsl:when>
6271                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'"
6272                                                 >continuing</xsl:when>
6273                                         </xsl:choose>
6274                                 </issuance>
6275                         </xsl:for-each>
6276                         <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
6277                                 <frequency>
6278                                         <xsl:call-template name="subfieldSelect">
6279                                                 <xsl:with-param name="codes">ab</xsl:with-param>
6280                                         </xsl:call-template>
6281                                 </frequency>
6282                         </xsl:for-each>
6283                 </originInfo>
6284                 <xsl:variable name="controlField008-35-37"
6285                         select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
6286                 <xsl:if test="$controlField008-35-37">
6287                         <language>
6288                                 <languageTerm authority="iso639-2b" type="code">
6289                                         <xsl:value-of select="substring($controlField008,36,3)"/>
6290                                 </languageTerm>
6291                         </language>
6292                 </xsl:if>
6293                 <xsl:for-each select="marc:datafield[@tag=041]">
6294                         <xsl:for-each
6295                                 select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
6296                                 <xsl:variable name="langCodes" select="."/>
6297                                 <xsl:choose>
6298                                         <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
6299                                                 <!-- not stacked but could be repeated -->
6300                                                 <xsl:call-template name="rfcLanguages">
6301                                                         <xsl:with-param name="nodeNum">
6302                                                                 <xsl:value-of select="1"/>
6303                                                         </xsl:with-param>
6304                                                         <xsl:with-param name="usedLanguages">
6305                                                                 <xsl:text/>
6306                                                         </xsl:with-param>
6307                                                         <xsl:with-param name="controlField008-35-37">
6308                                                                 <xsl:value-of select="$controlField008-35-37"/>
6309                                                         </xsl:with-param>
6310                                                 </xsl:call-template>
6311                                         </xsl:when>
6312                                         <xsl:otherwise>
6313                                                 <!-- iso -->
6314                                                 <xsl:variable name="allLanguages">
6315                                                         <xsl:copy-of select="$langCodes"/>
6316                                                 </xsl:variable>
6317                                                 <xsl:variable name="currentLanguage">
6318                                                         <xsl:value-of select="substring($allLanguages,1,3)"/>
6319                                                 </xsl:variable>
6320                                                 <xsl:call-template name="isoLanguage">
6321                                                         <xsl:with-param name="currentLanguage">
6322                                                                 <xsl:value-of select="substring($allLanguages,1,3)"/>
6323                                                         </xsl:with-param>
6324                                                         <xsl:with-param name="remainingLanguages">
6325                                                                 <xsl:value-of
6326                                                                         select="substring($allLanguages,4,string-length($allLanguages)-3)"
6327                                                                 />
6328                                                         </xsl:with-param>
6329                                                         <xsl:with-param name="usedLanguages">
6330                                                                 <xsl:if test="$controlField008-35-37">
6331                                                                         <xsl:value-of select="$controlField008-35-37"/>
6332                                                                 </xsl:if>
6333                                                         </xsl:with-param>
6334                                                 </xsl:call-template>
6335                                         </xsl:otherwise>
6336                                 </xsl:choose>
6337                         </xsl:for-each>
6338                 </xsl:for-each>
6339                 <xsl:variable name="physicalDescription">
6340                         <!--3.2 change tmee 007/11 -->
6341                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
6342                                 <digitalOrigin>reformatted digital</digitalOrigin>
6343                         </xsl:if>
6344                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
6345                                 <digitalOrigin>digitized microfilm</digitalOrigin>
6346                         </xsl:if>
6347                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
6348                                 <digitalOrigin>digitized other analog</digitalOrigin>
6349                         </xsl:if>
6350                         <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
6351                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
6352                         <xsl:variable name="check008-23">
6353                                 <xsl:if
6354                                         test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
6355                                         <xsl:value-of select="true()"/>
6356                                 </xsl:if>
6357                         </xsl:variable>
6358                         <xsl:variable name="check008-29">
6359                                 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
6360                                         <xsl:value-of select="true()"/>
6361                                 </xsl:if>
6362                         </xsl:variable>
6363                         <xsl:choose>
6364                                 <xsl:when
6365                                         test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
6366                                         <form authority="marcform">braille</form>
6367                                 </xsl:when>
6368                                 <xsl:when
6369                                         test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
6370                                         <form authority="marcform">print</form>
6371                                 </xsl:when>
6372                                 <xsl:when
6373                                         test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
6374                                         <form authority="marcform">electronic</form>
6375                                 </xsl:when>
6376                                 <xsl:when
6377                                         test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
6378                                         <form authority="marcform">microfiche</form>
6379                                 </xsl:when>
6380                                 <xsl:when
6381                                         test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
6382                                         <form authority="marcform">microfilm</form>
6383                                 </xsl:when>
6384                         </xsl:choose>
6385                         <!-- 1/04 fix -->
6386                         <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
6387                                 <form authority="gmd">
6388                                         <xsl:call-template name="chopBrackets">
6389                                                 <xsl:with-param name="chopString">
6390                                                         <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"
6391                                                         />
6392                                                 </xsl:with-param>
6393                                         </xsl:call-template>
6394                                 </form>
6395                         </xsl:if>
6396                         <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
6397                                 <form authority="gmd">
6398                                         <xsl:call-template name="chopBrackets">
6399                                                 <xsl:with-param name="chopString">
6400                                                         <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"
6401                                                         />
6402                                                 </xsl:with-param>
6403                                         </xsl:call-template>
6404                                 </form>
6405                         </xsl:if>
6406                         <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
6407                                 <form authority="gmd">
6408                                         <xsl:call-template name="chopBrackets">
6409                                                 <xsl:with-param name="chopString">
6410                                                         <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"
6411                                                         />
6412                                                 </xsl:with-param>
6413                                         </xsl:call-template>
6414                                 </form>
6415                         </xsl:if>
6416                         <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
6417                                 <form authority="gmd">
6418                                         <xsl:call-template name="chopBrackets">
6419                                                 <xsl:with-param name="chopString">
6420                                                         <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"
6421                                                         />
6422                                                 </xsl:with-param>
6423                                         </xsl:call-template>
6424                                 </form>
6425                         </xsl:if>
6426                         <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
6427                                 <form authority="gmd">
6428                                         <xsl:call-template name="chopBrackets">
6429                                                 <xsl:with-param name="chopString">
6430                                                         <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"
6431                                                         />
6432                                                 </xsl:with-param>
6433                                         </xsl:call-template>
6434                                 </form>
6435                         </xsl:if>
6436                         <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
6437                                 <form authority="gmd">
6438                                         <xsl:call-template name="chopBrackets">
6439                                                 <xsl:with-param name="chopString">
6440                                                         <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"
6441                                                         />
6442                                                 </xsl:with-param>
6443                                         </xsl:call-template>
6444                                 </form>
6445                         </xsl:if>
6446                         <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
6447                                 <form>
6448                                         <xsl:value-of select="."/>
6449                                 </form>
6450                         </xsl:for-each>
6451                         <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
6452                                 <xsl:choose>
6453                                         <xsl:when test="substring(text(),14,1)='a'">
6454                                                 <reformattingQuality>access</reformattingQuality>
6455                                         </xsl:when>
6456                                         <xsl:when test="substring(text(),14,1)='p'">
6457                                                 <reformattingQuality>preservation</reformattingQuality>
6458                                         </xsl:when>
6459                                         <xsl:when test="substring(text(),14,1)='r'">
6460                                                 <reformattingQuality>replacement</reformattingQuality>
6461                                         </xsl:when>
6462                                 </xsl:choose>
6463                         </xsl:for-each>
6464                         <!--3.2 change tmee 007/01 -->
6465                         <xsl:if
6466                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
6467                                 <form authority="smd">chip cartridge</form>
6468                         </xsl:if>
6469                         <xsl:if
6470                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
6471                                 <form authority="smd">computer optical disc cartridge</form>
6472                         </xsl:if>
6473                         <xsl:if
6474                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
6475                                 <form authority="smd">magnetic disc</form>
6476                         </xsl:if>
6477                         <xsl:if
6478                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
6479                                 <form authority="smd">magneto-optical disc</form>
6480                         </xsl:if>
6481                         <xsl:if
6482                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
6483                                 <form authority="smd">optical disc</form>
6484                         </xsl:if>
6485                         <xsl:if
6486                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
6487                                 <form authority="smd">remote</form>
6488                         </xsl:if>
6489                         <xsl:if
6490                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
6491                                 <form authority="smd">tape cartridge</form>
6492                         </xsl:if>
6493                         <xsl:if
6494                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
6495                                 <form authority="smd">tape cassette</form>
6496                         </xsl:if>
6497                         <xsl:if
6498                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
6499                                 <form authority="smd">tape reel</form>
6500                         </xsl:if>
6501
6502                         <xsl:if
6503                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
6504                                 <form authority="smd">celestial globe</form>
6505                         </xsl:if>
6506                         <xsl:if
6507                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
6508                                 <form authority="smd">earth moon globe</form>
6509                         </xsl:if>
6510                         <xsl:if
6511                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
6512                                 <form authority="smd">planetary or lunar globe</form>
6513                         </xsl:if>
6514                         <xsl:if
6515                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
6516                                 <form authority="smd">terrestrial globe</form>
6517                         </xsl:if>
6518
6519                         <xsl:if
6520                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
6521                                 <form authority="smd">kit</form>
6522                         </xsl:if>
6523
6524                         <xsl:if
6525                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
6526                                 <form authority="smd">atlas</form>
6527                         </xsl:if>
6528                         <xsl:if
6529                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
6530                                 <form authority="smd">diagram</form>
6531                         </xsl:if>
6532                         <xsl:if
6533                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
6534                                 <form authority="smd">map</form>
6535                         </xsl:if>
6536                         <xsl:if
6537                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
6538                                 <form authority="smd">model</form>
6539                         </xsl:if>
6540                         <xsl:if
6541                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
6542                                 <form authority="smd">profile</form>
6543                         </xsl:if>
6544                         <xsl:if
6545                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
6546                                 <form authority="smd">remote-sensing image</form>
6547                         </xsl:if>
6548                         <xsl:if
6549                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
6550                                 <form authority="smd">section</form>
6551                         </xsl:if>
6552                         <xsl:if
6553                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
6554                                 <form authority="smd">view</form>
6555                         </xsl:if>
6556
6557                         <xsl:if
6558                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
6559                                 <form authority="smd">aperture card</form>
6560                         </xsl:if>
6561                         <xsl:if
6562                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
6563                                 <form authority="smd">microfiche</form>
6564                         </xsl:if>
6565                         <xsl:if
6566                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
6567                                 <form authority="smd">microfiche cassette</form>
6568                         </xsl:if>
6569                         <xsl:if
6570                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
6571                                 <form authority="smd">microfilm cartridge</form>
6572                         </xsl:if>
6573                         <xsl:if
6574                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
6575                                 <form authority="smd">microfilm cassette</form>
6576                         </xsl:if>
6577                         <xsl:if
6578                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
6579                                 <form authority="smd">microfilm reel</form>
6580                         </xsl:if>
6581                         <xsl:if
6582                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
6583                                 <form authority="smd">microopaque</form>
6584                         </xsl:if>
6585
6586                         <xsl:if
6587                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
6588                                 <form authority="smd">film cartridge</form>
6589                         </xsl:if>
6590                         <xsl:if
6591                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
6592                                 <form authority="smd">film cassette</form>
6593                         </xsl:if>
6594                         <xsl:if
6595                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
6596                                 <form authority="smd">film reel</form>
6597                         </xsl:if>
6598
6599                         <xsl:if
6600                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
6601                                 <form authority="smd">chart</form>
6602                         </xsl:if>
6603                         <xsl:if
6604                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
6605                                 <form authority="smd">collage</form>
6606                         </xsl:if>
6607                         <xsl:if
6608                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
6609                                 <form authority="smd">drawing</form>
6610                         </xsl:if>
6611                         <xsl:if
6612                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
6613                                 <form authority="smd">flash card</form>
6614                         </xsl:if>
6615                         <xsl:if
6616                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
6617                                 <form authority="smd">painting</form>
6618                         </xsl:if>
6619                         <xsl:if
6620                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
6621                                 <form authority="smd">photomechanical print</form>
6622                         </xsl:if>
6623                         <xsl:if
6624                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
6625                                 <form authority="smd">photonegative</form>
6626                         </xsl:if>
6627                         <xsl:if
6628                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
6629                                 <form authority="smd">photoprint</form>
6630                         </xsl:if>
6631                         <xsl:if
6632                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
6633                                 <form authority="smd">picture</form>
6634                         </xsl:if>
6635                         <xsl:if
6636                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
6637                                 <form authority="smd">print</form>
6638                         </xsl:if>
6639                         <xsl:if
6640                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
6641                                 <form authority="smd">technical drawing</form>
6642                         </xsl:if>
6643
6644                         <xsl:if
6645                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
6646                                 <form authority="smd">notated music</form>
6647                         </xsl:if>
6648
6649                         <xsl:if
6650                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
6651                                 <form authority="smd">filmslip</form>
6652                         </xsl:if>
6653                         <xsl:if
6654                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
6655                                 <form authority="smd">filmstrip cartridge</form>
6656                         </xsl:if>
6657                         <xsl:if
6658                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
6659                                 <form authority="smd">filmstrip roll</form>
6660                         </xsl:if>
6661                         <xsl:if
6662                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
6663                                 <form authority="smd">other filmstrip type</form>
6664                         </xsl:if>
6665                         <xsl:if
6666                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
6667                                 <form authority="smd">slide</form>
6668                         </xsl:if>
6669                         <xsl:if
6670                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
6671                                 <form authority="smd">transparency</form>
6672                         </xsl:if>
6673                         <xsl:if
6674                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
6675                                 <form authority="smd">remote-sensing image</form>
6676                         </xsl:if>
6677                         <xsl:if
6678                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
6679                                 <form authority="smd">cylinder</form>
6680                         </xsl:if>
6681                         <xsl:if
6682                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
6683                                 <form authority="smd">roll</form>
6684                         </xsl:if>
6685                         <xsl:if
6686                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
6687                                 <form authority="smd">sound cartridge</form>
6688                         </xsl:if>
6689                         <xsl:if
6690                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
6691                                 <form authority="smd">sound cassette</form>
6692                         </xsl:if>
6693                         <xsl:if
6694                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
6695                                 <form authority="smd">sound disc</form>
6696                         </xsl:if>
6697                         <xsl:if
6698                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
6699                                 <form authority="smd">sound-tape reel</form>
6700                         </xsl:if>
6701                         <xsl:if
6702                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
6703                                 <form authority="smd">sound-track film</form>
6704                         </xsl:if>
6705                         <xsl:if
6706                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
6707                                 <form authority="smd">wire recording</form>
6708                         </xsl:if>
6709
6710                         <xsl:if
6711                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
6712                                 <form authority="smd">braille</form>
6713                         </xsl:if>
6714                         <xsl:if
6715                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
6716                                 <form authority="smd">combination</form>
6717                         </xsl:if>
6718                         <xsl:if
6719                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
6720                                 <form authority="smd">moon</form>
6721                         </xsl:if>
6722                         <xsl:if
6723                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
6724                                 <form authority="smd">tactile, with no writing system</form>
6725                         </xsl:if>
6726
6727                         <xsl:if
6728                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
6729                                 <form authority="smd">braille</form>
6730                         </xsl:if>
6731                         <xsl:if
6732                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
6733                                 <form authority="smd">large print</form>
6734                         </xsl:if>
6735                         <xsl:if
6736                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
6737                                 <form authority="smd">regular print</form>
6738                         </xsl:if>
6739                         <xsl:if
6740                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
6741                                 <form authority="smd">text in looseleaf binder</form>
6742                         </xsl:if>
6743
6744                         <xsl:if
6745                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
6746                                 <form authority="smd">videocartridge</form>
6747                         </xsl:if>
6748                         <xsl:if
6749                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
6750                                 <form authority="smd">videocassette</form>
6751                         </xsl:if>
6752                         <xsl:if
6753                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
6754                                 <form authority="smd">videodisc</form>
6755                         </xsl:if>
6756                         <xsl:if
6757                                 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
6758                                 <form authority="smd">videoreel</form>
6759                         </xsl:if>
6760
6761                         <xsl:for-each
6762                                 select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)&gt;1]">
6763                                 <internetMediaType>
6764                                         <xsl:value-of select="."/>
6765                                 </internetMediaType>
6766                         </xsl:for-each>
6767                         <xsl:for-each select="marc:datafield[@tag=300]">
6768                                 <extent>
6769                                         <xsl:call-template name="subfieldSelect">
6770                                                 <xsl:with-param name="codes">abce</xsl:with-param>
6771                                         </xsl:call-template>
6772                                 </extent>
6773                         </xsl:for-each>
6774                 </xsl:variable>
6775                 <xsl:if test="string-length(normalize-space($physicalDescription))">
6776                         <physicalDescription>
6777                                 <xsl:copy-of select="$physicalDescription"/>
6778                         </physicalDescription>
6779                 </xsl:if>
6780                 <xsl:for-each select="marc:datafield[@tag=520]">
6781                         <abstract>
6782                                 <xsl:call-template name="uri"/>
6783                                 <xsl:call-template name="subfieldSelect">
6784                                         <xsl:with-param name="codes">ab</xsl:with-param>
6785                                 </xsl:call-template>
6786                         </abstract>
6787                 </xsl:for-each>
6788                 <xsl:for-each select="marc:datafield[@tag=505]">
6789                         <tableOfContents>
6790                                 <xsl:call-template name="uri"/>
6791                                 <xsl:call-template name="subfieldSelect">
6792                                         <xsl:with-param name="codes">agrt</xsl:with-param>
6793                                 </xsl:call-template>
6794                         </tableOfContents>
6795                 </xsl:for-each>
6796                 <xsl:for-each select="marc:datafield[@tag=521]">
6797                         <targetAudience>
6798                                 <xsl:call-template name="subfieldSelect">
6799                                         <xsl:with-param name="codes">ab</xsl:with-param>
6800                                 </xsl:call-template>
6801                         </targetAudience>
6802                 </xsl:for-each>
6803                 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
6804                         <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
6805                         <xsl:choose>
6806                                 <!-- 01/04 fix -->
6807                                 <xsl:when test="$controlField008-22='d'">
6808                                         <targetAudience authority="marctarget">adolescent</targetAudience>
6809                                 </xsl:when>
6810                                 <xsl:when test="$controlField008-22='e'">
6811                                         <targetAudience authority="marctarget">adult</targetAudience>
6812                                 </xsl:when>
6813                                 <xsl:when test="$controlField008-22='g'">
6814                                         <targetAudience authority="marctarget">general</targetAudience>
6815                                 </xsl:when>
6816                                 <xsl:when
6817                                         test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
6818                                         <targetAudience authority="marctarget">juvenile</targetAudience>
6819                                 </xsl:when>
6820                                 <xsl:when test="$controlField008-22='a'">
6821                                         <targetAudience authority="marctarget">preschool</targetAudience>
6822                                 </xsl:when>
6823                                 <xsl:when test="$controlField008-22='f'">
6824                                         <targetAudience authority="marctarget">specialized</targetAudience>
6825                                 </xsl:when>
6826                         </xsl:choose>
6827                 </xsl:if>
6828                 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
6829                         <note type="statement of responsibility">
6830                                 <xsl:value-of select="."/>
6831                         </note>
6832                 </xsl:for-each>
6833                 <xsl:for-each select="marc:datafield[@tag=500]">
6834                         <note>
6835                                 <xsl:value-of select="marc:subfield[@code='a']"/>
6836                                 <xsl:call-template name="uri"/>
6837                         </note>
6838                 </xsl:for-each>
6839
6840                 <!--3.2 change tmee additional note fields-->
6841
6842                 <xsl:for-each select="marc:datafield[@tag=506]">
6843                         <note type="restrictions">
6844                                 <xsl:call-template name="uri"/>
6845                                 <xsl:variable name="str">
6846                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6847                                                 <xsl:value-of select="."/>
6848                                                 <xsl:text> </xsl:text>
6849                                         </xsl:for-each>
6850                                 </xsl:variable>
6851                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6852                         </note>
6853                 </xsl:for-each>
6854
6855                 <xsl:for-each select="marc:datafield[@tag=510]">
6856                         <note type="citation/reference">
6857                                 <xsl:call-template name="uri"/>
6858                                 <xsl:variable name="str">
6859                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6860                                                 <xsl:value-of select="."/>
6861                                                 <xsl:text> </xsl:text>
6862                                         </xsl:for-each>
6863                                 </xsl:variable>
6864                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6865                         </note>
6866                 </xsl:for-each>
6867
6868
6869                 <xsl:for-each select="marc:datafield[@tag=511]">
6870                         <note type="performers">
6871                                 <xsl:call-template name="uri"/>
6872                                 <xsl:value-of select="marc:subfield[@code='a']"/>
6873                         </note>
6874                 </xsl:for-each>
6875                 <xsl:for-each select="marc:datafield[@tag=518]">
6876                         <note type="venue">
6877                                 <xsl:call-template name="uri"/>
6878                                 <xsl:value-of select="marc:subfield[@code='a']"/>
6879                         </note>
6880                 </xsl:for-each>
6881
6882                 <xsl:for-each select="marc:datafield[@tag=530]">
6883                         <note type="additional physical form">
6884                                 <xsl:call-template name="uri"/>
6885                                 <xsl:variable name="str">
6886                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6887                                                 <xsl:value-of select="."/>
6888                                                 <xsl:text> </xsl:text>
6889                                         </xsl:for-each>
6890                                 </xsl:variable>
6891                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6892                         </note>
6893                 </xsl:for-each>
6894
6895                 <xsl:for-each select="marc:datafield[@tag=533]">
6896                         <note type="reproduction">
6897                                 <xsl:call-template name="uri"/>
6898                                 <xsl:variable name="str">
6899                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6900                                                 <xsl:value-of select="."/>
6901                                                 <xsl:text> </xsl:text>
6902                                         </xsl:for-each>
6903                                 </xsl:variable>
6904                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6905                         </note>
6906                 </xsl:for-each>
6907
6908                 <xsl:for-each select="marc:datafield[@tag=534]">
6909                         <note type="original version">
6910                                 <xsl:call-template name="uri"/>
6911                                 <xsl:variable name="str">
6912                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6913                                                 <xsl:value-of select="."/>
6914                                                 <xsl:text> </xsl:text>
6915                                         </xsl:for-each>
6916                                 </xsl:variable>
6917                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6918                         </note>
6919                 </xsl:for-each>
6920
6921                 <xsl:for-each select="marc:datafield[@tag=538]">
6922                         <note type="system details">
6923                                 <xsl:call-template name="uri"/>
6924                                 <xsl:variable name="str">
6925                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6926                                                 <xsl:value-of select="."/>
6927                                                 <xsl:text> </xsl:text>
6928                                         </xsl:for-each>
6929                                 </xsl:variable>
6930                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6931                         </note>
6932                 </xsl:for-each>
6933
6934                 <xsl:for-each select="marc:datafield[@tag=583]">
6935                         <note type="action">
6936                                 <xsl:call-template name="uri"/>
6937                                 <xsl:variable name="str">
6938                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6939                                                 <xsl:value-of select="."/>
6940                                                 <xsl:text> </xsl:text>
6941                                         </xsl:for-each>
6942                                 </xsl:variable>
6943                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6944                         </note>
6945                 </xsl:for-each>
6946
6947                 <xsl:for-each
6948                         select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or  @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
6949                         <note>
6950                                 <xsl:call-template name="uri"/>
6951                                 <xsl:variable name="str">
6952                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6953                                                 <xsl:value-of select="."/>
6954                                                 <xsl:text> </xsl:text>
6955                                         </xsl:for-each>
6956                                 </xsl:variable>
6957                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6958                         </note>
6959                 </xsl:for-each>
6960                 <xsl:for-each
6961                         select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
6962                         <subject>
6963                                 <cartographics>
6964                                         <coordinates>
6965                                                 <xsl:call-template name="subfieldSelect">
6966                                                         <xsl:with-param name="codes">defg</xsl:with-param>
6967                                                 </xsl:call-template>
6968                                         </coordinates>
6969                                 </cartographics>
6970                         </subject>
6971                 </xsl:for-each>
6972                 <xsl:for-each select="marc:datafield[@tag=043]">
6973                         <subject>
6974                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
6975                                         <geographicCode>
6976                                                 <xsl:attribute name="authority">
6977                                                         <xsl:if test="@code='a'">
6978                                                                 <xsl:text>marcgac</xsl:text>
6979                                                         </xsl:if>
6980                                                         <xsl:if test="@code='b'">
6981                                                                 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"/>
6982                                                         </xsl:if>
6983                                                         <xsl:if test="@code='c'">
6984                                                                 <xsl:text>iso3166</xsl:text>
6985                                                         </xsl:if>
6986                                                 </xsl:attribute>
6987                                                 <xsl:value-of select="self::marc:subfield"/>
6988                                         </geographicCode>
6989                                 </xsl:for-each>
6990                         </subject>
6991                 </xsl:for-each>
6992                 <!-- tmee 2006/11/27 -->
6993                 <xsl:for-each select="marc:datafield[@tag=255]">
6994                         <subject>
6995                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
6996                                         <cartographics>
6997                                                 <xsl:if test="@code='a'">
6998                                                         <scale>
6999                                                                 <xsl:value-of select="."/>
7000                                                         </scale>
7001                                                 </xsl:if>
7002                                                 <xsl:if test="@code='b'">
7003                                                         <projection>
7004                                                                 <xsl:value-of select="."/>
7005                                                         </projection>
7006                                                 </xsl:if>
7007                                                 <xsl:if test="@code='c'">
7008                                                         <coordinates>
7009                                                                 <xsl:value-of select="."/>
7010                                                         </coordinates>
7011                                                 </xsl:if>
7012                                         </cartographics>
7013                                 </xsl:for-each>
7014                         </subject>
7015                 </xsl:for-each>
7016
7017                 <xsl:apply-templates select="marc:datafield[653 &gt;= @tag and @tag &gt;= 600]"/>
7018                 <xsl:apply-templates select="marc:datafield[@tag=656]"/>
7019                 <xsl:for-each select="marc:datafield[@tag=752 or @tag=662]">
7020                         <subject>
7021                                 <hierarchicalGeographic>
7022                                         <xsl:for-each select="marc:subfield[@code='a']">
7023                                                 <country>
7024                                                         <xsl:call-template name="chopPunctuation">
7025                                                                 <xsl:with-param name="chopString" select="."/>
7026                                                         </xsl:call-template>
7027                                                 </country>
7028                                         </xsl:for-each>
7029                                         <xsl:for-each select="marc:subfield[@code='b']">
7030                                                 <state>
7031                                                         <xsl:call-template name="chopPunctuation">
7032                                                                 <xsl:with-param name="chopString" select="."/>
7033                                                         </xsl:call-template>
7034                                                 </state>
7035                                         </xsl:for-each>
7036                                         <xsl:for-each select="marc:subfield[@code='c']">
7037                                                 <county>
7038                                                         <xsl:call-template name="chopPunctuation">
7039                                                                 <xsl:with-param name="chopString" select="."/>
7040                                                         </xsl:call-template>
7041                                                 </county>
7042                                         </xsl:for-each>
7043                                         <xsl:for-each select="marc:subfield[@code='d']">
7044                                                 <city>
7045                                                         <xsl:call-template name="chopPunctuation">
7046                                                                 <xsl:with-param name="chopString" select="."/>
7047                                                         </xsl:call-template>
7048                                                 </city>
7049                                         </xsl:for-each>
7050                                         <xsl:for-each select="marc:subfield[@code='e']">
7051                                                 <citySection>
7052                                                         <xsl:call-template name="chopPunctuation">
7053                                                                 <xsl:with-param name="chopString" select="."/>
7054                                                         </xsl:call-template>
7055                                                 </citySection>
7056                                         </xsl:for-each>
7057                                         <xsl:for-each select="marc:subfield[@code='g']">
7058                                                 <region>
7059                                                         <xsl:call-template name="chopPunctuation">
7060                                                                 <xsl:with-param name="chopString" select="."/>
7061                                                         </xsl:call-template>
7062                                                 </region>
7063                                         </xsl:for-each>
7064                                         <xsl:for-each select="marc:subfield[@code='h']">
7065                                                 <extraterrestrialArea>
7066                                                         <xsl:call-template name="chopPunctuation">
7067                                                                 <xsl:with-param name="chopString" select="."/>
7068                                                         </xsl:call-template>
7069                                                 </extraterrestrialArea>
7070                                         </xsl:for-each>
7071                                 </hierarchicalGeographic>
7072                         </subject>
7073                 </xsl:for-each>
7074                 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
7075                         <subject>
7076                                 <xsl:choose>
7077                                         <xsl:when test="@ind1=2">
7078                                                 <temporal encoding="iso8601" point="start">
7079                                                         <xsl:call-template name="chopPunctuation">
7080                                                                 <xsl:with-param name="chopString">
7081                                                                         <xsl:value-of select="marc:subfield[@code='b'][1]"/>
7082                                                                 </xsl:with-param>
7083                                                         </xsl:call-template>
7084                                                 </temporal>
7085                                                 <temporal encoding="iso8601" point="end">
7086                                                         <xsl:call-template name="chopPunctuation">
7087                                                                 <xsl:with-param name="chopString">
7088                                                                         <xsl:value-of select="marc:subfield[@code='b'][2]"/>
7089                                                                 </xsl:with-param>
7090                                                         </xsl:call-template>
7091                                                 </temporal>
7092                                         </xsl:when>
7093                                         <xsl:otherwise>
7094                                                 <xsl:for-each select="marc:subfield[@code='b']">
7095                                                         <temporal encoding="iso8601">
7096                                                                 <xsl:call-template name="chopPunctuation">
7097                                                                         <xsl:with-param name="chopString" select="."/>
7098                                                                 </xsl:call-template>
7099                                                         </temporal>
7100                                                 </xsl:for-each>
7101                                         </xsl:otherwise>
7102                                 </xsl:choose>
7103                         </subject>
7104                 </xsl:for-each>
7105                 <xsl:for-each select="marc:datafield[@tag=050]">
7106                         <xsl:for-each select="marc:subfield[@code='b']">
7107                                 <classification authority="lcc">
7108                                         <xsl:if test="../marc:subfield[@code='3']">
7109                                                 <xsl:attribute name="displayLabel">
7110                                                         <xsl:value-of select="../marc:subfield[@code='3']"/>
7111                                                 </xsl:attribute>
7112                                         </xsl:if>
7113                                         <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
7114                                         <xsl:text> </xsl:text>
7115                                         <xsl:value-of select="text()"/>
7116                                 </classification>
7117                         </xsl:for-each>
7118                         <xsl:for-each
7119                                 select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
7120                                 <classification authority="lcc">
7121                                         <xsl:if test="../marc:subfield[@code='3']">
7122                                                 <xsl:attribute name="displayLabel">
7123                                                         <xsl:value-of select="../marc:subfield[@code='3']"/>
7124                                                 </xsl:attribute>
7125                                         </xsl:if>
7126                                         <xsl:value-of select="text()"/>
7127                                 </classification>
7128                         </xsl:for-each>
7129                 </xsl:for-each>
7130                 <xsl:for-each select="marc:datafield[@tag=082]">
7131                         <classification authority="ddc">
7132                                 <xsl:if test="marc:subfield[@code='2']">
7133                                         <xsl:attribute name="edition">
7134                                                 <xsl:value-of select="marc:subfield[@code='2']"/>
7135                                         </xsl:attribute>
7136                                 </xsl:if>
7137                                 <xsl:call-template name="subfieldSelect">
7138                                         <xsl:with-param name="codes">ab</xsl:with-param>
7139                                 </xsl:call-template>
7140                         </classification>
7141                 </xsl:for-each>
7142                 <xsl:for-each select="marc:datafield[@tag=080]">
7143                         <classification authority="udc">
7144                                 <xsl:call-template name="subfieldSelect">
7145                                         <xsl:with-param name="codes">abx</xsl:with-param>
7146                                 </xsl:call-template>
7147                         </classification>
7148                 </xsl:for-each>
7149                 <xsl:for-each select="marc:datafield[@tag=060]">
7150                         <classification authority="nlm">
7151                                 <xsl:call-template name="subfieldSelect">
7152                                         <xsl:with-param name="codes">ab</xsl:with-param>
7153                                 </xsl:call-template>
7154                         </classification>
7155                 </xsl:for-each>
7156                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
7157                         <classification authority="sudocs">
7158                                 <xsl:value-of select="marc:subfield[@code='a']"/>
7159                         </classification>
7160                 </xsl:for-each>
7161                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
7162                         <classification authority="candoc">
7163                                 <xsl:value-of select="marc:subfield[@code='a']"/>
7164                         </classification>
7165                 </xsl:for-each>
7166                 <xsl:for-each select="marc:datafield[@tag=086]">
7167                         <classification>
7168                                 <xsl:attribute name="authority">
7169                                         <xsl:value-of select="marc:subfield[@code='2']"/>
7170                                 </xsl:attribute>
7171                                 <xsl:value-of select="marc:subfield[@code='a']"/>
7172                         </classification>
7173                 </xsl:for-each>
7174                 <xsl:for-each select="marc:datafield[@tag=084]">
7175                         <classification>
7176                                 <xsl:attribute name="authority">
7177                                         <xsl:value-of select="marc:subfield[@code='2']"/>
7178                                 </xsl:attribute>
7179                                 <xsl:call-template name="subfieldSelect">
7180                                         <xsl:with-param name="codes">ab</xsl:with-param>
7181                                 </xsl:call-template>
7182                         </classification>
7183                 </xsl:for-each>
7184                 <xsl:for-each select="marc:datafield[@tag=440]">
7185                         <relatedItem type="series">
7186                                 <titleInfo>
7187                                         <title>
7188                                                 <xsl:call-template name="chopPunctuation">
7189                                                         <xsl:with-param name="chopString">
7190                                                                 <xsl:call-template name="subfieldSelect">
7191                                                                         <xsl:with-param name="codes">av</xsl:with-param>
7192                                                                 </xsl:call-template>
7193                                                         </xsl:with-param>
7194                                                 </xsl:call-template>
7195                                         </title>
7196                                         <xsl:call-template name="part"/>
7197                                 </titleInfo>
7198                         </relatedItem>
7199                 </xsl:for-each>
7200                 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
7201                         <relatedItem type="series">
7202                                 <titleInfo>
7203                                         <title>
7204                                                 <xsl:call-template name="chopPunctuation">
7205                                                         <xsl:with-param name="chopString">
7206                                                                 <xsl:call-template name="subfieldSelect">
7207                                                                         <xsl:with-param name="codes">av</xsl:with-param>
7208                                                                 </xsl:call-template>
7209                                                         </xsl:with-param>
7210                                                 </xsl:call-template>
7211                                         </title>
7212                                         <xsl:call-template name="part"/>
7213                                 </titleInfo>
7214                         </relatedItem>
7215                 </xsl:for-each>
7216                 <xsl:for-each select="marc:datafield[@tag=510]">
7217                         <relatedItem type="isReferencedBy">
7218                                 <note>
7219                                         <xsl:call-template name="subfieldSelect">
7220                                                 <xsl:with-param name="codes">abcx3</xsl:with-param>
7221                                         </xsl:call-template>
7222                                 </note>
7223                         </relatedItem>
7224                 </xsl:for-each>
7225                 <xsl:for-each select="marc:datafield[@tag=534]">
7226                         <relatedItem type="original">
7227                                 <xsl:call-template name="relatedTitle"/>
7228                                 <xsl:call-template name="relatedName"/>
7229                                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
7230                                         <originInfo>
7231                                                 <xsl:for-each select="marc:subfield[@code='c']">
7232                                                         <publisher>
7233                                                                 <xsl:value-of select="."/>
7234                                                         </publisher>
7235                                                 </xsl:for-each>
7236                                                 <xsl:for-each select="marc:subfield[@code='b']">
7237                                                         <edition>
7238                                                                 <xsl:value-of select="."/>
7239                                                         </edition>
7240                                                 </xsl:for-each>
7241                                         </originInfo>
7242                                 </xsl:if>
7243                                 <xsl:call-template name="relatedIdentifierISSN"/>
7244                                 <xsl:for-each select="marc:subfield[@code='z']">
7245                                         <identifier type="isbn">
7246                                                 <xsl:value-of select="."/>
7247                                         </identifier>
7248                                 </xsl:for-each>
7249                                 <xsl:call-template name="relatedNote"/>
7250                         </relatedItem>
7251                 </xsl:for-each>
7252                 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
7253                         <relatedItem>
7254                                 <xsl:call-template name="constituentOrRelatedType"/>
7255                                 <titleInfo>
7256                                         <title>
7257                                                 <xsl:call-template name="chopPunctuation">
7258                                                         <xsl:with-param name="chopString">
7259                                                                 <xsl:call-template name="specialSubfieldSelect">
7260                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7261                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7262                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
7263                                                                 </xsl:call-template>
7264                                                         </xsl:with-param>
7265                                                 </xsl:call-template>
7266                                         </title>
7267                                         <xsl:call-template name="part"/>
7268                                 </titleInfo>
7269                                 <name type="personal">
7270                                         <namePart>
7271                                                 <xsl:call-template name="specialSubfieldSelect">
7272                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
7273                                                         <xsl:with-param name="axis">t</xsl:with-param>
7274                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
7275                                                 </xsl:call-template>
7276                                         </namePart>
7277                                         <xsl:call-template name="termsOfAddress"/>
7278                                         <xsl:call-template name="nameDate"/>
7279                                         <xsl:call-template name="role"/>
7280                                 </name>
7281                                 <xsl:call-template name="relatedForm"/>
7282                                 <xsl:call-template name="relatedIdentifierISSN"/>
7283                         </relatedItem>
7284                 </xsl:for-each>
7285                 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
7286                         <relatedItem>
7287                                 <xsl:call-template name="constituentOrRelatedType"/>
7288                                 <titleInfo>
7289                                         <title>
7290                                                 <xsl:call-template name="chopPunctuation">
7291                                                         <xsl:with-param name="chopString">
7292                                                                 <xsl:call-template name="specialSubfieldSelect">
7293                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7294                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7295                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
7296                                                                 </xsl:call-template>
7297                                                         </xsl:with-param>
7298                                                 </xsl:call-template>
7299                                         </title>
7300                                         <xsl:call-template name="relatedPartNumName"/>
7301                                 </titleInfo>
7302                                 <name type="corporate">
7303                                         <xsl:for-each select="marc:subfield[@code='a']">
7304                                                 <namePart>
7305                                                         <xsl:value-of select="."/>
7306                                                 </namePart>
7307                                         </xsl:for-each>
7308                                         <xsl:for-each select="marc:subfield[@code='b']">
7309                                                 <namePart>
7310                                                         <xsl:value-of select="."/>
7311                                                 </namePart>
7312                                         </xsl:for-each>
7313                                         <xsl:variable name="tempNamePart">
7314                                                 <xsl:call-template name="specialSubfieldSelect">
7315                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
7316                                                         <xsl:with-param name="axis">t</xsl:with-param>
7317                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
7318                                                 </xsl:call-template>
7319                                         </xsl:variable>
7320                                         <xsl:if test="normalize-space($tempNamePart)">
7321                                                 <namePart>
7322                                                         <xsl:value-of select="$tempNamePart"/>
7323                                                 </namePart>
7324                                         </xsl:if>
7325                                         <xsl:call-template name="role"/>
7326                                 </name>
7327                                 <xsl:call-template name="relatedForm"/>
7328                                 <xsl:call-template name="relatedIdentifierISSN"/>
7329                         </relatedItem>
7330                 </xsl:for-each>
7331                 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
7332                         <relatedItem>
7333                                 <xsl:call-template name="constituentOrRelatedType"/>
7334                                 <titleInfo>
7335                                         <title>
7336                                                 <xsl:call-template name="chopPunctuation">
7337                                                         <xsl:with-param name="chopString">
7338                                                                 <xsl:call-template name="specialSubfieldSelect">
7339                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
7340                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7341                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
7342                                                                 </xsl:call-template>
7343                                                         </xsl:with-param>
7344                                                 </xsl:call-template>
7345                                         </title>
7346                                         <xsl:call-template name="relatedPartNumName"/>
7347                                 </titleInfo>
7348                                 <name type="conference">
7349                                         <namePart>
7350                                                 <xsl:call-template name="specialSubfieldSelect">
7351                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
7352                                                         <xsl:with-param name="axis">t</xsl:with-param>
7353                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
7354                                                 </xsl:call-template>
7355                                         </namePart>
7356                                 </name>
7357                                 <xsl:call-template name="relatedForm"/>
7358                                 <xsl:call-template name="relatedIdentifierISSN"/>
7359                         </relatedItem>
7360                 </xsl:for-each>
7361                 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
7362                         <relatedItem>
7363                                 <xsl:call-template name="constituentOrRelatedType"/>
7364                                 <titleInfo>
7365                                         <title>
7366                                                 <xsl:call-template name="chopPunctuation">
7367                                                         <xsl:with-param name="chopString">
7368                                                                 <xsl:call-template name="subfieldSelect">
7369                                                                         <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
7370                                                                 </xsl:call-template>
7371                                                         </xsl:with-param>
7372                                                 </xsl:call-template>
7373                                         </title>
7374                                         <xsl:call-template name="part"/>
7375                                 </titleInfo>
7376                                 <xsl:call-template name="relatedForm"/>
7377                                 <xsl:call-template name="relatedIdentifierISSN"/>
7378                         </relatedItem>
7379                 </xsl:for-each>
7380                 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
7381                         <relatedItem>
7382                                 <xsl:call-template name="constituentOrRelatedType"/>
7383                                 <titleInfo>
7384                                         <title>
7385                                                 <xsl:call-template name="chopPunctuation">
7386                                                         <xsl:with-param name="chopString">
7387                                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
7388                                                         </xsl:with-param>
7389                                                 </xsl:call-template>
7390                                         </title>
7391                                         <xsl:call-template name="part"/>
7392                                 </titleInfo>
7393                                 <xsl:call-template name="relatedForm"/>
7394                         </relatedItem>
7395                 </xsl:for-each>
7396                 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
7397                         <relatedItem type="series">
7398                                 <xsl:call-template name="relatedItem76X-78X"/>
7399                         </relatedItem>
7400                 </xsl:for-each>
7401                 <xsl:for-each
7402                         select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
7403                         <relatedItem>
7404                                 <xsl:call-template name="relatedItem76X-78X"/>
7405                         </relatedItem>
7406                 </xsl:for-each>
7407                 <xsl:for-each select="marc:datafield[@tag=775]">
7408                         <relatedItem type="otherVersion">
7409                                 <xsl:call-template name="relatedItem76X-78X"/>
7410                         </relatedItem>
7411                 </xsl:for-each>
7412                 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
7413                         <relatedItem type="constituent">
7414                                 <xsl:call-template name="relatedItem76X-78X"/>
7415                         </relatedItem>
7416                 </xsl:for-each>
7417                 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
7418                         <relatedItem type="host">
7419                                 <xsl:call-template name="relatedItem76X-78X"/>
7420                         </relatedItem>
7421                 </xsl:for-each>
7422                 <xsl:for-each select="marc:datafield[@tag=776]">
7423                         <relatedItem type="otherFormat">
7424                                 <xsl:call-template name="relatedItem76X-78X"/>
7425                         </relatedItem>
7426                 </xsl:for-each>
7427                 <xsl:for-each select="marc:datafield[@tag=780]">
7428                         <relatedItem type="preceding">
7429                                 <xsl:call-template name="relatedItem76X-78X"/>
7430                         </relatedItem>
7431                 </xsl:for-each>
7432                 <xsl:for-each select="marc:datafield[@tag=785]">
7433                         <relatedItem type="succeeding">
7434                                 <xsl:call-template name="relatedItem76X-78X"/>
7435                         </relatedItem>
7436                 </xsl:for-each>
7437                 <xsl:for-each select="marc:datafield[@tag=786]">
7438                         <relatedItem type="original">
7439                                 <xsl:call-template name="relatedItem76X-78X"/>
7440                         </relatedItem>
7441                 </xsl:for-each>
7442                 <xsl:for-each select="marc:datafield[@tag=800]">
7443                         <relatedItem type="series">
7444                                 <titleInfo>
7445                                         <title>
7446                                                 <xsl:call-template name="chopPunctuation">
7447                                                         <xsl:with-param name="chopString">
7448                                                                 <xsl:call-template name="specialSubfieldSelect">
7449                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7450                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7451                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
7452                                                                 </xsl:call-template>
7453                                                         </xsl:with-param>
7454                                                 </xsl:call-template>
7455                                         </title>
7456                                         <xsl:call-template name="part"/>
7457                                 </titleInfo>
7458                                 <name type="personal">
7459                                         <namePart>
7460                                                 <xsl:call-template name="chopPunctuation">
7461                                                         <xsl:with-param name="chopString">
7462                                                                 <xsl:call-template name="specialSubfieldSelect">
7463                                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
7464                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7465                                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
7466                                                                 </xsl:call-template>
7467                                                         </xsl:with-param>
7468                                                 </xsl:call-template>
7469                                         </namePart>
7470                                         <xsl:call-template name="termsOfAddress"/>
7471                                         <xsl:call-template name="nameDate"/>
7472                                         <xsl:call-template name="role"/>
7473                                 </name>
7474                                 <xsl:call-template name="relatedForm"/>
7475                         </relatedItem>
7476                 </xsl:for-each>
7477                 <xsl:for-each select="marc:datafield[@tag=810]">
7478                         <relatedItem type="series">
7479                                 <titleInfo>
7480                                         <title>
7481                                                 <xsl:call-template name="chopPunctuation">
7482                                                         <xsl:with-param name="chopString">
7483                                                                 <xsl:call-template name="specialSubfieldSelect">
7484                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7485                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7486                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
7487                                                                 </xsl:call-template>
7488                                                         </xsl:with-param>
7489                                                 </xsl:call-template>
7490                                         </title>
7491                                         <xsl:call-template name="relatedPartNumName"/>
7492                                 </titleInfo>
7493                                 <name type="corporate">
7494                                         <xsl:for-each select="marc:subfield[@code='a']">
7495                                                 <namePart>
7496                                                         <xsl:value-of select="."/>
7497                                                 </namePart>
7498                                         </xsl:for-each>
7499                                         <xsl:for-each select="marc:subfield[@code='b']">
7500                                                 <namePart>
7501                                                         <xsl:value-of select="."/>
7502                                                 </namePart>
7503                                         </xsl:for-each>
7504                                         <namePart>
7505                                                 <xsl:call-template name="specialSubfieldSelect">
7506                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
7507                                                         <xsl:with-param name="axis">t</xsl:with-param>
7508                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
7509                                                 </xsl:call-template>
7510                                         </namePart>
7511                                         <xsl:call-template name="role"/>
7512                                 </name>
7513                                 <xsl:call-template name="relatedForm"/>
7514                         </relatedItem>
7515                 </xsl:for-each>
7516                 <xsl:for-each select="marc:datafield[@tag=811]">
7517                         <relatedItem type="series">
7518                                 <titleInfo>
7519                                         <title>
7520                                                 <xsl:call-template name="chopPunctuation">
7521                                                         <xsl:with-param name="chopString">
7522                                                                 <xsl:call-template name="specialSubfieldSelect">
7523                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
7524                                                                         <xsl:with-param name="axis">t</xsl:with-param>
7525                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
7526                                                                 </xsl:call-template>
7527                                                         </xsl:with-param>
7528                                                 </xsl:call-template>
7529                                         </title>
7530                                         <xsl:call-template name="relatedPartNumName"/>
7531                                 </titleInfo>
7532                                 <name type="conference">
7533                                         <namePart>
7534                                                 <xsl:call-template name="specialSubfieldSelect">
7535                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
7536                                                         <xsl:with-param name="axis">t</xsl:with-param>
7537                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
7538                                                 </xsl:call-template>
7539                                         </namePart>
7540                                         <xsl:call-template name="role"/>
7541                                 </name>
7542                                 <xsl:call-template name="relatedForm"/>
7543                         </relatedItem>
7544                 </xsl:for-each>
7545                 <xsl:for-each select="marc:datafield[@tag='830']">
7546                         <relatedItem type="series">
7547                                 <titleInfo>
7548                                         <title>
7549                                                 <xsl:call-template name="chopPunctuation">
7550                                                         <xsl:with-param name="chopString">
7551                                                                 <xsl:call-template name="subfieldSelect">
7552                                                                         <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
7553                                                                 </xsl:call-template>
7554                                                         </xsl:with-param>
7555                                                 </xsl:call-template>
7556                                         </title>
7557                                         <xsl:call-template name="part"/>
7558                                 </titleInfo>
7559                                 <xsl:call-template name="relatedForm"/>
7560                         </relatedItem>
7561                 </xsl:for-each>
7562                 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
7563                         <relatedItem>
7564                                 <internetMediaType>
7565                                         <xsl:value-of select="."/>
7566                                 </internetMediaType>
7567                         </relatedItem>
7568                 </xsl:for-each>
7569                 <xsl:for-each select="marc:datafield[@tag='020']">
7570                         <xsl:call-template name="isInvalid">
7571                                 <xsl:with-param name="type">isbn</xsl:with-param>
7572                         </xsl:call-template>
7573                         <xsl:if test="marc:subfield[@code='a']">
7574                                 <identifier type="isbn">
7575                                         <xsl:value-of select="marc:subfield[@code='a']"/>
7576                                 </identifier>
7577                         </xsl:if>
7578                 </xsl:for-each>
7579                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
7580                         <xsl:call-template name="isInvalid">
7581                                 <xsl:with-param name="type">isrc</xsl:with-param>
7582                         </xsl:call-template>
7583                         <xsl:if test="marc:subfield[@code='a']">
7584                                 <identifier type="isrc">
7585                                         <xsl:value-of select="marc:subfield[@code='a']"/>
7586                                 </identifier>
7587                         </xsl:if>
7588                 </xsl:for-each>
7589                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
7590                         <xsl:call-template name="isInvalid">
7591                                 <xsl:with-param name="type">ismn</xsl:with-param>
7592                         </xsl:call-template>
7593                         <xsl:if test="marc:subfield[@code='a']">
7594                                 <identifier type="ismn">
7595                                         <xsl:value-of select="marc:subfield[@code='a']"/>
7596                                 </identifier>
7597                         </xsl:if>
7598                 </xsl:for-each>
7599                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
7600                         <xsl:call-template name="isInvalid">
7601                                 <xsl:with-param name="type">sici</xsl:with-param>
7602                         </xsl:call-template>
7603                         <identifier type="sici">
7604                                 <xsl:call-template name="subfieldSelect">
7605                                         <xsl:with-param name="codes">ab</xsl:with-param>
7606                                 </xsl:call-template>
7607                         </identifier>
7608                 </xsl:for-each>
7609                 <xsl:for-each select="marc:datafield[@tag='022']">
7610                         <xsl:if test="marc:subfield[@code='a']">
7611                                 <xsl:call-template name="isInvalid">
7612                                         <xsl:with-param name="type">issn</xsl:with-param>
7613                                 </xsl:call-template>
7614                                 <identifier type="issn">
7615                                         <xsl:value-of select="marc:subfield[@code='a']"/>
7616                                 </identifier>
7617                         </xsl:if>
7618                         <xsl:if test="marc:subfield[@code='l']">
7619                                 <xsl:call-template name="isInvalid">
7620                                         <xsl:with-param name="type">issn-l</xsl:with-param>
7621                                 </xsl:call-template>
7622                                 <identifier type="issn-l">
7623                                         <xsl:value-of select="marc:subfield[@code='l']"/>
7624                                 </identifier>
7625                         </xsl:if>
7626                 </xsl:for-each>
7627
7628
7629
7630                 <xsl:for-each select="marc:datafield[@tag='010']">
7631                         <xsl:call-template name="isInvalid">
7632                                 <xsl:with-param name="type">lccn</xsl:with-param>
7633                         </xsl:call-template>
7634                         <identifier type="lccn">
7635                                 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
7636                         </identifier>
7637                 </xsl:for-each>
7638                 <xsl:for-each select="marc:datafield[@tag='028']">
7639                         <identifier>
7640                                 <xsl:attribute name="type">
7641                                         <xsl:choose>
7642                                                 <xsl:when test="@ind1='0'">issue number</xsl:when>
7643                                                 <xsl:when test="@ind1='1'">matrix number</xsl:when>
7644                                                 <xsl:when test="@ind1='2'">music plate</xsl:when>
7645                                                 <xsl:when test="@ind1='3'">music publisher</xsl:when>
7646                                                 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
7647                                         </xsl:choose>
7648                                 </xsl:attribute>
7649                                 <!--<xsl:call-template name="isInvalid"/>-->
7650                                 <!-- no $z in 028 -->
7651                                 <xsl:call-template name="subfieldSelect">
7652                                         <xsl:with-param name="codes">
7653                                                 <xsl:choose>
7654                                                         <xsl:when test="@ind1='0'">ba</xsl:when>
7655                                                         <xsl:otherwise>ab</xsl:otherwise>
7656                                                 </xsl:choose>
7657                                         </xsl:with-param>
7658                                 </xsl:call-template>
7659                         </identifier>
7660                 </xsl:for-each>
7661                 <xsl:for-each select="marc:datafield[@tag='037']">
7662                         <identifier type="stock number">
7663                                 <!--<xsl:call-template name="isInvalid"/>-->
7664                                 <!-- no $z in 037 -->
7665                                 <xsl:call-template name="subfieldSelect">
7666                                         <xsl:with-param name="codes">ab</xsl:with-param>
7667                                 </xsl:call-template>
7668                         </identifier>
7669                 </xsl:for-each>
7670                 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
7671                         <identifier>
7672                                 <xsl:attribute name="type">
7673                                         <xsl:choose>
7674                                                 <xsl:when
7675                                                         test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')"
7676                                                         >doi</xsl:when>
7677                                                 <xsl:when
7678                                                         test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')"
7679                                                         >hdl</xsl:when>
7680                                                 <xsl:otherwise>uri</xsl:otherwise>
7681                                         </xsl:choose>
7682                                 </xsl:attribute>
7683                                 <xsl:choose>
7684                                         <xsl:when
7685                                                 test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
7686                                                 <xsl:value-of
7687                                                         select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
7688                                                 />
7689                                         </xsl:when>
7690                                         <xsl:otherwise>
7691                                                 <xsl:value-of select="marc:subfield[@code='u']"/>
7692                                         </xsl:otherwise>
7693                                 </xsl:choose>
7694                         </identifier>
7695                         <xsl:if
7696                                 test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
7697                                 <identifier type="hdl">
7698                                         <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
7699                                                 <xsl:attribute name="displayLabel">
7700                                                         <xsl:call-template name="subfieldSelect">
7701                                                                 <xsl:with-param name="codes">y3z</xsl:with-param>
7702                                                         </xsl:call-template>
7703                                                 </xsl:attribute>
7704                                         </xsl:if>
7705                                         <xsl:value-of
7706                                                 select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
7707                                         />
7708                                 </identifier>
7709                         </xsl:if>
7710                 </xsl:for-each>
7711                 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
7712                         <identifier type="upc">
7713                                 <xsl:call-template name="isInvalid"/>
7714                                 <xsl:value-of select="marc:subfield[@code='a']"/>
7715                         </identifier>
7716                 </xsl:for-each>
7717
7718                 <!-- 1/04 fix added $y -->
7719
7720                 <!-- 1.21  tmee-->
7721                 <xsl:for-each select="marc:datafield[@tag=856][@ind2=1][marc:subfield[@code='u']]">
7722                         <relatedItem type="otherVersion">
7723                                 <location>
7724                                         <url>
7725                                                 <xsl:if test="marc:subfield[@code='y' or @code='3']">
7726                                                         <xsl:attribute name="displayLabel">
7727                                                                 <xsl:call-template name="subfieldSelect">
7728                                                                         <xsl:with-param name="codes">y3</xsl:with-param>
7729                                                                 </xsl:call-template>
7730                                                         </xsl:attribute>
7731                                                 </xsl:if>
7732                                                 <xsl:if test="marc:subfield[@code='z' ]">
7733                                                         <xsl:attribute name="note">
7734                                                                 <xsl:call-template name="subfieldSelect">
7735                                                                         <xsl:with-param name="codes">z</xsl:with-param>
7736                                                                 </xsl:call-template>
7737                                                         </xsl:attribute>
7738                                                 </xsl:if>
7739                                                 <xsl:value-of select="marc:subfield[@code='u']"/>
7740                                         </url>
7741                                 </location>
7742                         </relatedItem>
7743                 </xsl:for-each>
7744                 <xsl:for-each select="marc:datafield[@tag=856][@ind2=2][marc:subfield[@code='u']]">
7745                         <relatedItem>
7746                                 <location>
7747                                         <url>
7748                                                 <xsl:if test="marc:subfield[@code='y' or @code='3']">
7749                                                         <xsl:attribute name="displayLabel">
7750                                                                 <xsl:call-template name="subfieldSelect">
7751                                                                         <xsl:with-param name="codes">y3</xsl:with-param>
7752                                                                 </xsl:call-template>
7753                                                         </xsl:attribute>
7754                                                 </xsl:if>
7755                                                 <xsl:if test="marc:subfield[@code='z' ]">
7756                                                         <xsl:attribute name="note">
7757                                                                 <xsl:call-template name="subfieldSelect">
7758                                                                         <xsl:with-param name="codes">z</xsl:with-param>
7759                                                                 </xsl:call-template>
7760                                                         </xsl:attribute>
7761                                                 </xsl:if>
7762                                                 <xsl:value-of select="marc:subfield[@code='u']"/>
7763                                         </url>
7764                                 </location>
7765                         </relatedItem>
7766                 </xsl:for-each>
7767
7768                 <!-- 3.2 change tmee 856z  -->
7769
7770                 <!-- 1.24  tmee  -->
7771                 <xsl:for-each select="marc:datafield[@tag=852]">
7772                         <location>
7773                                 <xsl:if test="marc:subfield[@code='a' or @code='b' or @code='e']">
7774                                         <physicalLocation>
7775                                                 <xsl:call-template name="subfieldSelect">
7776                                                         <xsl:with-param name="codes">abe</xsl:with-param>
7777                                                 </xsl:call-template>
7778                                         </physicalLocation>
7779                                 </xsl:if>
7780
7781                                 <xsl:if test="marc:subfield[@code='u']">
7782                                         <physicalLocation>
7783                                                 <xsl:call-template name="uri"/>
7784                                                 <xsl:call-template name="subfieldSelect">
7785                                                         <xsl:with-param name="codes">u</xsl:with-param>
7786                                                 </xsl:call-template>
7787                                         </physicalLocation>
7788                                 </xsl:if>
7789
7790                                 <xsl:if
7791                                         test="marc:subfield[@code='h' or @code='i' or @code='j' or @code='k' or @code='l' or @code='m' or @code='t']">
7792                                         <shelfLocation>
7793                                                 <xsl:call-template name="subfieldSelect">
7794                                                         <xsl:with-param name="codes">hijklmt</xsl:with-param>
7795                                                 </xsl:call-template>
7796                                         </shelfLocation>
7797                                 </xsl:if>
7798                         </location>
7799                 </xsl:for-each>
7800
7801                 <xsl:for-each select="marc:datafield[@tag=506]">
7802                         <accessCondition type="restrictionOnAccess">
7803                                 <xsl:call-template name="subfieldSelect">
7804                                         <xsl:with-param name="codes">abcd35</xsl:with-param>
7805                                 </xsl:call-template>
7806                         </accessCondition>
7807                 </xsl:for-each>
7808                 <xsl:for-each select="marc:datafield[@tag=540]">
7809                         <accessCondition type="useAndReproduction">
7810                                 <xsl:call-template name="subfieldSelect">
7811                                         <xsl:with-param name="codes">abcde35</xsl:with-param>
7812                                 </xsl:call-template>
7813                         </accessCondition>
7814                 </xsl:for-each>
7815
7816                 <recordInfo>
7817                         <!-- 1.25  tmee-->
7818
7819
7820                         <xsl:for-each select="marc:leader[substring($leader,19,1)='a']">
7821                                 <descriptionStandard>aacr2</descriptionStandard>
7822                         </xsl:for-each>
7823
7824                         <xsl:for-each select="marc:datafield[@tag=040]">
7825                                 <xsl:if test="marc:subfield[@code='e']">
7826                                         <descriptionStandard>
7827                                                 <xsl:value-of select="marc:subfield[@code='e']"/>
7828                                         </descriptionStandard>
7829                                 </xsl:if>
7830                                 <recordContentSource authority="marcorg">
7831                                         <xsl:value-of select="marc:subfield[@code='a']"/>
7832                                 </recordContentSource>
7833                         </xsl:for-each>
7834                         <xsl:for-each select="marc:controlfield[@tag=008]">
7835                                 <recordCreationDate encoding="marc">
7836                                         <xsl:value-of select="substring(.,1,6)"/>
7837                                 </recordCreationDate>
7838                         </xsl:for-each>
7839
7840                         <xsl:for-each select="marc:controlfield[@tag=005]">
7841                                 <recordChangeDate encoding="iso8601">
7842                                         <xsl:value-of select="."/>
7843                                 </recordChangeDate>
7844                         </xsl:for-each>
7845                         <xsl:for-each select="marc:controlfield[@tag=001]">
7846                                 <recordIdentifier>
7847                                         <xsl:if test="../marc:controlfield[@tag=003]">
7848                                                 <xsl:attribute name="source">
7849                                                         <xsl:value-of select="../marc:controlfield[@tag=003]"/>
7850                                                 </xsl:attribute>
7851                                         </xsl:if>
7852                                         <xsl:value-of select="."/>
7853                                 </recordIdentifier>
7854                         </xsl:for-each>
7855                         <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
7856                                 <languageOfCataloging>
7857                                         <languageTerm authority="iso639-2b" type="code">
7858                                                 <xsl:value-of select="."/>
7859                                         </languageTerm>
7860                                 </languageOfCataloging>
7861                         </xsl:for-each>
7862                 </recordInfo>
7863         </xsl:template>
7864         <xsl:template name="displayForm">
7865                 <xsl:for-each select="marc:subfield[@code='c']">
7866                         <displayForm>
7867                                 <xsl:value-of select="."/>
7868                         </displayForm>
7869                 </xsl:for-each>
7870         </xsl:template>
7871         <xsl:template name="affiliation">
7872                 <xsl:for-each select="marc:subfield[@code='u']">
7873                         <affiliation>
7874                                 <xsl:value-of select="."/>
7875                         </affiliation>
7876                 </xsl:for-each>
7877         </xsl:template>
7878         <xsl:template name="uri">
7879                 <xsl:for-each select="marc:subfield[@code='u']">
7880                         <xsl:attribute name="xlink:href">
7881                                 <xsl:value-of select="."/>
7882                         </xsl:attribute>
7883                 </xsl:for-each>
7884                 <xsl:for-each select="marc:subfield[@code='0']">
7885                         <xsl:choose>
7886                                 <xsl:when test="contains(text(), ')')">
7887                                         <xsl:attribute name="xlink:href">
7888                                                 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
7889                                         </xsl:attribute>
7890                                 </xsl:when>
7891                                 <xsl:otherwise>
7892                                         <xsl:attribute name="xlink:href">
7893                                                 <xsl:value-of select="."></xsl:value-of>
7894                                         </xsl:attribute>
7895                                 </xsl:otherwise>
7896                         </xsl:choose>
7897                 </xsl:for-each>
7898         </xsl:template>
7899         <xsl:template name="role">
7900                 <xsl:for-each select="marc:subfield[@code='e']">
7901                         <role>
7902                                 <roleTerm type="text">
7903                                         <xsl:value-of select="."/>
7904                                 </roleTerm>
7905                         </role>
7906                 </xsl:for-each>
7907                 <xsl:for-each select="marc:subfield[@code='4']">
7908                         <role>
7909                                 <roleTerm authority="marcrelator" type="code">
7910                                         <xsl:value-of select="."/>
7911                                 </roleTerm>
7912                         </role>
7913                 </xsl:for-each>
7914         </xsl:template>
7915         <xsl:template name="part">
7916                 <xsl:variable name="partNumber">
7917                         <xsl:call-template name="specialSubfieldSelect">
7918                                 <xsl:with-param name="axis">n</xsl:with-param>
7919                                 <xsl:with-param name="anyCodes">n</xsl:with-param>
7920                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
7921                         </xsl:call-template>
7922                 </xsl:variable>
7923                 <xsl:variable name="partName">
7924                         <xsl:call-template name="specialSubfieldSelect">
7925                                 <xsl:with-param name="axis">p</xsl:with-param>
7926                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
7927                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
7928                         </xsl:call-template>
7929                 </xsl:variable>
7930                 <xsl:if test="string-length(normalize-space($partNumber))">
7931                         <partNumber>
7932                                 <xsl:call-template name="chopPunctuation">
7933                                         <xsl:with-param name="chopString" select="$partNumber"/>
7934                                 </xsl:call-template>
7935                         </partNumber>
7936                 </xsl:if>
7937                 <xsl:if test="string-length(normalize-space($partName))">
7938                         <partName>
7939                                 <xsl:call-template name="chopPunctuation">
7940                                         <xsl:with-param name="chopString" select="$partName"/>
7941                                 </xsl:call-template>
7942                         </partName>
7943                 </xsl:if>
7944         </xsl:template>
7945         <xsl:template name="relatedPart">
7946                 <xsl:if test="@tag=773">
7947                         <xsl:for-each select="marc:subfield[@code='g']">
7948                                 <part>
7949                                         <text>
7950                                                 <xsl:value-of select="."/>
7951                                         </text>
7952                                 </part>
7953                         </xsl:for-each>
7954                         <xsl:for-each select="marc:subfield[@code='q']">
7955                                 <part>
7956                                         <xsl:call-template name="parsePart"/>
7957                                 </part>
7958                         </xsl:for-each>
7959                 </xsl:if>
7960         </xsl:template>
7961         <xsl:template name="relatedPartNumName">
7962                 <xsl:variable name="partNumber">
7963                         <xsl:call-template name="specialSubfieldSelect">
7964                                 <xsl:with-param name="axis">g</xsl:with-param>
7965                                 <xsl:with-param name="anyCodes">g</xsl:with-param>
7966                                 <xsl:with-param name="afterCodes">pst</xsl:with-param>
7967                         </xsl:call-template>
7968                 </xsl:variable>
7969                 <xsl:variable name="partName">
7970                         <xsl:call-template name="specialSubfieldSelect">
7971                                 <xsl:with-param name="axis">p</xsl:with-param>
7972                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
7973                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
7974                         </xsl:call-template>
7975                 </xsl:variable>
7976                 <xsl:if test="string-length(normalize-space($partNumber))">
7977                         <partNumber>
7978                                 <xsl:value-of select="$partNumber"/>
7979                         </partNumber>
7980                 </xsl:if>
7981                 <xsl:if test="string-length(normalize-space($partName))">
7982                         <partName>
7983                                 <xsl:value-of select="$partName"/>
7984                         </partName>
7985                 </xsl:if>
7986         </xsl:template>
7987         <xsl:template name="relatedName">
7988                 <xsl:for-each select="marc:subfield[@code='a']">
7989                         <name>
7990                                 <namePart>
7991                                         <xsl:value-of select="."/>
7992                                 </namePart>
7993                         </name>
7994                 </xsl:for-each>
7995         </xsl:template>
7996         <xsl:template name="relatedForm">
7997                 <xsl:for-each select="marc:subfield[@code='h']">
7998                         <physicalDescription>
7999                                 <form>
8000                                         <xsl:value-of select="."/>
8001                                 </form>
8002                         </physicalDescription>
8003                 </xsl:for-each>
8004         </xsl:template>
8005         <xsl:template name="relatedExtent">
8006                 <xsl:for-each select="marc:subfield[@code='h']">
8007                         <physicalDescription>
8008                                 <extent>
8009                                         <xsl:value-of select="."/>
8010                                 </extent>
8011                         </physicalDescription>
8012                 </xsl:for-each>
8013         </xsl:template>
8014         <xsl:template name="relatedNote">
8015                 <xsl:for-each select="marc:subfield[@code='n']">
8016                         <note>
8017                                 <xsl:value-of select="."/>
8018                         </note>
8019                 </xsl:for-each>
8020         </xsl:template>
8021         <xsl:template name="relatedSubject">
8022                 <xsl:for-each select="marc:subfield[@code='j']">
8023                         <subject>
8024                                 <temporal encoding="iso8601">
8025                                         <xsl:call-template name="chopPunctuation">
8026                                                 <xsl:with-param name="chopString" select="."/>
8027                                         </xsl:call-template>
8028                                 </temporal>
8029                         </subject>
8030                 </xsl:for-each>
8031         </xsl:template>
8032         <xsl:template name="relatedIdentifierISSN">
8033                 <xsl:for-each select="marc:subfield[@code='x']">
8034                         <identifier type="issn">
8035                                 <xsl:value-of select="."/>
8036                         </identifier>
8037                 </xsl:for-each>
8038         </xsl:template>
8039         <xsl:template name="relatedIdentifierLocal">
8040                 <xsl:for-each select="marc:subfield[@code='w']">
8041                         <identifier type="local">
8042                                 <xsl:value-of select="."/>
8043                         </identifier>
8044                 </xsl:for-each>
8045         </xsl:template>
8046         <xsl:template name="relatedIdentifier">
8047                 <xsl:for-each select="marc:subfield[@code='o']">
8048                         <identifier>
8049                                 <xsl:value-of select="."/>
8050                         </identifier>
8051                 </xsl:for-each>
8052         </xsl:template>
8053         <xsl:template name="relatedItem76X-78X">
8054                 <xsl:call-template name="displayLabel"/>
8055                 <xsl:call-template name="relatedTitle76X-78X"/>
8056                 <xsl:call-template name="relatedName"/>
8057                 <xsl:call-template name="relatedOriginInfo"/>
8058                 <xsl:call-template name="relatedLanguage"/>
8059                 <xsl:call-template name="relatedExtent"/>
8060                 <xsl:call-template name="relatedNote"/>
8061                 <xsl:call-template name="relatedSubject"/>
8062                 <xsl:call-template name="relatedIdentifier"/>
8063                 <xsl:call-template name="relatedIdentifierISSN"/>
8064                 <xsl:call-template name="relatedIdentifierLocal"/>
8065                 <xsl:call-template name="relatedPart"/>
8066         </xsl:template>
8067         <xsl:template name="subjectGeographicZ">
8068                 <geographic>
8069                         <xsl:call-template name="chopPunctuation">
8070                                 <xsl:with-param name="chopString" select="."/>
8071                         </xsl:call-template>
8072                 </geographic>
8073         </xsl:template>
8074         <xsl:template name="subjectTemporalY">
8075                 <temporal>
8076                         <xsl:call-template name="chopPunctuation">
8077                                 <xsl:with-param name="chopString" select="."/>
8078                         </xsl:call-template>
8079                 </temporal>
8080         </xsl:template>
8081         <xsl:template name="subjectTopic">
8082                 <topic>
8083                         <xsl:call-template name="chopPunctuation">
8084                                 <xsl:with-param name="chopString" select="."/>
8085                         </xsl:call-template>
8086                 </topic>
8087         </xsl:template>
8088         <!-- 3.2 change tmee 6xx $v genre -->
8089         <xsl:template name="subjectGenre">
8090                 <genre>
8091                         <xsl:call-template name="chopPunctuation">
8092                                 <xsl:with-param name="chopString" select="."/>
8093                         </xsl:call-template>
8094                 </genre>
8095         </xsl:template>
8096
8097         <xsl:template name="nameABCDN">
8098                 <xsl:for-each select="marc:subfield[@code='a']">
8099                         <namePart>
8100                                 <xsl:call-template name="chopPunctuation">
8101                                         <xsl:with-param name="chopString" select="."/>
8102                                 </xsl:call-template>
8103                         </namePart>
8104                 </xsl:for-each>
8105                 <xsl:for-each select="marc:subfield[@code='b']">
8106                         <namePart>
8107                                 <xsl:value-of select="."/>
8108                         </namePart>
8109                 </xsl:for-each>
8110                 <xsl:if
8111                         test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
8112                         <namePart>
8113                                 <xsl:call-template name="subfieldSelect">
8114                                         <xsl:with-param name="codes">cdn</xsl:with-param>
8115                                 </xsl:call-template>
8116                         </namePart>
8117                 </xsl:if>
8118         </xsl:template>
8119         <xsl:template name="nameABCDQ">
8120                 <namePart>
8121                         <xsl:call-template name="chopPunctuation">
8122                                 <xsl:with-param name="chopString">
8123                                         <xsl:call-template name="subfieldSelect">
8124                                                 <xsl:with-param name="codes">aq</xsl:with-param>
8125                                         </xsl:call-template>
8126                                 </xsl:with-param>
8127                                 <xsl:with-param name="punctuation">
8128                                         <xsl:text>:,;/ </xsl:text>
8129                                 </xsl:with-param>
8130                         </xsl:call-template>
8131                 </namePart>
8132                 <xsl:call-template name="termsOfAddress"/>
8133                 <xsl:call-template name="nameDate"/>
8134         </xsl:template>
8135         <xsl:template name="nameACDEQ">
8136                 <namePart>
8137                         <xsl:call-template name="subfieldSelect">
8138                                 <xsl:with-param name="codes">acdeq</xsl:with-param>
8139                         </xsl:call-template>
8140                 </namePart>
8141         </xsl:template>
8142         <xsl:template name="constituentOrRelatedType">
8143                 <xsl:if test="@ind2=2">
8144                         <xsl:attribute name="type">constituent</xsl:attribute>
8145                 </xsl:if>
8146         </xsl:template>
8147         <xsl:template name="relatedTitle">
8148                 <xsl:for-each select="marc:subfield[@code='t']">
8149                         <titleInfo>
8150                                 <title>
8151                                         <xsl:call-template name="chopPunctuation">
8152                                                 <xsl:with-param name="chopString">
8153                                                         <xsl:value-of select="."/>
8154                                                 </xsl:with-param>
8155                                         </xsl:call-template>
8156                                 </title>
8157                         </titleInfo>
8158                 </xsl:for-each>
8159         </xsl:template>
8160         <xsl:template name="relatedTitle76X-78X">
8161                 <xsl:for-each select="marc:subfield[@code='t']">
8162                         <titleInfo>
8163                                 <title>
8164                                         <xsl:call-template name="chopPunctuation">
8165                                                 <xsl:with-param name="chopString">
8166                                                         <xsl:value-of select="."/>
8167                                                 </xsl:with-param>
8168                                         </xsl:call-template>
8169                                 </title>
8170                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8171                                         <xsl:call-template name="relatedPartNumName"/>
8172                                 </xsl:if>
8173                         </titleInfo>
8174                 </xsl:for-each>
8175                 <xsl:for-each select="marc:subfield[@code='p']">
8176                         <titleInfo type="abbreviated">
8177                                 <title>
8178                                         <xsl:call-template name="chopPunctuation">
8179                                                 <xsl:with-param name="chopString">
8180                                                         <xsl:value-of select="."/>
8181                                                 </xsl:with-param>
8182                                         </xsl:call-template>
8183                                 </title>
8184                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8185                                         <xsl:call-template name="relatedPartNumName"/>
8186                                 </xsl:if>
8187                         </titleInfo>
8188                 </xsl:for-each>
8189                 <xsl:for-each select="marc:subfield[@code='s']">
8190                         <titleInfo type="uniform">
8191                                 <title>
8192                                         <xsl:call-template name="chopPunctuation">
8193                                                 <xsl:with-param name="chopString">
8194                                                         <xsl:value-of select="."/>
8195                                                 </xsl:with-param>
8196                                         </xsl:call-template>
8197                                 </title>
8198                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8199                                         <xsl:call-template name="relatedPartNumName"/>
8200                                 </xsl:if>
8201                         </titleInfo>
8202                 </xsl:for-each>
8203         </xsl:template>
8204         <xsl:template name="relatedOriginInfo">
8205                 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
8206                         <originInfo>
8207                                 <xsl:if test="@tag=775">
8208                                         <xsl:for-each select="marc:subfield[@code='f']">
8209                                                 <place>
8210                                                         <placeTerm>
8211                                                                 <xsl:attribute name="type">code</xsl:attribute>
8212                                                                 <xsl:attribute name="authority">marcgac</xsl:attribute>
8213                                                                 <xsl:value-of select="."/>
8214                                                         </placeTerm>
8215                                                 </place>
8216                                         </xsl:for-each>
8217                                 </xsl:if>
8218                                 <xsl:for-each select="marc:subfield[@code='d']">
8219                                         <publisher>
8220                                                 <xsl:value-of select="."/>
8221                                         </publisher>
8222                                 </xsl:for-each>
8223                                 <xsl:for-each select="marc:subfield[@code='b']">
8224                                         <edition>
8225                                                 <xsl:value-of select="."/>
8226                                         </edition>
8227                                 </xsl:for-each>
8228                         </originInfo>
8229                 </xsl:if>
8230         </xsl:template>
8231         <xsl:template name="relatedLanguage">
8232                 <xsl:for-each select="marc:subfield[@code='e']">
8233                         <xsl:call-template name="getLanguage">
8234                                 <xsl:with-param name="langString">
8235                                         <xsl:value-of select="."/>
8236                                 </xsl:with-param>
8237                         </xsl:call-template>
8238                 </xsl:for-each>
8239         </xsl:template>
8240         <xsl:template name="nameDate">
8241                 <xsl:for-each select="marc:subfield[@code='d']">
8242                         <namePart type="date">
8243                                 <xsl:call-template name="chopPunctuation">
8244                                         <xsl:with-param name="chopString" select="."/>
8245                                 </xsl:call-template>
8246                         </namePart>
8247                 </xsl:for-each>
8248         </xsl:template>
8249         <xsl:template name="subjectAuthority">
8250                 <xsl:if test="@ind2!=4">
8251                         <xsl:if test="@ind2!=' '">
8252                                 <xsl:if test="@ind2!=8">
8253                                         <xsl:if test="@ind2!=9">
8254                                                 <xsl:attribute name="authority">
8255                                                         <xsl:choose>
8256                                                                 <xsl:when test="@ind2=0">lcsh</xsl:when>
8257                                                                 <xsl:when test="@ind2=1">lcshac</xsl:when>
8258                                                                 <xsl:when test="@ind2=2">mesh</xsl:when>
8259                                                                 <!-- 1/04 fix -->
8260                                                                 <xsl:when test="@ind2=3">nal</xsl:when>
8261                                                                 <xsl:when test="@ind2=5">csh</xsl:when>
8262                                                                 <xsl:when test="@ind2=6">rvm</xsl:when>
8263                                                                 <xsl:when test="@ind2=7">
8264                                                                         <xsl:value-of select="marc:subfield[@code='2']"/>
8265                                                                 </xsl:when>
8266                                                         </xsl:choose>
8267                                                 </xsl:attribute>
8268                                         </xsl:if>
8269                                 </xsl:if>
8270                         </xsl:if>
8271                 </xsl:if>
8272         </xsl:template>
8273         <xsl:template name="subjectAnyOrder">
8274                 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
8275                         <xsl:choose>
8276                                 <xsl:when test="@code='v'">
8277                                         <xsl:call-template name="subjectGenre"/>
8278                                 </xsl:when>
8279                                 <xsl:when test="@code='x'">
8280                                         <xsl:call-template name="subjectTopic"/>
8281                                 </xsl:when>
8282                                 <xsl:when test="@code='y'">
8283                                         <xsl:call-template name="subjectTemporalY"/>
8284                                 </xsl:when>
8285                                 <xsl:when test="@code='z'">
8286                                         <xsl:call-template name="subjectGeographicZ"/>
8287                                 </xsl:when>
8288                         </xsl:choose>
8289                 </xsl:for-each>
8290         </xsl:template>
8291         <xsl:template name="specialSubfieldSelect">
8292                 <xsl:param name="anyCodes"/>
8293                 <xsl:param name="axis"/>
8294                 <xsl:param name="beforeCodes"/>
8295                 <xsl:param name="afterCodes"/>
8296                 <xsl:variable name="str">
8297                         <xsl:for-each select="marc:subfield">
8298                                 <xsl:if
8299                                         test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
8300                                         <xsl:value-of select="text()"/>
8301                                         <xsl:text> </xsl:text>
8302                                 </xsl:if>
8303                         </xsl:for-each>
8304                 </xsl:variable>
8305                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
8306         </xsl:template>
8307
8308         <!-- 3.2 change tmee 6xx $v genre -->
8309         <xsl:template match="marc:datafield[@tag=600]">
8310                 <subject>
8311                         <xsl:call-template name="subjectAuthority"/>
8312                         <name type="personal">
8313                                 <xsl:call-template name="termsOfAddress"/>
8314                                 <namePart>
8315                                         <xsl:call-template name="chopPunctuation">
8316                                                 <xsl:with-param name="chopString">
8317                                                         <xsl:call-template name="subfieldSelect">
8318                                                                 <xsl:with-param name="codes">aq</xsl:with-param>
8319                                                         </xsl:call-template>
8320                                                 </xsl:with-param>
8321                                         </xsl:call-template>
8322                                 </namePart>
8323                                 <xsl:call-template name="nameDate"/>
8324                                 <xsl:call-template name="affiliation"/>
8325                                 <xsl:call-template name="role"/>
8326                         </name>
8327                         <xsl:call-template name="subjectAnyOrder"/>
8328                 </subject>
8329         </xsl:template>
8330         <xsl:template match="marc:datafield[@tag=610]">
8331                 <subject>
8332                         <xsl:call-template name="subjectAuthority"/>
8333                         <name type="corporate">
8334                                 <xsl:for-each select="marc:subfield[@code='a']">
8335                                         <namePart>
8336                                                 <xsl:value-of select="."/>
8337                                         </namePart>
8338                                 </xsl:for-each>
8339                                 <xsl:for-each select="marc:subfield[@code='b']">
8340                                         <namePart>
8341                                                 <xsl:value-of select="."/>
8342                                         </namePart>
8343                                 </xsl:for-each>
8344                                 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
8345                                         <namePart>
8346                                                 <xsl:call-template name="subfieldSelect">
8347                                                         <xsl:with-param name="codes">cdnp</xsl:with-param>
8348                                                 </xsl:call-template>
8349                                         </namePart>
8350                                 </xsl:if>
8351                                 <xsl:call-template name="role"/>
8352                         </name>
8353                         <xsl:call-template name="subjectAnyOrder"/>
8354                 </subject>
8355         </xsl:template>
8356         <xsl:template match="marc:datafield[@tag=611]">
8357                 <subject>
8358                         <xsl:call-template name="subjectAuthority"/>
8359                         <name type="conference">
8360                                 <namePart>
8361                                         <xsl:call-template name="subfieldSelect">
8362                                                 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
8363                                         </xsl:call-template>
8364                                 </namePart>
8365                                 <xsl:for-each select="marc:subfield[@code='4']">
8366                                         <role>
8367                                                 <roleTerm authority="marcrelator" type="code">
8368                                                         <xsl:value-of select="."/>
8369                                                 </roleTerm>
8370                                         </role>
8371                                 </xsl:for-each>
8372                         </name>
8373                         <xsl:call-template name="subjectAnyOrder"/>
8374                 </subject>
8375         </xsl:template>
8376         <xsl:template match="marc:datafield[@tag=630]">
8377                 <subject>
8378                         <xsl:call-template name="subjectAuthority"/>
8379                         <titleInfo>
8380                                 <title>
8381                                         <xsl:call-template name="chopPunctuation">
8382                                                 <xsl:with-param name="chopString">
8383                                                         <xsl:call-template name="subfieldSelect">
8384                                                                 <xsl:with-param name="codes">adfhklor</xsl:with-param>
8385                                                         </xsl:call-template>
8386                                                 </xsl:with-param>
8387                                         </xsl:call-template>
8388                                 </title>
8389                                 <xsl:call-template name="part"/>
8390                         </titleInfo>
8391                         <xsl:call-template name="subjectAnyOrder"/>
8392                 </subject>
8393         </xsl:template>
8394         <!-- 1.27 648 tmee-->
8395         <xsl:template match="marc:datafield[@tag=648]">
8396                 <subject>
8397                         <xsl:if test="marc:subfield[@code=2]">
8398                                 <xsl:attribute name="authority">
8399                                         <xsl:value-of select="marc:subfield[@code=2]"/>
8400                                 </xsl:attribute>
8401                         </xsl:if>
8402                         <xsl:call-template name="uri"/>
8403
8404                         <xsl:call-template name="subjectAuthority"/>
8405                         <temporal>
8406                                 <xsl:call-template name="chopPunctuation">
8407                                         <xsl:with-param name="chopString">
8408                                                 <xsl:call-template name="subfieldSelect">
8409                                                         <xsl:with-param name="codes">abcd</xsl:with-param>
8410                                                 </xsl:call-template>
8411                                         </xsl:with-param>
8412                                 </xsl:call-template>
8413                         </temporal>
8414                         <xsl:call-template name="subjectAnyOrder"/>
8415
8416                 </subject>
8417         </xsl:template>
8418         <xsl:template match="marc:datafield[@tag=650]">
8419                 <subject>
8420                         <xsl:call-template name="subjectAuthority"/>
8421                         <topic>
8422                                 <xsl:call-template name="chopPunctuation">
8423                                         <xsl:with-param name="chopString">
8424                                                 <xsl:call-template name="subfieldSelect">
8425                                                         <xsl:with-param name="codes">abcd</xsl:with-param>
8426                                                 </xsl:call-template>
8427                                         </xsl:with-param>
8428                                 </xsl:call-template>
8429                         </topic>
8430                         <xsl:call-template name="subjectAnyOrder"/>
8431                 </subject>
8432         </xsl:template>
8433         <xsl:template match="marc:datafield[@tag=651]">
8434                 <subject>
8435                         <xsl:call-template name="subjectAuthority"/>
8436                         <xsl:for-each select="marc:subfield[@code='a']">
8437                                 <geographic>
8438                                         <xsl:call-template name="chopPunctuation">
8439                                                 <xsl:with-param name="chopString" select="."/>
8440                                         </xsl:call-template>
8441                                 </geographic>
8442                         </xsl:for-each>
8443                         <xsl:call-template name="subjectAnyOrder"/>
8444                 </subject>
8445         </xsl:template>
8446         <xsl:template match="marc:datafield[@tag=653]">
8447                 <subject>
8448                         <xsl:for-each select="marc:subfield[@code='a']">
8449                                 <topic>
8450                                         <xsl:value-of select="."/>
8451                                 </topic>
8452                         </xsl:for-each>
8453                 </subject>
8454         </xsl:template>
8455         <xsl:template match="marc:datafield[@tag=656]">
8456                 <subject>
8457                         <xsl:if test="marc:subfield[@code=2]">
8458                                 <xsl:attribute name="authority">
8459                                         <xsl:value-of select="marc:subfield[@code=2]"/>
8460                                 </xsl:attribute>
8461                         </xsl:if>
8462                         <occupation>
8463                                 <xsl:call-template name="chopPunctuation">
8464                                         <xsl:with-param name="chopString">
8465                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
8466                                         </xsl:with-param>
8467                                 </xsl:call-template>
8468                         </occupation>
8469                 </subject>
8470         </xsl:template>
8471         <xsl:template name="termsOfAddress">
8472                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
8473                         <namePart type="termsOfAddress">
8474                                 <xsl:call-template name="chopPunctuation">
8475                                         <xsl:with-param name="chopString">
8476                                                 <xsl:call-template name="subfieldSelect">
8477                                                         <xsl:with-param name="codes">bc</xsl:with-param>
8478                                                 </xsl:call-template>
8479                                         </xsl:with-param>
8480                                 </xsl:call-template>
8481                         </namePart>
8482                 </xsl:if>
8483         </xsl:template>
8484         <xsl:template name="displayLabel">
8485                 <xsl:if test="marc:subfield[@code='i']">
8486                         <xsl:attribute name="displayLabel">
8487                                 <xsl:value-of select="marc:subfield[@code='i']"/>
8488                         </xsl:attribute>
8489                 </xsl:if>
8490                 <xsl:if test="marc:subfield[@code='3']">
8491                         <xsl:attribute name="displayLabel">
8492                                 <xsl:value-of select="marc:subfield[@code='3']"/>
8493                         </xsl:attribute>
8494                 </xsl:if>
8495         </xsl:template>
8496         <xsl:template name="isInvalid">
8497                 <xsl:param name="type"/>
8498                 <xsl:if
8499                         test="marc:subfield[@code='z'] or marc:subfield[@code='y']  or marc:subfield[@code='m']">
8500                         <identifier>
8501                                 <xsl:attribute name="type">
8502                                         <xsl:value-of select="$type"/>
8503                                 </xsl:attribute>
8504                                 <xsl:attribute name="invalid">
8505                                         <xsl:text>yes</xsl:text>
8506                                 </xsl:attribute>
8507                                 <xsl:if test="marc:subfield[@code='z']">
8508                                         <xsl:value-of select="marc:subfield[@code='z']"/>
8509                                 </xsl:if>
8510                                 <xsl:if test="marc:subfield[@code='y']">
8511                                         <xsl:value-of select="marc:subfield[@code='y']"/>
8512                                 </xsl:if>
8513                                 <xsl:if test="marc:subfield[@code='m']">
8514                                         <xsl:value-of select="marc:subfield[@code='m']"/>
8515                                 </xsl:if>
8516                         </identifier>
8517                 </xsl:if>
8518         </xsl:template>
8519         <xsl:template name="subtitle">
8520                 <xsl:if test="marc:subfield[@code='b']">
8521                         <subTitle>
8522                                 <xsl:call-template name="chopPunctuation">
8523                                         <xsl:with-param name="chopString">
8524                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
8525                                                 <!--<xsl:call-template name="subfieldSelect">
8526                                                         <xsl:with-param name="codes">b</xsl:with-param>                                                                 
8527                                                 </xsl:call-template>-->
8528                                         </xsl:with-param>
8529                                 </xsl:call-template>
8530                         </subTitle>
8531                 </xsl:if>
8532         </xsl:template>
8533         <xsl:template name="script">
8534                 <xsl:param name="scriptCode"/>
8535                 <xsl:attribute name="script">
8536                         <xsl:choose>
8537                                 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
8538                                 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
8539                                 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
8540                                 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
8541                                 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
8542                                 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
8543                         </xsl:choose>
8544                 </xsl:attribute>
8545         </xsl:template>
8546         <xsl:template name="parsePart">
8547                 <!-- assumes 773$q= 1:2:3<4
8548                      with up to 3 levels and one optional start page
8549                 -->
8550                 <xsl:variable name="level1">
8551                         <xsl:choose>
8552                                 <xsl:when test="contains(text(),':')">
8553                                         <!-- 1:2 -->
8554                                         <xsl:value-of select="substring-before(text(),':')"/>
8555                                 </xsl:when>
8556                                 <xsl:when test="not(contains(text(),':'))">
8557                                         <!-- 1 or 1<3 -->
8558                                         <xsl:if test="contains(text(),'&lt;')">
8559                                                 <!-- 1<3 -->
8560                                                 <xsl:value-of select="substring-before(text(),'&lt;')"/>
8561                                         </xsl:if>
8562                                         <xsl:if test="not(contains(text(),'&lt;'))">
8563                                                 <!-- 1 -->
8564                                                 <xsl:value-of select="text()"/>
8565                                         </xsl:if>
8566                                 </xsl:when>
8567                         </xsl:choose>
8568                 </xsl:variable>
8569                 <xsl:variable name="sici2">
8570                         <xsl:choose>
8571                                 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
8572                                         <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
8573                                 </xsl:when>
8574                                 <xsl:otherwise>
8575                                         <xsl:value-of select="substring-after(text(),$level1)"/>
8576                                 </xsl:otherwise>
8577                         </xsl:choose>
8578                 </xsl:variable>
8579                 <xsl:variable name="level2">
8580                         <xsl:choose>
8581                                 <xsl:when test="contains($sici2,':')">
8582                                         <!--  2:3<4  -->
8583                                         <xsl:value-of select="substring-before($sici2,':')"/>
8584                                 </xsl:when>
8585                                 <xsl:when test="contains($sici2,'&lt;')">
8586                                         <!-- 1: 2<4 -->
8587                                         <xsl:value-of select="substring-before($sici2,'&lt;')"/>
8588                                 </xsl:when>
8589                                 <xsl:otherwise>
8590                                         <xsl:value-of select="$sici2"/>
8591                                         <!-- 1:2 -->
8592                                 </xsl:otherwise>
8593                         </xsl:choose>
8594                 </xsl:variable>
8595                 <xsl:variable name="sici3">
8596                         <xsl:choose>
8597                                 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
8598                                         <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
8599                                 </xsl:when>
8600                                 <xsl:otherwise>
8601                                         <xsl:value-of select="substring-after($sici2,$level2)"/>
8602                                 </xsl:otherwise>
8603                         </xsl:choose>
8604                 </xsl:variable>
8605                 <xsl:variable name="level3">
8606                         <xsl:choose>
8607                                 <xsl:when test="contains($sici3,'&lt;')">
8608                                         <!-- 2<4 -->
8609                                         <xsl:value-of select="substring-before($sici3,'&lt;')"/>
8610                                 </xsl:when>
8611                                 <xsl:otherwise>
8612                                         <xsl:value-of select="$sici3"/>
8613                                         <!-- 3 -->
8614                                 </xsl:otherwise>
8615                         </xsl:choose>
8616                 </xsl:variable>
8617                 <xsl:variable name="page">
8618                         <xsl:if test="contains(text(),'&lt;')">
8619                                 <xsl:value-of select="substring-after(text(),'&lt;')"/>
8620                         </xsl:if>
8621                 </xsl:variable>
8622                 <xsl:if test="$level1">
8623                         <detail level="1">
8624                                 <number>
8625                                         <xsl:value-of select="$level1"/>
8626                                 </number>
8627                         </detail>
8628                 </xsl:if>
8629                 <xsl:if test="$level2">
8630                         <detail level="2">
8631                                 <number>
8632                                         <xsl:value-of select="$level2"/>
8633                                 </number>
8634                         </detail>
8635                 </xsl:if>
8636                 <xsl:if test="$level3">
8637                         <detail level="3">
8638                                 <number>
8639                                         <xsl:value-of select="$level3"/>
8640                                 </number>
8641                         </detail>
8642                 </xsl:if>
8643                 <xsl:if test="$page">
8644                         <extent unit="page">
8645                                 <start>
8646                                         <xsl:value-of select="$page"/>
8647                                 </start>
8648                         </extent>
8649                 </xsl:if>
8650         </xsl:template>
8651         <xsl:template name="getLanguage">
8652                 <xsl:param name="langString"/>
8653                 <xsl:param name="controlField008-35-37"/>
8654                 <xsl:variable name="length" select="string-length($langString)"/>
8655                 <xsl:choose>
8656                         <xsl:when test="$length=0"/>
8657                         <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
8658                                 <xsl:call-template name="getLanguage">
8659                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
8660                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
8661                                 </xsl:call-template>
8662                         </xsl:when>
8663                         <xsl:otherwise>
8664                                 <language>
8665                                         <languageTerm authority="iso639-2b" type="code">
8666                                                 <xsl:value-of select="substring($langString,1,3)"/>
8667                                         </languageTerm>
8668                                 </language>
8669                                 <xsl:call-template name="getLanguage">
8670                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
8671                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
8672                                 </xsl:call-template>
8673                         </xsl:otherwise>
8674                 </xsl:choose>
8675         </xsl:template>
8676         <xsl:template name="isoLanguage">
8677                 <xsl:param name="currentLanguage"/>
8678                 <xsl:param name="usedLanguages"/>
8679                 <xsl:param name="remainingLanguages"/>
8680                 <xsl:choose>
8681                         <xsl:when test="string-length($currentLanguage)=0"/>
8682                         <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
8683                                 <language>
8684                                         <xsl:if test="@code!='a'">
8685                                                 <xsl:attribute name="objectPart">
8686                                                         <xsl:choose>
8687                                                                 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
8688                                                                 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
8689                                                                 <xsl:when test="@code='e'">libretto</xsl:when>
8690                                                                 <xsl:when test="@code='f'">table of contents</xsl:when>
8691                                                                 <xsl:when test="@code='g'">accompanying material</xsl:when>
8692                                                                 <xsl:when test="@code='h'">translation</xsl:when>
8693                                                         </xsl:choose>
8694                                                 </xsl:attribute>
8695                                         </xsl:if>
8696                                         <languageTerm authority="iso639-2b" type="code">
8697                                                 <xsl:value-of select="$currentLanguage"/>
8698                                         </languageTerm>
8699                                 </language>
8700                                 <xsl:call-template name="isoLanguage">
8701                                         <xsl:with-param name="currentLanguage">
8702                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"/>
8703                                         </xsl:with-param>
8704                                         <xsl:with-param name="usedLanguages">
8705                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
8706                                         </xsl:with-param>
8707                                         <xsl:with-param name="remainingLanguages">
8708                                                 <xsl:value-of
8709                                                         select="substring($remainingLanguages,4,string-length($remainingLanguages))"
8710                                                 />
8711                                         </xsl:with-param>
8712                                 </xsl:call-template>
8713                         </xsl:when>
8714                         <xsl:otherwise>
8715                                 <xsl:call-template name="isoLanguage">
8716                                         <xsl:with-param name="currentLanguage">
8717                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"/>
8718                                         </xsl:with-param>
8719                                         <xsl:with-param name="usedLanguages">
8720                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
8721                                         </xsl:with-param>
8722                                         <xsl:with-param name="remainingLanguages">
8723                                                 <xsl:value-of
8724                                                         select="substring($remainingLanguages,4,string-length($remainingLanguages))"
8725                                                 />
8726                                         </xsl:with-param>
8727                                 </xsl:call-template>
8728                         </xsl:otherwise>
8729                 </xsl:choose>
8730         </xsl:template>
8731         <xsl:template name="chopBrackets">
8732                 <xsl:param name="chopString"/>
8733                 <xsl:variable name="string">
8734                         <xsl:call-template name="chopPunctuation">
8735                                 <xsl:with-param name="chopString" select="$chopString"/>
8736                         </xsl:call-template>
8737                 </xsl:variable>
8738                 <xsl:if test="substring($string, 1,1)='['">
8739                         <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
8740                 </xsl:if>
8741                 <xsl:if test="substring($string, 1,1)!='['">
8742                         <xsl:value-of select="$string"/>
8743                 </xsl:if>
8744         </xsl:template>
8745         <xsl:template name="rfcLanguages">
8746                 <xsl:param name="nodeNum"/>
8747                 <xsl:param name="usedLanguages"/>
8748                 <xsl:param name="controlField008-35-37"/>
8749                 <xsl:variable name="currentLanguage" select="."/>
8750                 <xsl:choose>
8751                         <xsl:when test="not($currentLanguage)"/>
8752                         <xsl:when
8753                                 test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
8754                                 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
8755                                         <language>
8756                                                 <xsl:if test="@code!='a'">
8757                                                         <xsl:attribute name="objectPart">
8758                                                                 <xsl:choose>
8759                                                                         <xsl:when test="@code='b'">summary or subtitle</xsl:when>
8760                                                                         <xsl:when test="@code='d'">sung or spoken text</xsl:when>
8761                                                                         <xsl:when test="@code='e'">libretto</xsl:when>
8762                                                                         <xsl:when test="@code='f'">table of contents</xsl:when>
8763                                                                         <xsl:when test="@code='g'">accompanying material</xsl:when>
8764                                                                         <xsl:when test="@code='h'">translation</xsl:when>
8765                                                                 </xsl:choose>
8766                                                         </xsl:attribute>
8767                                                 </xsl:if>
8768                                                 <languageTerm authority="rfc3066" type="code">
8769                                                         <xsl:value-of select="$currentLanguage"/>
8770                                                 </languageTerm>
8771                                         </language>
8772                                 </xsl:if>
8773                         </xsl:when>
8774                         <xsl:otherwise> </xsl:otherwise>
8775                 </xsl:choose>
8776         </xsl:template>
8777
8778     <xsl:template name="datafield">
8779                 <xsl:param name="tag"/>
8780                 <xsl:param name="ind1">
8781                         <xsl:text> </xsl:text>
8782                 </xsl:param>
8783                 <xsl:param name="ind2">
8784                         <xsl:text> </xsl:text>
8785                 </xsl:param>
8786                 <xsl:param name="subfields"/>
8787                 <xsl:element name="marc:datafield">
8788                         <xsl:attribute name="tag">
8789                                 <xsl:value-of select="$tag"/>
8790                         </xsl:attribute>
8791                         <xsl:attribute name="ind1">
8792                                 <xsl:value-of select="$ind1"/>
8793                         </xsl:attribute>
8794                         <xsl:attribute name="ind2">
8795                                 <xsl:value-of select="$ind2"/>
8796                         </xsl:attribute>
8797                         <xsl:copy-of select="$subfields"/>
8798                 </xsl:element>
8799         </xsl:template>
8800
8801         <xsl:template name="subfieldSelect">
8802                 <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
8803                 <xsl:param name="delimeter">
8804                         <xsl:text> </xsl:text>
8805                 </xsl:param>
8806                 <xsl:variable name="str">
8807                         <xsl:for-each select="marc:subfield">
8808                                 <xsl:if test="contains($codes, @code)">
8809                                         <xsl:value-of select="text()"/>
8810                                         <xsl:value-of select="$delimeter"/>
8811                                 </xsl:if>
8812                         </xsl:for-each>
8813                 </xsl:variable>
8814                 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
8815         </xsl:template>
8816
8817         <xsl:template name="buildSpaces">
8818                 <xsl:param name="spaces"/>
8819                 <xsl:param name="char">
8820                         <xsl:text> </xsl:text>
8821                 </xsl:param>
8822                 <xsl:if test="$spaces>0">
8823                         <xsl:value-of select="$char"/>
8824                         <xsl:call-template name="buildSpaces">
8825                                 <xsl:with-param name="spaces" select="$spaces - 1"/>
8826                                 <xsl:with-param name="char" select="$char"/>
8827                         </xsl:call-template>
8828                 </xsl:if>
8829         </xsl:template>
8830
8831         <xsl:template name="chopPunctuation">
8832                 <xsl:param name="chopString"/>
8833                 <xsl:param name="punctuation">
8834                         <xsl:text>.:,;/ </xsl:text>
8835                 </xsl:param>
8836                 <xsl:variable name="length" select="string-length($chopString)"/>
8837                 <xsl:choose>
8838                         <xsl:when test="$length=0"/>
8839                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
8840                                 <xsl:call-template name="chopPunctuation">
8841                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
8842                                         <xsl:with-param name="punctuation" select="$punctuation"/>
8843                                 </xsl:call-template>
8844                         </xsl:when>
8845                         <xsl:when test="not($chopString)"/>
8846                         <xsl:otherwise>
8847                                 <xsl:value-of select="$chopString"/>
8848                         </xsl:otherwise>
8849                 </xsl:choose>
8850         </xsl:template>
8851
8852         <xsl:template name="chopPunctuationFront">
8853                 <xsl:param name="chopString"/>
8854                 <xsl:variable name="length" select="string-length($chopString)"/>
8855                 <xsl:choose>
8856                         <xsl:when test="$length=0"/>
8857                         <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
8858                                 <xsl:call-template name="chopPunctuationFront">
8859                                         <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
8860                                         />
8861                                 </xsl:call-template>
8862                         </xsl:when>
8863                         <xsl:when test="not($chopString)"/>
8864                         <xsl:otherwise>
8865                                 <xsl:value-of select="$chopString"/>
8866                         </xsl:otherwise>
8867                 </xsl:choose>
8868         </xsl:template>
8869
8870         <xsl:template name="chopPunctuationBack">
8871                 <xsl:param name="chopString"/>
8872                 <xsl:param name="punctuation">
8873                         <xsl:text>.:,;/] </xsl:text>
8874                 </xsl:param>
8875                 <xsl:variable name="length" select="string-length($chopString)"/>
8876                 <xsl:choose>
8877                         <xsl:when test="$length=0"/>
8878                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
8879                                 <xsl:call-template name="chopPunctuation">
8880                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
8881                                         <xsl:with-param name="punctuation" select="$punctuation"/>
8882                                 </xsl:call-template>
8883                         </xsl:when>
8884                         <xsl:when test="not($chopString)"/>
8885                         <xsl:otherwise>
8886                                 <xsl:value-of select="$chopString"/>
8887                         </xsl:otherwise>
8888                 </xsl:choose>
8889         </xsl:template>
8890
8891         <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
8892         <xsl:template name="url-encode">
8893
8894                 <xsl:param name="str"/>
8895
8896                 <xsl:if test="$str">
8897                         <xsl:variable name="first-char" select="substring($str,1,1)"/>
8898                         <xsl:choose>
8899                                 <xsl:when test="contains($safe,$first-char)">
8900                                         <xsl:value-of select="$first-char"/>
8901                                 </xsl:when>
8902                                 <xsl:otherwise>
8903                                         <xsl:variable name="codepoint">
8904                                                 <xsl:choose>
8905                                                         <xsl:when test="contains($ascii,$first-char)">
8906                                                                 <xsl:value-of
8907                                                                         select="string-length(substring-before($ascii,$first-char)) + 32"
8908                                                                 />
8909                                                         </xsl:when>
8910                                                         <xsl:when test="contains($latin1,$first-char)">
8911                                                                 <xsl:value-of
8912                                                                         select="string-length(substring-before($latin1,$first-char)) + 160"/>
8913                                                                 <!-- was 160 -->
8914                                                         </xsl:when>
8915                                                         <xsl:otherwise>
8916                                                                 <xsl:message terminate="no">Warning: string contains a character
8917                                                                         that is out of range! Substituting "?".</xsl:message>
8918                                                                 <xsl:text>63</xsl:text>
8919                                                         </xsl:otherwise>
8920                                                 </xsl:choose>
8921                                         </xsl:variable>
8922                                         <xsl:variable name="hex-digit1"
8923                                                 select="substring($hex,floor($codepoint div 16) + 1,1)"/>
8924                                         <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
8925                                         <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
8926                                         <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
8927                                 </xsl:otherwise>
8928                         </xsl:choose>
8929                         <xsl:if test="string-length($str) &gt; 1">
8930                                 <xsl:call-template name="url-encode">
8931                                         <xsl:with-param name="str" select="substring($str,2)"/>
8932                                 </xsl:call-template>
8933                         </xsl:if>
8934                 </xsl:if>
8935         </xsl:template>
8936 </xsl:stylesheet>$$ WHERE name = 'mods33';
8937
8938
8939 INSERT INTO config.global_flag (name, value, enabled, label) VALUES
8940 (
8941     'opac.browse.warnable_regexp_per_class',
8942     '{"title": "^(a|the|an)\\s"}',
8943     FALSE,
8944     oils_i18n_gettext(
8945         'opac.browse.warnable_regexp_per_class',
8946         'Map of search classes to regular expressions to warn user about leading articles.',
8947         'cgf',
8948         'label'
8949     )
8950 ),
8951 (
8952     'opac.browse.holdings_visibility_test_limit',
8953     '100',
8954     TRUE,
8955     oils_i18n_gettext(
8956         'opac.browse.holdings_visibility_test_limit',
8957         'Don''t look for more than this number of records with holdings when displaying browse headings with visible record counts.',
8958         'cgf',
8959         'label'
8960     )
8961 );
8962
8963 ALTER TABLE metabib.browse_entry DROP CONSTRAINT browse_entry_value_key;
8964 ALTER TABLE metabib.browse_entry ADD COLUMN sort_value TEXT;
8965 DELETE FROM metabib.browse_entry_def_map; -- Yeah.
8966 DELETE FROM metabib.browse_entry WHERE sort_value IS NULL;
8967 ALTER TABLE metabib.browse_entry ALTER COLUMN sort_value SET NOT NULL;
8968 ALTER TABLE metabib.browse_entry ADD UNIQUE (sort_value, value);
8969 DROP TRIGGER IF EXISTS mbe_sort_value ON metabib.browse_entry;
8970
8971 CREATE INDEX browse_entry_sort_value_idx
8972     ON metabib.browse_entry USING BTREE (sort_value);
8973
8974 -- NOTE If I understand ordered indices correctly, an index on sort_value DESC
8975 -- is not actually needed, even though we do have a query that does ORDER BY
8976 -- on this column in that direction.  The previous index serves for both
8977 -- directions, and ordering in an index is only helpful for multi-column
8978 -- indices, I think. See http://www.postgresql.org/docs/9.1/static/indexes-ordering.html
8979
8980 -- CREATE INDEX CONCURRENTLY browse_entry_sort_value_idx_desc
8981 --     ON metabib.browse_entry USING BTREE (sort_value DESC);
8982
8983 CREATE TYPE metabib.flat_browse_entry_appearance AS (
8984     browse_entry    BIGINT,
8985     value           TEXT,
8986     fields          TEXT,
8987     authorities     TEXT,
8988     sources         INT,        -- visible ones, that is
8989     row_number      INT,        -- internal use, sort of
8990     accurate        BOOL,       -- Count in sources field is accurate? Not
8991                                 -- if we had more than a browse superpage
8992                                 -- of records to look at.
8993     pivot_point     BIGINT
8994 );
8995
8996
8997 CREATE OR REPLACE FUNCTION metabib.browse_pivot(
8998     search_field        INT[],
8999     browse_term         TEXT
9000 ) RETURNS BIGINT AS $p$
9001 DECLARE
9002     id                  BIGINT;
9003 BEGIN
9004     SELECT INTO id mbe.id FROM metabib.browse_entry mbe
9005         JOIN metabib.browse_entry_def_map mbedm ON (
9006             mbedm.entry = mbe.id AND
9007             mbedm.def = ANY(search_field)
9008         )
9009         WHERE mbe.sort_value >= public.search_normalize(browse_term)
9010         ORDER BY mbe.sort_value, mbe.value LIMIT 1;
9011
9012     RETURN id;
9013 END;
9014 $p$ LANGUAGE PLPGSQL;
9015
9016 CREATE OR REPLACE FUNCTION metabib.staged_browse(
9017     query                   TEXT,
9018     fields                  INT[],
9019     context_org             INT,
9020     context_locations       INT[],
9021     staff                   BOOL,
9022     browse_superpage_size   INT,
9023     count_up_from_zero      BOOL,   -- if false, count down from -1
9024     result_limit            INT,
9025     next_pivot_pos          INT
9026 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9027 DECLARE
9028     curs                    REFCURSOR;
9029     rec                     RECORD;
9030     qpfts_query             TEXT;
9031     result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
9032     results_skipped         INT := 0;
9033     row_counter             INT := 0;
9034     row_number              INT;
9035     slice_start             INT;
9036     slice_end               INT;
9037     full_end                INT;
9038     all_records             BIGINT[];
9039     superpage_of_records    BIGINT[];
9040     superpage_size          INT;
9041 BEGIN
9042     IF count_up_from_zero THEN
9043         row_number := 0;
9044     ELSE
9045         row_number := -1;
9046     END IF;
9047
9048     OPEN curs FOR EXECUTE query;
9049
9050     LOOP
9051         FETCH curs INTO rec;
9052         IF NOT FOUND THEN
9053             IF result_row.pivot_point IS NOT NULL THEN
9054                 RETURN NEXT result_row;
9055             END IF;
9056             RETURN;
9057         END IF;
9058
9059         -- Gather aggregate data based on the MBE row we're looking at now
9060         SELECT INTO all_records, result_row.authorities, result_row.fields
9061                 ARRAY_AGG(DISTINCT source),
9062                 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT authority), $$,$$),
9063                 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT def), $$,$$)
9064           FROM  metabib.browse_entry_def_map
9065           WHERE entry = rec.id
9066                 AND def = ANY(fields);
9067
9068         result_row.sources := 0;
9069
9070         full_end := ARRAY_LENGTH(all_records, 1);
9071         superpage_size := COALESCE(browse_superpage_size, full_end);
9072         slice_start := 1;
9073         slice_end := superpage_size;
9074
9075         WHILE result_row.sources = 0 AND slice_start <= full_end LOOP
9076             superpage_of_records := all_records[slice_start:slice_end];
9077             qpfts_query :=
9078                 'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
9079                 '1::INT AS rel FROM (SELECT UNNEST(' ||
9080                 quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
9081
9082             -- We use search.query_parser_fts() for visibility testing.
9083             -- We're calling it once per browse-superpage worth of records
9084             -- out of the set of records related to a given mbe, until we've
9085             -- either exhausted that set of records or found at least 1
9086             -- visible record.
9087
9088             SELECT INTO result_row.sources visible
9089                 FROM search.query_parser_fts(
9090                     context_org, NULL, qpfts_query, NULL,
9091                     context_locations, 0, NULL, NULL, FALSE, staff, FALSE
9092                 ) qpfts
9093                 WHERE qpfts.rel IS NULL;
9094
9095             slice_start := slice_start + superpage_size;
9096             slice_end := slice_end + superpage_size;
9097         END LOOP;
9098
9099         -- Accurate?  Well, probably.
9100         result_row.accurate := browse_superpage_size IS NULL OR
9101             browse_superpage_size >= full_end;
9102
9103         IF result_row.sources > 0 THEN
9104             -- We've got a browse entry with visible holdings. Yay.
9105
9106
9107             -- The function that calls this function needs row_number in order
9108             -- to correctly order results from two different runs of this
9109             -- functions.
9110             result_row.row_number := row_number;
9111
9112             -- Now, if row_counter is still less than limit, return a row.  If
9113             -- not, but it is less than next_pivot_pos, continue on without
9114             -- returning actual result rows until we find
9115             -- that next pivot, and return it.
9116
9117             IF row_counter < result_limit THEN
9118                 result_row.browse_entry := rec.id;
9119                 result_row.value := rec.value;
9120
9121                 RETURN NEXT result_row;
9122             ELSE
9123                 result_row.browse_entry := NULL;
9124                 result_row.authorities := NULL;
9125                 result_row.fields := NULL;
9126                 result_row.value := NULL;
9127                 result_row.sources := NULL;
9128                 result_row.accurate := NULL;
9129                 result_row.pivot_point := rec.id;
9130
9131                 IF row_counter >= next_pivot_pos THEN
9132                     RETURN NEXT result_row;
9133                     RETURN;
9134                 END IF;
9135             END IF;
9136
9137             IF count_up_from_zero THEN
9138                 row_number := row_number + 1;
9139             ELSE
9140                 row_number := row_number - 1;
9141             END IF;
9142
9143             -- row_counter is different from row_number.
9144             -- It simply counts up from zero so that we know when
9145             -- we've reached our limit.
9146             row_counter := row_counter + 1;
9147         END IF;
9148     END LOOP;
9149 END;
9150 $p$ LANGUAGE PLPGSQL;
9151
9152 CREATE OR REPLACE FUNCTION metabib.browse(
9153     search_field            INT[],
9154     browse_term             TEXT,
9155     context_org             INT DEFAULT NULL,
9156     context_loc_group       INT DEFAULT NULL,
9157     staff                   BOOL DEFAULT FALSE,
9158     pivot_id                BIGINT DEFAULT NULL,
9159     result_limit            INT DEFAULT 10
9160 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9161 DECLARE
9162     core_query              TEXT;
9163     back_query              TEXT;
9164     forward_query           TEXT;
9165     pivot_sort_value        TEXT;
9166     pivot_sort_fallback     TEXT;
9167     context_locations       INT[];
9168     browse_superpage_size   INT;
9169     results_skipped         INT := 0;
9170     back_limit              INT;
9171     back_to_pivot           INT;
9172     forward_limit           INT;
9173     forward_to_pivot        INT;
9174 BEGIN
9175     -- First, find the pivot if we were given a browse term but not a pivot.
9176     IF pivot_id IS NULL THEN
9177         pivot_id := metabib.browse_pivot(search_field, browse_term);
9178     END IF;
9179
9180     SELECT INTO pivot_sort_value, pivot_sort_fallback
9181         sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
9182
9183     -- Bail if we couldn't find a pivot.
9184     IF pivot_sort_value IS NULL THEN
9185         RETURN;
9186     END IF;
9187
9188     -- Transform the context_loc_group argument (if any) (logc at the
9189     -- TPAC layer) into a form we'll be able to use.
9190     IF context_loc_group IS NOT NULL THEN
9191         SELECT INTO context_locations ARRAY_AGG(location)
9192             FROM asset.copy_location_group_map
9193             WHERE lgroup = context_loc_group;
9194     END IF;
9195
9196     -- Get the configured size of browse superpages.
9197     SELECT INTO browse_superpage_size value     -- NULL ok
9198         FROM config.global_flag
9199         WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
9200
9201     -- First we're going to search backward from the pivot, then we're going
9202     -- to search forward.  In each direction, we need two limits.  At the
9203     -- lesser of the two limits, we delineate the edge of the result set
9204     -- we're going to return.  At the greater of the two limits, we find the
9205     -- pivot value that would represent an offset from the current pivot
9206     -- at a distance of one "page" in either direction, where a "page" is a
9207     -- result set of the size specified in the "result_limit" argument.
9208     --
9209     -- The two limits in each direction make four derived values in total,
9210     -- and we calculate them now.
9211     back_limit := CEIL(result_limit::FLOAT / 2);
9212     back_to_pivot := result_limit;
9213     forward_limit := result_limit / 2;
9214     forward_to_pivot := result_limit - 1;
9215
9216     -- This is the meat of the SQL query that finds browse entries.  We'll
9217     -- pass this to a function which uses it with a cursor, so that individual
9218     -- rows may be fetched in a loop until some condition is satisfied, without
9219     -- waiting for a result set of fixed size to be collected all at once.
9220     core_query := '
9221     SELECT
9222         mbe.id,
9223         mbe.value,
9224         mbe.sort_value
9225     FROM metabib.browse_entry mbe
9226     WHERE EXISTS (SELECT 1 FROM  metabib.browse_entry_def_map mbedm WHERE
9227         mbedm.entry = mbe.id AND
9228         mbedm.def = ANY(' || quote_literal(search_field) || ')
9229     ) AND ';
9230
9231     -- This is the variant of the query for browsing backward.
9232     back_query := core_query ||
9233         ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
9234     ' ORDER BY mbe.sort_value DESC, mbe.value DESC ';
9235
9236     -- This variant browses forward.
9237     forward_query := core_query ||
9238         ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
9239     ' ORDER BY mbe.sort_value, mbe.value ';
9240
9241     -- We now call the function which applies a cursor to the provided
9242     -- queries, stopping at the appropriate limits and also giving us
9243     -- the next page's pivot.
9244     RETURN QUERY
9245         SELECT * FROM metabib.staged_browse(
9246             back_query, search_field, context_org, context_locations,
9247             staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
9248         ) UNION
9249         SELECT * FROM metabib.staged_browse(
9250             forward_query, search_field, context_org, context_locations,
9251             staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
9252         ) ORDER BY row_number DESC;
9253
9254 END;
9255 $p$ LANGUAGE PLPGSQL;
9256
9257 CREATE OR REPLACE FUNCTION metabib.browse(
9258     search_class        TEXT,
9259     browse_term         TEXT,
9260     context_org         INT DEFAULT NULL,
9261     context_loc_group   INT DEFAULT NULL,
9262     staff               BOOL DEFAULT FALSE,
9263     pivot_id            BIGINT DEFAULT NULL,
9264     result_limit        INT DEFAULT 10
9265 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9266 BEGIN
9267     RETURN QUERY SELECT * FROM metabib.browse(
9268         (SELECT COALESCE(ARRAY_AGG(id), ARRAY[]::INT[])
9269             FROM config.metabib_field WHERE field_class = search_class),
9270         browse_term,
9271         context_org,
9272         context_loc_group,
9273         staff,
9274         pivot_id,
9275         result_limit
9276     );
9277 END;
9278 $p$ LANGUAGE PLPGSQL;
9279
9280 UPDATE config.metabib_field
9281 SET
9282     xpath = $$//mods32:mods/mods32:relatedItem[@type="series"]/mods32:titleInfo[@type="nfi"]$$,
9283     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9284     browse_xpath = NULL
9285 WHERE
9286     field_class = 'series' AND name = 'seriestitle' ;
9287
9288 UPDATE config.metabib_field
9289 SET
9290     xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and not (@type)]$$,
9291     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9292     browse_xpath = NULL,
9293     browse_field = TRUE
9294 WHERE
9295     field_class = 'title' AND name = 'proper' ;
9296
9297 UPDATE config.metabib_field
9298 SET
9299     xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='alternative-nfi')]$$,
9300     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9301     browse_xpath = NULL
9302 WHERE
9303     field_class = 'title' AND name = 'alternative' ;
9304
9305 UPDATE config.metabib_field
9306 SET
9307     xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='uniform-nfi')]$$,
9308     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9309     browse_xpath = NULL
9310 WHERE
9311     field_class = 'title' AND name = 'uniform' ;
9312
9313 UPDATE config.metabib_field
9314 SET
9315     xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='translated-nfi')]$$,
9316     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9317     browse_xpath = NULL
9318 WHERE
9319     field_class = 'title' AND name = 'translated' ;
9320
9321 -- This keeps extra terms like "creator" out of browse headings.
9322 UPDATE config.metabib_field
9323     SET browse_xpath = $$//*[local-name()='namePart']$$     -- vim */
9324     WHERE
9325         browse_field AND
9326         browse_xpath IS NULL AND
9327         field_class = 'author';
9328
9329 INSERT INTO config.org_unit_setting_type (
9330     name, label, grp, description, datatype
9331 ) VALUES (
9332     'opac.browse.pager_shortcuts',
9333     'Paging shortcut links for OPAC Browse',
9334     'opac',
9335     'The characters in this string, in order, will be used as shortcut links for quick paging in the OPAC browse interface. Any sequence surrounded by asterisks will be taken as a whole label, not split into individual labels at the character level, but only the first character will serve as the basis of the search.',
9336     'string'
9337 );
9338
9339
9340 -- NOTE: very IDs are still correct for perms and event_def data at merge.
9341
9342 SELECT evergreen.upgrade_deps_block_check('0817', :eg_version);
9343
9344 -- copy status
9345
9346 INSERT INTO config.copy_status
9347     (id, name, holdable, opac_visible, copy_active, restrict_copy_delete)
9348     VALUES (16, oils_i18n_gettext(16, 'Long Overdue', 'ccs', 'name'), 'f', 'f', 'f', 't');
9349
9350 -- checkin override perm
9351
9352 INSERT INTO permission.perm_list (id, code, description) VALUES (
9353     549, -- VERIFY
9354     'COPY_STATUS_LONGOVERDUE.override',
9355     oils_i18n_gettext(
9356         549, -- VERIFY
9357         'Allows the user to check-in long-overdue items, prompting ' ||
9358             'long-overdue check-in processing',
9359         'ppl',
9360         'code'
9361     )
9362 ), (
9363     550, -- VERIFY
9364     'SET_CIRC_LONG_OVERDUE',
9365     oils_i18n_gettext(
9366         550, -- VERIFY
9367         'Allows the user to mark a circulation as long-overdue',
9368         'ppl',
9369         'code'
9370     )
9371 );
9372
9373 -- billing types
9374
9375 INSERT INTO config.billing_type (id, owner, name) VALUES
9376     (10, 1, oils_i18n_gettext(
9377         10, 'Long-Overdue Materials', 'cbt', 'name')),
9378     (11, 1, oils_i18n_gettext(
9379         11, 'Long-Overdue Materials Processing Fee', 'cbt', 'name'));
9380
9381 -- org settings
9382
9383 INSERT INTO config.org_unit_setting_type 
9384     (name, grp, datatype, label, description) VALUES 
9385 (
9386     'circ.longoverdue_immediately_available',
9387     'circ', 'bool',
9388     oils_i18n_gettext(
9389         'circ.longoverdue_immediately_available',
9390         'Long-Overdue Items Usable on Checkin',
9391         'coust',
9392         'label'
9393     ),
9394     oils_i18n_gettext(
9395         'circ.longoverdue_immediately_available',
9396         'Long-overdue items are usable on checkin instead of going "home" first',
9397         'coust',
9398         'description'
9399     )
9400 ), (
9401     'circ.longoverdue_materials_processing_fee',
9402     'finance', 'currency',
9403     oils_i18n_gettext(
9404         'circ.longoverdue_materials_processing_fee',
9405         'Long-Overdue Materials Processing Fee',
9406         'coust',
9407         'label'
9408     ),
9409     oils_i18n_gettext(
9410         'circ.longoverdue_materials_processing_fee',
9411         'Long-Overdue Materials Processing Fee',
9412         'coust',
9413         'description'
9414     )
9415 ), (
9416     'circ.max_accept_return_of_longoverdue',
9417     'circ', 'interval',
9418     oils_i18n_gettext(
9419         'circ.max_accept_return_of_longoverdue',
9420         'Long-Overdue Max Return Interval',
9421         'coust',
9422         'label'
9423     ),
9424     oils_i18n_gettext(
9425         'circ.max_accept_return_of_longoverdue',
9426         'Long-overdue check-in processing (voiding fees, re-instating ' ||
9427             'overdues, etc.) will not take place for items that have been ' ||
9428             'overdue for (or have last activity older than) this amount of time',
9429         'coust',
9430         'description'
9431     )
9432 ), (
9433     'circ.restore_overdue_on_longoverdue_return',
9434     'circ', 'bool',
9435     oils_i18n_gettext(
9436         'circ.restore_overdue_on_longoverdue_return',
9437         'Restore Overdues on Long-Overdue Item Return',
9438         'coust',
9439         'label'
9440     ),
9441     oils_i18n_gettext(
9442         'circ.restore_overdue_on_longoverdue_return',
9443         'Restore Overdues on Long-Overdue Item Return',
9444         'coust',
9445         'description'
9446     )
9447 ), (
9448     'circ.void_longoverdue_on_checkin',
9449     'circ', 'bool',
9450     oils_i18n_gettext(
9451         'circ.void_longoverdue_on_checkin',
9452         'Void Long-Overdue Item Billing When Returned',
9453         'coust',
9454         'label'
9455     ),
9456     oils_i18n_gettext(
9457         'circ.void_longoverdue_on_checkin',
9458         'Void Long-Overdue Item Billing When Returned',
9459         'coust',
9460         'description'
9461     )
9462 ), (
9463     'circ.void_longoverdue_proc_fee_on_checkin',
9464     'circ', 'bool',
9465     oils_i18n_gettext(
9466         'circ.void_longoverdue_proc_fee_on_checkin',
9467         'Void Processing Fee on Long-Overdue Item Return',
9468         'coust',
9469         'label'
9470     ),
9471     oils_i18n_gettext(
9472         'circ.void_longoverdue_proc_fee_on_checkin',
9473         'Void Processing Fee on Long-Overdue Item Return',
9474         'coust',
9475         'description'
9476     )
9477 ), (
9478     'circ.void_overdue_on_longoverdue',
9479     'finance', 'bool',
9480     oils_i18n_gettext(
9481         'circ.void_overdue_on_longoverdue',
9482         'Void Overdue Fines When Items are Marked Long-Overdue',
9483         'coust',
9484         'label'
9485     ),
9486     oils_i18n_gettext(
9487         'circ.void_overdue_on_longoverdue',
9488         'Void Overdue Fines When Items are Marked Long-Overdue',
9489         'coust',
9490         'description'
9491     )
9492 ), (
9493     'circ.longoverdue.xact_open_on_zero',
9494     'finance', 'bool',
9495     oils_i18n_gettext(
9496         'circ.longoverdue.xact_open_on_zero',
9497         'Leave transaction open when long overdue balance equals zero',
9498         'coust',
9499         'label'
9500     ),
9501     oils_i18n_gettext(
9502         'circ.longoverdue.xact_open_on_zero',
9503         'Leave transaction open when long-overdue balance equals zero.  ' ||
9504             'This leaves the lost copy on the patron record when it is paid',
9505         'coust',
9506         'description'
9507     )
9508 ), (
9509     'circ.longoverdue.use_last_activity_date_on_return',
9510     'circ', 'bool',
9511     oils_i18n_gettext(
9512         'circ.longoverdue.use_last_activity_date_on_return',
9513         'Long-Overdue Check-In Interval Uses Last Activity Date',
9514         'coust',
9515         'label'
9516     ),
9517     oils_i18n_gettext(
9518         'circ.longoverdue.use_last_activity_date_on_return',
9519         'Use the long-overdue last-activity date instead of the due_date to ' ||
9520             'determine whether the item has been checked out too long to ' ||
9521             'perform long-overdue check-in processing.  If set, the system ' ||
9522             'will first check the last payment time, followed by the last ' ||
9523             'billing time, followed by the due date.  See also ' ||
9524             'circ.max_accept_return_of_longoverdue',
9525         'coust',
9526         'description'
9527     )
9528 );
9529
9530 -- mark long-overdue reactor
9531
9532 INSERT INTO action_trigger.reactor (module, description) VALUES
9533 (   'MarkItemLongOverdue',
9534     oils_i18n_gettext(
9535         'MarkItemLongOverdue',
9536         'Marks a circulating item as long-overdue and applies configured ' ||
9537         'penalties.  Also creates events for the longoverdue.auto hook',
9538         'atreact',
9539         'description'
9540     )
9541 );
9542
9543 INSERT INTO action_trigger.validator (module, description) VALUES (
9544     'PatronNotInCollections', 
9545     'Event is valid if the linked patron is not in collections processing ' ||
9546         'at the context org unit'
9547 );
9548
9549 -- VERIFY ID
9550 INSERT INTO action_trigger.event_definition 
9551     (id, active, owner, name, hook, validator, reactor, delay, delay_field) 
9552 VALUES ( 
9553     49, FALSE, 1, '6 Month Overdue Mark Long-Overdue', 
9554     'checkout.due', 'PatronNotInCollections', 
9555     'MarkItemLongOverdue', '6 months', 'due_date'
9556 );
9557
9558 -- VERIFY ID
9559 INSERT INTO action_trigger.event_params (event_def, param, value) VALUES
9560     (49, 'editor', '''1'''); 
9561
9562 -- new longoverdue and longervdue.auto hook.
9563
9564 INSERT INTO action_trigger.hook (key,core_type,description) VALUES (
9565     'longoverdue',
9566     'circ',
9567     'Circulating Item marked long-overdue'
9568 );
9569
9570 INSERT INTO action_trigger.hook (key,core_type,description) VALUES (
9571     'longoverdue.auto',
9572     'circ',
9573     'Circulating Item automatically marked long-overdue'
9574 );
9575
9576 -- sample longoverdue.auto notification reactor
9577
9578 -- VERIFY ID
9579 INSERT INTO action_trigger.event_definition 
9580     (id, active, owner, name, hook, validator, reactor, group_field, template) 
9581     VALUES ( 
9582         50, FALSE, 1, '6 Month Long Overdue Notice', 
9583         'longoverdue.auto', 'NOOP_True', 'SendEmail', 'usr',
9584 $$
9585 [%- USE date -%]
9586 [%- user = target.0.usr -%]
9587 To: [%- params.recipient_email || user.email %]
9588 From: [%- params.sender_email || default_sender %]
9589 Subject: Overdue Items Marked Long Overdue
9590
9591 Dear [% user.family_name %], [% user.first_given_name %]
9592 The following items are 6 months overdue and have been marked Long Overdue.
9593
9594 [% FOR circ IN target %]
9595     [%- copy_details = helpers.get_copy_bib_basics(circ.target_copy.id) -%]
9596     Title: [% copy_details.title %], by [% copy_details.author %]
9597     Call Number: [% circ.target_copy.call_number.label %]
9598     Shelving Location: [% circ.target_copy.location.name %]
9599     Barcode: [% circ.target_copy.barcode %]
9600     Due: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
9601     Item Cost: [% helpers.get_copy_price(circ.target_copy) %]
9602     Total Owed For Transaction: [% circ.billable_transaction.summary.balance_owed %]
9603     Library: [% circ.circ_lib.name %]
9604
9605 [% END %]
9606 $$);
9607
9608 -- ENV for above
9609
9610 -- VERIFY IDs
9611 INSERT INTO action_trigger.environment (event_def, path) VALUES 
9612     (50, 'target_copy.call_number'),
9613     (50, 'usr'),
9614     (50, 'billable_transaction.summary'),
9615     (50, 'circ_lib.billing_address'),
9616     (50, 'target_copy.location');
9617
9618
9619 --ROLLBACK;
9620
9621 SELECT evergreen.upgrade_deps_block_check('0822', :eg_version);
9622
9623 ALTER TABLE action.hold_request 
9624     ADD COLUMN behind_desk BOOLEAN NOT NULL DEFAULT FALSE;
9625
9626 -- The value on the hold is the new arbiter of whether a 
9627 -- hold should be held behind the desk and reported as such
9628 -- Update existing holds that would in the current regime
9629 -- be considered behind-the-desk holds to use the new column
9630
9631 UPDATE action.hold_request ahr
9632     SET behind_desk = TRUE
9633     FROM actor.usr_setting aus
9634     WHERE 
9635         ahr.cancel_time IS NULL AND
9636         ahr.fulfillment_time IS NULL AND
9637         aus.usr = ahr.usr AND
9638         aus.name = 'circ.holds_behind_desk' AND
9639         aus.value = 'true' AND
9640         EXISTS (
9641             SELECT 1 
9642             FROM actor.org_unit_ancestor_setting(
9643                 'circ.holds.behind_desk_pickup_supported', 
9644                 ahr.pickup_lib
9645             ) 
9646             WHERE value = 'true'
9647         );
9648
9649
9650
9651 SELECT evergreen.upgrade_deps_block_check('0823', :eg_version);
9652
9653 -- Track the requesting user
9654 ALTER TABLE staging.user_stage
9655     ADD COLUMN requesting_usr INTEGER 
9656         REFERENCES actor.usr(id) ON DELETE SET NULL;
9657
9658 -- add county column to staged address tables and 
9659 -- drop state requirement to match actor.usr_address
9660 ALTER TABLE staging.mailing_address_stage 
9661     ADD COLUMN county TEXT,
9662     ALTER COLUMN state DROP DEFAULT,
9663     ALTER COLUMN state DROP NOT NULL;
9664
9665 ALTER TABLE staging.billing_address_stage 
9666     ADD COLUMN county TEXT,
9667     ALTER COLUMN state DROP DEFAULT,
9668     ALTER COLUMN state DROP NOT NULL;
9669
9670 -- stored procedure for deleting expired pending patrons
9671 CREATE OR REPLACE FUNCTION staging.purge_pending_users() RETURNS VOID AS $$
9672 DECLARE
9673     org_id INT;
9674     intvl TEXT;
9675 BEGIN
9676     FOR org_id IN SELECT DISTINCT(home_ou) FROM staging.user_stage LOOP
9677
9678         SELECT INTO intvl value FROM 
9679             actor.org_unit_ancestor_setting(
9680                 'opac.pending_user_expire_interval', org_id);
9681
9682         CONTINUE WHEN intvl IS NULL OR intvl ILIKE 'null';
9683
9684         -- de-JSON-ify the string
9685         SELECT INTO intvl TRIM(BOTH '"' FROM intvl);
9686
9687         DELETE FROM staging.user_stage 
9688             WHERE home_ou = org_id AND row_date + intvl::INTERVAL < NOW();
9689
9690     END LOOP;
9691 END;
9692 $$ LANGUAGE PLPGSQL;
9693
9694
9695 INSERT INTO config.org_unit_setting_type
9696     (name, grp, datatype, label, description)
9697 VALUES (
9698     'opac.allow_pending_user',
9699     'opac',
9700     'bool',
9701     oils_i18n_gettext(
9702         'opac.allow_pending_user',
9703         'Allow Patron Self-Registration',
9704         'coust',
9705         'label'
9706     ),
9707     oils_i18n_gettext(
9708         'opac.allow_pending_user',
9709         'Allow patrons to self-register, creating pending user accounts',
9710         'coust',
9711         'description'
9712     )
9713 ), (
9714     'opac.pending_user_expire_interval',
9715     'opac',
9716     'interval',
9717     oils_i18n_gettext(
9718         'opac.pending_user_expire_interval',
9719         'Patron Self-Reg. Expire Interval',
9720         'coust',
9721         'label'
9722     ),
9723     oils_i18n_gettext(
9724         'opac.pending_user_expire_interval',
9725         'If set, this is the amount of time a pending user account will ' ||
9726         'be allowed to sit in the database.  After this time, the pending ' ||
9727         'user information will be purged',
9728         'coust',
9729         'description'
9730     )
9731 ), (
9732     'ui.patron.edit.aua.county.show',
9733     'gui',
9734     'bool',
9735     oils_i18n_gettext(
9736         'ui.patron.edit.aua.county.require',
9737         'Show county field on patron registration',
9738         'coust',
9739         'label'
9740     ),
9741     oils_i18n_gettext(
9742         'ui.patron.edit.aua.county.require',
9743         'The county field will be shown on the patron registration screen',
9744         'coust',
9745         'description'
9746     )
9747 );
9748
9749
9750
9751 SELECT evergreen.upgrade_deps_block_check('0824', :eg_version);
9752
9753 INSERT INTO config.org_unit_setting_type
9754     (grp, name, label, description, datatype, fm_class)
9755 VALUES (
9756     'vandelay',
9757     'vandelay.item.barcode.auto',
9758     oils_i18n_gettext(
9759         'vandelay.item.barcode.auto',
9760         'Vandelay Generate Default Barcodes',
9761         'coust', 'label'),
9762     oils_i18n_gettext(
9763         'vandelay.item.barcode.auto',
9764         'Auto-generate deault item barcodes when no item barcode is present',
9765         'coust', 'label'),
9766     'bool',
9767     NULL
9768 ), (
9769     'vandelay',
9770     'vandelay.item.barcode.prefix',
9771     oils_i18n_gettext(
9772         'vandelay.item.barcode.prefix',
9773         'Vandelay Default Barcode Prefix',
9774         'coust', 'label'),
9775     oils_i18n_gettext(
9776         'vandelay.item.barcode.prefix',
9777         'Apply this prefix to any auto-generated item barcodes',
9778         'coust', 'label'),
9779     'string',
9780     NULL
9781 ), (
9782     'vandelay',
9783     'vandelay.item.call_number.auto',
9784     oils_i18n_gettext(
9785         'vandelay.item.call_number.auto',
9786         'Vandelay Generate Default Call Numbers',
9787         'coust', 'label'),
9788     oils_i18n_gettext(
9789         'vandelay.item.call_number.auto',
9790         'Auto-generate default item call numbers when no item call number is present',
9791         'coust', 'label'),
9792     'bool',
9793     NULL
9794 ), (
9795     'vandelay',
9796     'vandelay.item.call_number.prefix',
9797     oils_i18n_gettext(
9798         'vandelay.item.call_number.prefix',
9799         'Vandelay Default Call Number Prefix',
9800         'coust', 'label'),
9801     oils_i18n_gettext(
9802         'vandelay.item.call_number.prefix',
9803         'Apply this prefix to any auto-generated item call numbers',
9804         'coust', 'label'),
9805     'string',
9806     NULL
9807 ), (
9808     'vandelay',
9809     'vandelay.item.copy_location.default',
9810     oils_i18n_gettext(
9811         'vandelay.item.copy_location.default',
9812         'Vandelay Default Copy Location',
9813         'coust', 'label'),
9814     oils_i18n_gettext(
9815         'vandelay.item.copy_location.default',
9816         'Default copy location value for imported items',
9817         'coust', 'label'),
9818     'link',
9819     'acpl'
9820 ), (
9821     'vandelay',
9822     'vandelay.item.circ_modifier.default',
9823     oils_i18n_gettext(
9824         'vandelay.item.circ_modifier.default',
9825         'Vandelay Default Circulation Modifier',
9826         'coust', 'label'),
9827     oils_i18n_gettext(
9828         'vandelay.item.circ_modifier.default',
9829         'Default circulation modifier value for imported items',
9830         'coust', 'label'),
9831     'link',
9832     'ccm'
9833 );
9834
9835
9836 CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
9837 DECLARE
9838
9839     owning_lib      TEXT;
9840     circ_lib        TEXT;
9841     call_number     TEXT;
9842     copy_number     TEXT;
9843     status          TEXT;
9844     location        TEXT;
9845     circulate       TEXT;
9846     deposit         TEXT;
9847     deposit_amount  TEXT;
9848     ref             TEXT;
9849     holdable        TEXT;
9850     price           TEXT;
9851     barcode         TEXT;
9852     circ_modifier   TEXT;
9853     circ_as_type    TEXT;
9854     alert_message   TEXT;
9855     opac_visible    TEXT;
9856     pub_note        TEXT;
9857     priv_note       TEXT;
9858     internal_id     TEXT;
9859
9860     attr_def        RECORD;
9861     tmp_attr_set    RECORD;
9862     attr_set        vandelay.import_item%ROWTYPE;
9863
9864     xpath           TEXT;
9865     tmp_str         TEXT;
9866
9867 BEGIN
9868
9869     SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
9870
9871     IF FOUND THEN
9872
9873         attr_set.definition := attr_def.id;
9874
9875         -- Build the combined XPath
9876
9877         owning_lib :=
9878             CASE
9879                 WHEN attr_def.owning_lib IS NULL THEN 'null()'
9880                 WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
9881                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
9882             END;
9883
9884         circ_lib :=
9885             CASE
9886                 WHEN attr_def.circ_lib IS NULL THEN 'null()'
9887                 WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
9888                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
9889             END;
9890
9891         call_number :=
9892             CASE
9893                 WHEN attr_def.call_number IS NULL THEN 'null()'
9894                 WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
9895                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
9896             END;
9897
9898         copy_number :=
9899             CASE
9900                 WHEN attr_def.copy_number IS NULL THEN 'null()'
9901                 WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
9902                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
9903             END;
9904
9905         status :=
9906             CASE
9907                 WHEN attr_def.status IS NULL THEN 'null()'
9908                 WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
9909                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
9910             END;
9911
9912         location :=
9913             CASE
9914                 WHEN attr_def.location IS NULL THEN 'null()'
9915                 WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
9916                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
9917             END;
9918
9919         circulate :=
9920             CASE
9921                 WHEN attr_def.circulate IS NULL THEN 'null()'
9922                 WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
9923                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
9924             END;
9925
9926         deposit :=
9927             CASE
9928                 WHEN attr_def.deposit IS NULL THEN 'null()'
9929                 WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
9930                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
9931             END;
9932
9933         deposit_amount :=
9934             CASE
9935                 WHEN attr_def.deposit_amount IS NULL THEN 'null()'
9936                 WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
9937                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
9938             END;
9939
9940         ref :=
9941             CASE
9942                 WHEN attr_def.ref IS NULL THEN 'null()'
9943                 WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
9944                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
9945             END;
9946
9947         holdable :=
9948             CASE
9949                 WHEN attr_def.holdable IS NULL THEN 'null()'
9950                 WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
9951                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
9952             END;
9953
9954         price :=
9955             CASE
9956                 WHEN attr_def.price IS NULL THEN 'null()'
9957                 WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
9958                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
9959             END;
9960
9961         barcode :=
9962             CASE
9963                 WHEN attr_def.barcode IS NULL THEN 'null()'
9964                 WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
9965                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
9966             END;
9967
9968         circ_modifier :=
9969             CASE
9970                 WHEN attr_def.circ_modifier IS NULL THEN 'null()'
9971                 WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
9972                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
9973             END;
9974
9975         circ_as_type :=
9976             CASE
9977                 WHEN attr_def.circ_as_type IS NULL THEN 'null()'
9978                 WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
9979                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
9980             END;
9981
9982         alert_message :=
9983             CASE
9984                 WHEN attr_def.alert_message IS NULL THEN 'null()'
9985                 WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
9986                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
9987             END;
9988
9989         opac_visible :=
9990             CASE
9991                 WHEN attr_def.opac_visible IS NULL THEN 'null()'
9992                 WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
9993                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
9994             END;
9995
9996         pub_note :=
9997             CASE
9998                 WHEN attr_def.pub_note IS NULL THEN 'null()'
9999                 WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
10000                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
10001             END;
10002         priv_note :=
10003             CASE
10004                 WHEN attr_def.priv_note IS NULL THEN 'null()'
10005                 WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
10006                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
10007             END;
10008
10009         internal_id :=
10010             CASE
10011                 WHEN attr_def.internal_id IS NULL THEN 'null()'
10012                 WHEN LENGTH( attr_def.internal_id ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.internal_id || '"]'
10013                 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.internal_id
10014             END;
10015
10016
10017
10018         xpath :=
10019             owning_lib      || '|' ||
10020             circ_lib        || '|' ||
10021             call_number     || '|' ||
10022             copy_number     || '|' ||
10023             status          || '|' ||
10024             location        || '|' ||
10025             circulate       || '|' ||
10026             deposit         || '|' ||
10027             deposit_amount  || '|' ||
10028             ref             || '|' ||
10029             holdable        || '|' ||
10030             price           || '|' ||
10031             barcode         || '|' ||
10032             circ_modifier   || '|' ||
10033             circ_as_type    || '|' ||
10034             alert_message   || '|' ||
10035             pub_note        || '|' ||
10036             priv_note       || '|' ||
10037             internal_id     || '|' ||
10038             opac_visible;
10039
10040         FOR tmp_attr_set IN
10041                 SELECT  *
10042                   FROM  oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
10043                             AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
10044                                   dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
10045                                   circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT, opac_vis TEXT )
10046         LOOP
10047
10048             attr_set.import_error := NULL;
10049             attr_set.error_detail := NULL;
10050             attr_set.deposit_amount := NULL;
10051             attr_set.copy_number := NULL;
10052             attr_set.price := NULL;
10053             attr_set.circ_modifier := NULL;
10054             attr_set.location := NULL;
10055             attr_set.barcode := NULL;
10056             attr_set.call_number := NULL;
10057
10058             IF tmp_attr_set.pr != '' THEN
10059                 tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
10060                 IF tmp_str = '' THEN 
10061                     attr_set.import_error := 'import.item.invalid.price';
10062                     attr_set.error_detail := tmp_attr_set.pr; -- original value
10063                     RETURN NEXT attr_set; CONTINUE; 
10064                 END IF;
10065                 attr_set.price := tmp_str::NUMERIC(8,2); 
10066             END IF;
10067
10068             IF tmp_attr_set.dep_amount != '' THEN
10069                 tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
10070                 IF tmp_str = '' THEN 
10071                     attr_set.import_error := 'import.item.invalid.deposit_amount';
10072                     attr_set.error_detail := tmp_attr_set.dep_amount; 
10073                     RETURN NEXT attr_set; CONTINUE; 
10074                 END IF;
10075                 attr_set.deposit_amount := tmp_str::NUMERIC(8,2); 
10076             END IF;
10077
10078             IF tmp_attr_set.cnum != '' THEN
10079                 tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
10080                 IF tmp_str = '' THEN 
10081                     attr_set.import_error := 'import.item.invalid.copy_number';
10082                     attr_set.error_detail := tmp_attr_set.cnum; 
10083                     RETURN NEXT attr_set; CONTINUE; 
10084                 END IF;
10085                 attr_set.copy_number := tmp_str::INT; 
10086             END IF;
10087
10088             IF tmp_attr_set.ol != '' THEN
10089                 SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
10090                 IF NOT FOUND THEN
10091                     attr_set.import_error := 'import.item.invalid.owning_lib';
10092                     attr_set.error_detail := tmp_attr_set.ol;
10093                     RETURN NEXT attr_set; CONTINUE; 
10094                 END IF;
10095             END IF;
10096
10097             IF tmp_attr_set.clib != '' THEN
10098                 SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
10099                 IF NOT FOUND THEN
10100                     attr_set.import_error := 'import.item.invalid.circ_lib';
10101                     attr_set.error_detail := tmp_attr_set.clib;
10102                     RETURN NEXT attr_set; CONTINUE; 
10103                 END IF;
10104             END IF;
10105
10106             IF tmp_attr_set.cs != '' THEN
10107                 SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
10108                 IF NOT FOUND THEN
10109                     attr_set.import_error := 'import.item.invalid.status';
10110                     attr_set.error_detail := tmp_attr_set.cs;
10111                     RETURN NEXT attr_set; CONTINUE; 
10112                 END IF;
10113             END IF;
10114
10115             IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
10116
10117                 -- no circ mod defined, see if we should apply a default
10118                 SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value) 
10119                     FROM actor.org_unit_ancestor_setting(
10120                         'vandelay.item.circ_modifier.default', 
10121                         attr_set.owning_lib
10122                     );
10123
10124                 -- make sure the value from the org setting is still valid
10125                 PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
10126                 IF NOT FOUND THEN
10127                     attr_set.import_error := 'import.item.invalid.circ_modifier';
10128                     attr_set.error_detail := tmp_attr_set.circ_mod;
10129                     RETURN NEXT attr_set; CONTINUE; 
10130                 END IF;
10131
10132             ELSE 
10133
10134                 SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
10135                 IF NOT FOUND THEN
10136                     attr_set.import_error := 'import.item.invalid.circ_modifier';
10137                     attr_set.error_detail := tmp_attr_set.circ_mod;
10138                     RETURN NEXT attr_set; CONTINUE; 
10139                 END IF;
10140             END IF;
10141
10142             IF tmp_attr_set.circ_as != '' THEN
10143                 SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
10144                 IF NOT FOUND THEN
10145                     attr_set.import_error := 'import.item.invalid.circ_as_type';
10146                     attr_set.error_detail := tmp_attr_set.circ_as;
10147                     RETURN NEXT attr_set; CONTINUE; 
10148                 END IF;
10149             END IF;
10150
10151             IF COALESCE(tmp_attr_set.cl, '') = '' THEN
10152                 -- no location specified, see if we should apply a default
10153
10154                 SELECT INTO attr_set.location TRIM(BOTH '"' FROM value) 
10155                     FROM actor.org_unit_ancestor_setting(
10156                         'vandelay.item.copy_location.default', 
10157                         attr_set.owning_lib
10158                     );
10159
10160                 -- make sure the value from the org setting is still valid
10161                 PERFORM 1 FROM asset.copy_location WHERE id = attr_set.location;
10162                 IF NOT FOUND THEN
10163                     attr_set.import_error := 'import.item.invalid.location';
10164                     attr_set.error_detail := tmp_attr_set.cs;
10165                     RETURN NEXT attr_set; CONTINUE; 
10166                 END IF;
10167             ELSE
10168
10169                 -- search up the org unit tree for a matching copy location
10170                 WITH RECURSIVE anscestor_depth AS (
10171                     SELECT  ou.id,
10172                         out.depth AS depth,
10173                         ou.parent_ou
10174                     FROM  actor.org_unit ou
10175                         JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
10176                     WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
10177                         UNION ALL
10178                     SELECT  ou.id,
10179                         out.depth,
10180                         ou.parent_ou
10181                     FROM  actor.org_unit ou
10182                         JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
10183                         JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
10184                 ) SELECT  cpl.id INTO attr_set.location
10185                     FROM  anscestor_depth a
10186                         JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
10187                     WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
10188                     ORDER BY a.depth DESC
10189                     LIMIT 1; 
10190
10191                 IF NOT FOUND THEN
10192                     attr_set.import_error := 'import.item.invalid.location';
10193                     attr_set.error_detail := tmp_attr_set.cs;
10194                     RETURN NEXT attr_set; CONTINUE; 
10195                 END IF;
10196             END IF;
10197
10198             attr_set.circulate      :=
10199                 LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
10200                 OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
10201
10202             attr_set.deposit        :=
10203                 LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
10204                 OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
10205
10206             attr_set.holdable       :=
10207                 LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
10208                 OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
10209
10210             attr_set.opac_visible   :=
10211                 LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
10212                 OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
10213
10214             attr_set.ref            :=
10215                 LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
10216                 OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
10217
10218             attr_set.call_number    := tmp_attr_set.cn; -- TEXT
10219             attr_set.barcode        := tmp_attr_set.bc; -- TEXT,
10220             attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
10221             attr_set.pub_note       := tmp_attr_set.note; -- TEXT,
10222             attr_set.priv_note      := tmp_attr_set.pnote; -- TEXT,
10223             attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
10224             attr_set.internal_id    := tmp_attr_set.internal_id::BIGINT;
10225
10226             RETURN NEXT attr_set;
10227
10228         END LOOP;
10229
10230     END IF;
10231
10232     RETURN;
10233
10234 END;
10235 $$ LANGUAGE PLPGSQL;
10236
10237
10238 SELECT evergreen.upgrade_deps_block_check('0826', :eg_version);
10239
10240 INSERT INTO permission.perm_list ( id, code, description ) VALUES (
10241     551,
10242     'ADMIN_SERVER_ADDON_FOR_WORKSTATION',
10243     oils_i18n_gettext(
10244         551,
10245         'Allows a user to specify which Server Add-ons get invoked at the current workstation',
10246         'ppl',
10247         'description'
10248     )
10249 );
10250
10251
10252
10253 SELECT evergreen.upgrade_deps_block_check('0828', :eg_version);
10254
10255 INSERT into config.org_unit_setting_type 
10256     (name, grp, label, description, datatype)
10257 VALUES ( 
10258     'opac.holds.org_unit_not_pickup_lib', 
10259     'opac',
10260     oils_i18n_gettext('opac.holds.org_unit_not_pickup_lib',
10261         'OPAC: Org Unit is not a hold pickup library',
10262         'coust', 'label'),
10263     oils_i18n_gettext('opac.holds.org_unit_not_pickup_lib',
10264         'If set, this org unit will not be offered to the patron as an '||
10265         'option for a hold pickup location.  This setting has no affect '||
10266         'on searching or hold targeting',
10267         'coust', 'description'),
10268     'bool'
10269 );
10270
10271
10272 --
10273 -- Adds a setting for selecting the number of items per page of a my list.
10274 --
10275
10276 -- check whether patch can be applied
10277 SELECT evergreen.upgrade_deps_block_check('0829', :eg_version);
10278
10279 INSERT INTO config.usr_setting_type (name,opac_visible,label,description,datatype)
10280     VALUES (
10281         'opac.list_items_per_page',
10282         TRUE,
10283         oils_i18n_gettext(
10284             'opac.list_items_per_page',
10285             'List Items per Page',
10286             'cust',
10287             'label'
10288         ),
10289         oils_i18n_gettext(
10290             'opac.list_items_per_page',
10291             'A number designating the amount of list items displayed per page of a selected list.',
10292             'cust',
10293             'description'
10294         ),
10295         'string'
10296     );
10297
10298 --
10299 -- Adds a setting for selecting the number of lists per page for my list.
10300 --
10301
10302 -- check whether patch can be applied
10303 SELECT evergreen.upgrade_deps_block_check('0830', :eg_version);
10304
10305 INSERT INTO config.usr_setting_type (name,opac_visible,label,description,datatype)
10306     VALUES (
10307         'opac.lists_per_page',
10308         TRUE,
10309         oils_i18n_gettext(
10310             'opac.lists_per_page',
10311             'Lists per Page',
10312             'cust',
10313             'label'
10314         ),
10315         oils_i18n_gettext(
10316             'opac.lists_per_page',
10317             'A number designating the amount of lists displayed per page.',
10318             'cust',
10319             'description'
10320         ),
10321         'string'
10322     );
10323     
10324
10325 SELECT evergreen.upgrade_deps_block_check('0831', :eg_version);
10326
10327 -- TODO: check for penalty ID collision before master merge; affects 
10328 -- config.standing_penalty and actor.calculate_system_penalties
10329
10330 INSERT INTO config.standing_penalty
10331     (id, name, label, block_list, staff_alert)
10332 VALUES (
10333     35,
10334     'PATRON_EXCEEDS_LONGOVERDUE_COUNT',
10335     oils_i18n_gettext(
10336         35,
10337         'Patron Exceeds Max Long-Overdue Threshold',
10338         'csp',
10339         'label'
10340     ),
10341     'CIRC|FULFILL|HOLD|CAPTURE|RENEW',
10342     TRUE
10343 );
10344
10345
10346 CREATE OR REPLACE FUNCTION actor.calculate_system_penalties( match_user INT, context_org INT ) RETURNS SETOF actor.usr_standing_penalty AS $func$
10347 DECLARE
10348     user_object         actor.usr%ROWTYPE;
10349     new_sp_row          actor.usr_standing_penalty%ROWTYPE;
10350     existing_sp_row     actor.usr_standing_penalty%ROWTYPE;
10351     collections_fines   permission.grp_penalty_threshold%ROWTYPE;
10352     max_fines           permission.grp_penalty_threshold%ROWTYPE;
10353     max_overdue         permission.grp_penalty_threshold%ROWTYPE;
10354     max_items_out       permission.grp_penalty_threshold%ROWTYPE;
10355     max_lost            permission.grp_penalty_threshold%ROWTYPE;
10356     max_longoverdue     permission.grp_penalty_threshold%ROWTYPE;
10357     tmp_grp             INT;
10358     items_overdue       INT;
10359     items_out           INT;
10360     items_lost          INT;
10361     items_longoverdue   INT;
10362     context_org_list    INT[];
10363     current_fines        NUMERIC(8,2) := 0.0;
10364     tmp_fines            NUMERIC(8,2);
10365     tmp_groc            RECORD;
10366     tmp_circ            RECORD;
10367     tmp_org             actor.org_unit%ROWTYPE;
10368     tmp_penalty         config.standing_penalty%ROWTYPE;
10369     tmp_depth           INTEGER;
10370 BEGIN
10371     SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
10372
10373     -- Max fines
10374     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10375
10376     -- Fail if the user has a high fine balance
10377     LOOP
10378         tmp_grp := user_object.profile;
10379         LOOP
10380             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 1 AND org_unit = tmp_org.id;
10381
10382             IF max_fines.threshold IS NULL THEN
10383                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10384             ELSE
10385                 EXIT;
10386             END IF;
10387
10388             IF tmp_grp IS NULL THEN
10389                 EXIT;
10390             END IF;
10391         END LOOP;
10392
10393         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10394             EXIT;
10395         END IF;
10396
10397         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10398
10399     END LOOP;
10400
10401     IF max_fines.threshold IS NOT NULL THEN
10402
10403         RETURN QUERY
10404             SELECT  *
10405               FROM  actor.usr_standing_penalty
10406               WHERE usr = match_user
10407                     AND org_unit = max_fines.org_unit
10408                     AND (stop_date IS NULL or stop_date > NOW())
10409                     AND standing_penalty = 1;
10410
10411         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10412
10413         SELECT  SUM(f.balance_owed) INTO current_fines
10414           FROM  money.materialized_billable_xact_summary f
10415                 JOIN (
10416                     SELECT  r.id
10417                       FROM  booking.reservation r
10418                       WHERE r.usr = match_user
10419                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10420                             AND xact_finish IS NULL
10421                                 UNION ALL
10422                     SELECT  g.id
10423                       FROM  money.grocery g
10424                       WHERE g.usr = match_user
10425                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10426                             AND xact_finish IS NULL
10427                                 UNION ALL
10428                     SELECT  circ.id
10429                       FROM  action.circulation circ
10430                       WHERE circ.usr = match_user
10431                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10432                             AND xact_finish IS NULL ) l USING (id);
10433
10434         IF current_fines >= max_fines.threshold THEN
10435             new_sp_row.usr := match_user;
10436             new_sp_row.org_unit := max_fines.org_unit;
10437             new_sp_row.standing_penalty := 1;
10438             RETURN NEXT new_sp_row;
10439         END IF;
10440     END IF;
10441
10442     -- Start over for max overdue
10443     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10444
10445     -- Fail if the user has too many overdue items
10446     LOOP
10447         tmp_grp := user_object.profile;
10448         LOOP
10449
10450             SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 2 AND org_unit = tmp_org.id;
10451
10452             IF max_overdue.threshold IS NULL THEN
10453                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10454             ELSE
10455                 EXIT;
10456             END IF;
10457
10458             IF tmp_grp IS NULL THEN
10459                 EXIT;
10460             END IF;
10461         END LOOP;
10462
10463         IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10464             EXIT;
10465         END IF;
10466
10467         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10468
10469     END LOOP;
10470
10471     IF max_overdue.threshold IS NOT NULL THEN
10472
10473         RETURN QUERY
10474             SELECT  *
10475               FROM  actor.usr_standing_penalty
10476               WHERE usr = match_user
10477                     AND org_unit = max_overdue.org_unit
10478                     AND (stop_date IS NULL or stop_date > NOW())
10479                     AND standing_penalty = 2;
10480
10481         SELECT  INTO items_overdue COUNT(*)
10482           FROM  action.circulation circ
10483                 JOIN  actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
10484           WHERE circ.usr = match_user
10485             AND circ.checkin_time IS NULL
10486             AND circ.due_date < NOW()
10487             AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);
10488
10489         IF items_overdue >= max_overdue.threshold::INT THEN
10490             new_sp_row.usr := match_user;
10491             new_sp_row.org_unit := max_overdue.org_unit;
10492             new_sp_row.standing_penalty := 2;
10493             RETURN NEXT new_sp_row;
10494         END IF;
10495     END IF;
10496
10497     -- Start over for max out
10498     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10499
10500     -- Fail if the user has too many checked out items
10501     LOOP
10502         tmp_grp := user_object.profile;
10503         LOOP
10504             SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 3 AND org_unit = tmp_org.id;
10505
10506             IF max_items_out.threshold IS NULL THEN
10507                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10508             ELSE
10509                 EXIT;
10510             END IF;
10511
10512             IF tmp_grp IS NULL THEN
10513                 EXIT;
10514             END IF;
10515         END LOOP;
10516
10517         IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10518             EXIT;
10519         END IF;
10520
10521         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10522
10523     END LOOP;
10524
10525
10526     -- Fail if the user has too many items checked out
10527     IF max_items_out.threshold IS NOT NULL THEN
10528
10529         RETURN QUERY
10530             SELECT  *
10531               FROM  actor.usr_standing_penalty
10532               WHERE usr = match_user
10533                     AND org_unit = max_items_out.org_unit
10534                     AND (stop_date IS NULL or stop_date > NOW())
10535                     AND standing_penalty = 3;
10536
10537         SELECT  INTO items_out COUNT(*)
10538           FROM  action.circulation circ
10539                 JOIN  actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
10540           WHERE circ.usr = match_user
10541                 AND circ.checkin_time IS NULL
10542                 AND (circ.stop_fines IN (
10543                     SELECT 'MAXFINES'::TEXT
10544                     UNION ALL
10545                     SELECT 'LONGOVERDUE'::TEXT
10546                     UNION ALL
10547                     SELECT 'LOST'::TEXT
10548                     WHERE 'true' ILIKE
10549                     (
10550                         SELECT CASE
10551                             WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.tally_lost', circ.circ_lib)) ILIKE 'true' THEN 'true'
10552                             ELSE 'false'
10553                         END
10554                     )
10555                     UNION ALL
10556                     SELECT 'CLAIMSRETURNED'::TEXT
10557                     WHERE 'false' ILIKE
10558                     (
10559                         SELECT CASE
10560                             WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.do_not_tally_claims_returned', circ.circ_lib)) ILIKE 'true' THEN 'true'
10561                             ELSE 'false'
10562                         END
10563                     )
10564                     ) OR circ.stop_fines IS NULL)
10565                 AND xact_finish IS NULL;
10566
10567            IF items_out >= max_items_out.threshold::INT THEN
10568             new_sp_row.usr := match_user;
10569             new_sp_row.org_unit := max_items_out.org_unit;
10570             new_sp_row.standing_penalty := 3;
10571             RETURN NEXT new_sp_row;
10572            END IF;
10573     END IF;
10574
10575     -- Start over for max lost
10576     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10577
10578     -- Fail if the user has too many lost items
10579     LOOP
10580         tmp_grp := user_object.profile;
10581         LOOP
10582
10583             SELECT * INTO max_lost FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 5 AND org_unit = tmp_org.id;
10584
10585             IF max_lost.threshold IS NULL THEN
10586                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10587             ELSE
10588                 EXIT;
10589             END IF;
10590
10591             IF tmp_grp IS NULL THEN
10592                 EXIT;
10593             END IF;
10594         END LOOP;
10595
10596         IF max_lost.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10597             EXIT;
10598         END IF;
10599
10600         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10601
10602     END LOOP;
10603
10604     IF max_lost.threshold IS NOT NULL THEN
10605
10606         RETURN QUERY
10607             SELECT  *
10608             FROM  actor.usr_standing_penalty
10609             WHERE usr = match_user
10610                 AND org_unit = max_lost.org_unit
10611                 AND (stop_date IS NULL or stop_date > NOW())
10612                 AND standing_penalty = 5;
10613
10614         SELECT  INTO items_lost COUNT(*)
10615         FROM  action.circulation circ
10616             JOIN  actor.org_unit_full_path( max_lost.org_unit ) fp ON (circ.circ_lib = fp.id)
10617         WHERE circ.usr = match_user
10618             AND circ.checkin_time IS NULL
10619             AND (circ.stop_fines = 'LOST')
10620             AND xact_finish IS NULL;
10621
10622         IF items_lost >= max_lost.threshold::INT AND 0 < max_lost.threshold::INT THEN
10623             new_sp_row.usr := match_user;
10624             new_sp_row.org_unit := max_lost.org_unit;
10625             new_sp_row.standing_penalty := 5;
10626             RETURN NEXT new_sp_row;
10627         END IF;
10628     END IF;
10629
10630     -- Start over for max longoverdue
10631     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10632
10633     -- Fail if the user has too many longoverdue items
10634     LOOP
10635         tmp_grp := user_object.profile;
10636         LOOP
10637
10638             SELECT * INTO max_longoverdue 
10639                 FROM permission.grp_penalty_threshold 
10640                 WHERE grp = tmp_grp AND 
10641                     penalty = 35 AND 
10642                     org_unit = tmp_org.id;
10643
10644             IF max_longoverdue.threshold IS NULL THEN
10645                 SELECT parent INTO tmp_grp 
10646                     FROM permission.grp_tree WHERE id = tmp_grp;
10647             ELSE
10648                 EXIT;
10649             END IF;
10650
10651             IF tmp_grp IS NULL THEN
10652                 EXIT;
10653             END IF;
10654         END LOOP;
10655
10656         IF max_longoverdue.threshold IS NOT NULL 
10657                 OR tmp_org.parent_ou IS NULL THEN
10658             EXIT;
10659         END IF;
10660
10661         SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10662
10663     END LOOP;
10664
10665     IF max_longoverdue.threshold IS NOT NULL THEN
10666
10667         RETURN QUERY
10668             SELECT  *
10669             FROM  actor.usr_standing_penalty
10670             WHERE usr = match_user
10671                 AND org_unit = max_longoverdue.org_unit
10672                 AND (stop_date IS NULL or stop_date > NOW())
10673                 AND standing_penalty = 35;
10674
10675         SELECT INTO items_longoverdue COUNT(*)
10676         FROM action.circulation circ
10677             JOIN actor.org_unit_full_path( max_longoverdue.org_unit ) fp 
10678                 ON (circ.circ_lib = fp.id)
10679         WHERE circ.usr = match_user
10680             AND circ.checkin_time IS NULL
10681             AND (circ.stop_fines = 'LONGOVERDUE')
10682             AND xact_finish IS NULL;
10683
10684         IF items_longoverdue >= max_longoverdue.threshold::INT 
10685                 AND 0 < max_longoverdue.threshold::INT THEN
10686             new_sp_row.usr := match_user;
10687             new_sp_row.org_unit := max_longoverdue.org_unit;
10688             new_sp_row.standing_penalty := 35;
10689             RETURN NEXT new_sp_row;
10690         END IF;
10691     END IF;
10692
10693
10694     -- Start over for collections warning
10695     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10696
10697     -- Fail if the user has a collections-level fine balance
10698     LOOP
10699         tmp_grp := user_object.profile;
10700         LOOP
10701             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id;
10702
10703             IF max_fines.threshold IS NULL THEN
10704                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10705             ELSE
10706                 EXIT;
10707             END IF;
10708
10709             IF tmp_grp IS NULL THEN
10710                 EXIT;
10711             END IF;
10712         END LOOP;
10713
10714         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10715             EXIT;
10716         END IF;
10717
10718         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10719
10720     END LOOP;
10721
10722     IF max_fines.threshold IS NOT NULL THEN
10723
10724         RETURN QUERY
10725             SELECT  *
10726               FROM  actor.usr_standing_penalty
10727               WHERE usr = match_user
10728                     AND org_unit = max_fines.org_unit
10729                     AND (stop_date IS NULL or stop_date > NOW())
10730                     AND standing_penalty = 4;
10731
10732         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10733
10734         SELECT  SUM(f.balance_owed) INTO current_fines
10735           FROM  money.materialized_billable_xact_summary f
10736                 JOIN (
10737                     SELECT  r.id
10738                       FROM  booking.reservation r
10739                       WHERE r.usr = match_user
10740                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10741                             AND r.xact_finish IS NULL
10742                                 UNION ALL
10743                     SELECT  g.id
10744                       FROM  money.grocery g
10745                       WHERE g.usr = match_user
10746                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10747                             AND g.xact_finish IS NULL
10748                                 UNION ALL
10749                     SELECT  circ.id
10750                       FROM  action.circulation circ
10751                       WHERE circ.usr = match_user
10752                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10753                             AND circ.xact_finish IS NULL ) l USING (id);
10754
10755         IF current_fines >= max_fines.threshold THEN
10756             new_sp_row.usr := match_user;
10757             new_sp_row.org_unit := max_fines.org_unit;
10758             new_sp_row.standing_penalty := 4;
10759             RETURN NEXT new_sp_row;
10760         END IF;
10761     END IF;
10762
10763     -- Start over for in collections
10764     SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10765
10766     -- Remove the in-collections penalty if the user has paid down enough
10767     -- This penalty is different, because this code is not responsible for creating 
10768     -- new in-collections penalties, only for removing them
10769     LOOP
10770         tmp_grp := user_object.profile;
10771         LOOP
10772             SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 30 AND org_unit = tmp_org.id;
10773
10774             IF max_fines.threshold IS NULL THEN
10775                 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10776             ELSE
10777                 EXIT;
10778             END IF;
10779
10780             IF tmp_grp IS NULL THEN
10781                 EXIT;
10782             END IF;
10783         END LOOP;
10784
10785         IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10786             EXIT;
10787         END IF;
10788
10789         SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10790
10791     END LOOP;
10792
10793     IF max_fines.threshold IS NOT NULL THEN
10794
10795         SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10796
10797         -- first, see if the user had paid down to the threshold
10798         SELECT  SUM(f.balance_owed) INTO current_fines
10799           FROM  money.materialized_billable_xact_summary f
10800                 JOIN (
10801                     SELECT  r.id
10802                       FROM  booking.reservation r
10803                       WHERE r.usr = match_user
10804                             AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10805                             AND r.xact_finish IS NULL
10806                                 UNION ALL
10807                     SELECT  g.id
10808                       FROM  money.grocery g
10809                       WHERE g.usr = match_user
10810                             AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10811                             AND g.xact_finish IS NULL
10812                                 UNION ALL
10813                     SELECT  circ.id
10814                       FROM  action.circulation circ
10815                       WHERE circ.usr = match_user
10816                             AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10817                             AND circ.xact_finish IS NULL ) l USING (id);
10818
10819         IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
10820             -- patron has paid down enough
10821
10822             SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = 30;
10823
10824             IF tmp_penalty.org_depth IS NOT NULL THEN
10825
10826                 -- since this code is not responsible for applying the penalty, it can't 
10827                 -- guarantee the current context org will match the org at which the penalty 
10828                 --- was applied.  search up the org tree until we hit the configured penalty depth
10829                 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10830                 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
10831
10832                 WHILE tmp_depth >= tmp_penalty.org_depth LOOP
10833
10834                     RETURN QUERY
10835                         SELECT  *
10836                           FROM  actor.usr_standing_penalty
10837                           WHERE usr = match_user
10838                                 AND org_unit = tmp_org.id
10839                                 AND (stop_date IS NULL or stop_date > NOW())
10840                                 AND standing_penalty = 30;
10841
10842                     IF tmp_org.parent_ou IS NULL THEN
10843                         EXIT;
10844                     END IF;
10845
10846                     SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10847                     SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
10848                 END LOOP;
10849
10850             ELSE
10851
10852                 -- no penalty depth is defined, look for exact matches
10853
10854                 RETURN QUERY
10855                     SELECT  *
10856                       FROM  actor.usr_standing_penalty
10857                       WHERE usr = match_user
10858                             AND org_unit = max_fines.org_unit
10859                             AND (stop_date IS NULL or stop_date > NOW())
10860                             AND standing_penalty = 30;
10861             END IF;
10862     
10863         END IF;
10864
10865     END IF;
10866
10867     RETURN;
10868 END;
10869 $func$ LANGUAGE plpgsql;
10870
10871
10872
10873 SELECT evergreen.upgrade_deps_block_check('0832', :eg_version);
10874
10875 ALTER TABLE serial.subscription_note
10876         ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10877
10878 ALTER TABLE serial.distribution_note
10879         ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10880
10881 ALTER TABLE serial.item_note
10882         ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10883
10884
10885 SELECT evergreen.upgrade_deps_block_check('0833', :eg_version);
10886
10887 INSERT INTO config.org_unit_setting_type
10888     (name, grp, datatype, label, description)
10889 VALUES (
10890     'opac.self_register.timeout',
10891     'opac',
10892     'integer',
10893     oils_i18n_gettext(
10894         'opac.self_register.timeout',
10895         'Patron Self-Reg. Display Timeout',
10896         'coust',
10897         'label'
10898     ),
10899     oils_i18n_gettext(
10900         'opac.self_register.timeout',
10901         'Number of seconds to wait before reloading the patron self-'||
10902         'registration interface to clear sensitive data',
10903         'coust',
10904         'description'
10905     )
10906 );
10907
10908
10909 SELECT evergreen.upgrade_deps_block_check('0834', :eg_version);
10910
10911 INSERT INTO config.org_unit_setting_type 
10912     (name, grp, datatype, label, description)
10913 VALUES (
10914     'ui.circ.items_out.longoverdue', 'gui', 'integer',
10915     oils_i18n_gettext(
10916         'ui.circ.items_out.longoverdue',
10917         'Items Out Long-Overdue display setting',
10918         'coust',
10919         'label'
10920     ),
10921     oils_i18n_gettext(
10922         'ui.circ.items_out.longoverdue',
10923 'Value is a numeric code, describing which list the circulation '||
10924 'should appear while checked out and whether the circulation should '||
10925 'continue to appear in the bottom list, when checked in with '||
10926 'oustanding fines.  '||
10927 '1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
10928 '5 = top list, do not display.  6 = bottom list, do not display.',
10929         'coust',
10930         'description'
10931     )
10932 ), (
10933     'ui.circ.items_out.lost', 'gui', 'integer',
10934     oils_i18n_gettext(
10935         'ui.circ.items_out.lost',
10936         'Items Out Lost display setting',
10937         'coust',
10938         'label'
10939     ),
10940     oils_i18n_gettext(
10941         'ui.circ.items_out.lost',
10942 'Value is a numeric code, describing which list the circulation '||
10943 'should appear while checked out and whether the circulation should '||
10944 'continue to appear in the bottom list, when checked in with '||
10945 'oustanding fines.  '||
10946 '1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
10947 '5 = top list, do not display.  6 = bottom list, do not display.',
10948         'coust',
10949         'description'
10950     )
10951 ), (
10952     'ui.circ.items_out.claimsreturned', 'gui', 'integer',
10953     oils_i18n_gettext(
10954         'ui.circ.items_out.claimsreturned',
10955         'Items Out Claims Returned display setting',
10956         'coust',
10957         'label'
10958     ),
10959     oils_i18n_gettext(
10960         'ui.circ.items_out.claimsreturned',
10961 'Value is a numeric code, describing which list the circulation '||
10962 'should appear while checked out and whether the circulation should '||
10963 'continue to appear in the bottom list, when checked in with '||
10964 'oustanding fines.  '||
10965 '1 = top list, bottom list.  2 = bottom list, bottom list.  ' ||
10966 '5 = top list, do not display.  6 = bottom list, do not display.',
10967         'coust',
10968         'description'
10969     )
10970 );
10971
10972
10973 SELECT evergreen.upgrade_deps_block_check('0835', :eg_version);
10974
10975 INSERT INTO config.org_unit_setting_type 
10976     (grp, name, datatype, label, description) 
10977 VALUES (
10978     'finance',
10979     'circ.disable_patron_credit',
10980     'bool',
10981     oils_i18n_gettext(
10982         'circ.disable_patron_credit',
10983         'Disable Patron Credit',
10984         'coust',
10985         'label'
10986     ),
10987     oils_i18n_gettext(
10988         'circ.disable_patron_credit',
10989         'Do not allow patrons to accrue credit or pay fines/fees with accrued credit',
10990         'coust',
10991         'description'
10992     )
10993 );
10994
10995
10996 SELECT evergreen.upgrade_deps_block_check('0836', :eg_version);
10997
10998 CREATE TABLE config.floating_group (
10999     id      SERIAL PRIMARY KEY, 
11000     name    TEXT UNIQUE NOT NULL,
11001     manual  BOOL NOT NULL DEFAULT FALSE
11002     );
11003
11004 CREATE TABLE config.floating_group_member (
11005     id              SERIAL PRIMARY KEY,
11006     floating_group  INT NOT NULL REFERENCES config.floating_group (id),
11007     org_unit        INT NOT NULL REFERENCES actor.org_unit (id),
11008     stop_depth      INT NOT NULL DEFAULT 0,
11009     max_depth       INT,
11010     exclude         BOOL NOT NULL DEFAULT FALSE
11011     );
11012
11013 CREATE OR REPLACE FUNCTION evergreen.can_float( copy_floating_group integer, from_ou integer, to_ou integer ) RETURNS BOOL AS $f$
11014 DECLARE
11015     float_member config.floating_group_member%ROWTYPE;
11016     shared_ou_depth INT;
11017     to_ou_depth INT;
11018 BEGIN
11019     -- Grab the shared OU depth. If this is less than the stop depth later we ignore the entry.
11020     SELECT INTO shared_ou_depth max(depth) FROM actor.org_unit_common_ancestors( from_ou, to_ou ) aou JOIN actor.org_unit_type aout ON aou.ou_type = aout.id;
11021     -- Grab the to ou depth. If this is greater than max depth we ignore the entry.
11022     SELECT INTO to_ou_depth depth FROM actor.org_unit aou JOIN actor.org_unit_type aout ON aou.ou_type = aout.id WHERE aou.id = to_ou;
11023     -- Grab float members that apply. We don't care what we get beyond wanting excluded ones first.
11024     SELECT INTO float_member *
11025         FROM
11026             config.floating_group_member cfgm
11027             JOIN actor.org_unit aou ON cfgm.org_unit = aou.id
11028             JOIN actor.org_unit_type aout ON aou.ou_type = aout.id
11029         WHERE
11030             cfgm.floating_group = copy_floating_group
11031             AND to_ou IN (SELECT id FROM actor.org_unit_descendants(aou.id))
11032             AND cfgm.stop_depth <= shared_ou_depth
11033             AND (cfgm.max_depth IS NULL OR to_ou_depth <= max_depth)
11034         ORDER BY
11035             exclude DESC;
11036     -- If we found something then we want to return the opposite of the exclude flag
11037     IF FOUND THEN
11038         RETURN NOT float_member.exclude;
11039     END IF;
11040     -- Otherwise no floating.
11041     RETURN false;
11042 END;
11043 $f$ LANGUAGE PLPGSQL;
11044
11045 INSERT INTO config.floating_group(name) VALUES ('Everywhere');
11046 INSERT INTO config.floating_group_member(floating_group, org_unit) VALUES (1, 1);
11047
11048 -- We need to drop these before we can update asset.copy
11049 DROP VIEW auditor.asset_copy_lifecycle;
11050 DROP VIEW auditor.serial_unit_lifecycle;
11051
11052 -- Update the appropriate auditor tables
11053 ALTER TABLE auditor.asset_copy_history
11054     ALTER COLUMN floating DROP DEFAULT,
11055     ALTER COLUMN floating DROP NOT NULL,
11056     ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11057 ALTER TABLE auditor.serial_unit_history
11058     ALTER COLUMN floating DROP DEFAULT,
11059     ALTER COLUMN floating DROP NOT NULL,
11060     ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11061
11062 -- Update asset.copy itself (does not appear to trigger update triggers!)
11063 ALTER TABLE asset.copy
11064     ALTER COLUMN floating DROP DEFAULT,
11065     ALTER COLUMN floating DROP NOT NULL,
11066     ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11067
11068 ALTER TABLE asset.copy ADD CONSTRAINT asset_copy_floating_fkey FOREIGN KEY (floating) REFERENCES config.floating_group (id) DEFERRABLE INITIALLY DEFERRED;
11069
11070 -- Update asset.copy_template too
11071 ALTER TABLE asset.copy_template
11072     ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11073 ALTER TABLE asset.copy_template ADD CONSTRAINT asset_copy_template_floating_fkey FOREIGN KEY (floating) REFERENCES config.floating_group (id) DEFERRABLE INITIALLY DEFERRED;
11074
11075 INSERT INTO permission.perm_list( code, description) VALUES
11076 ('ADMIN_FLOAT_GROUPS', 'Allows administration of floating groups');
11077
11078 -- And lets just update all auditors to re-create those lifecycle views
11079 SELECT auditor.update_auditors();
11080
11081 -- Evergreen DB patch 0837.schema.browse-auth-linking.plus-joiner.sql
11082 --
11083 -- In this upgrade script we complete inter-subfield joiner support, so that
11084 -- subject components can be separated by " -- ", for instance.  That's the
11085 -- easy part.
11086 --
11087 -- We also add the ability to browse by in-use authority main entries and find
11088 -- bibs that use unauthorized versions of the authority's value, by string matching.
11089 --
11090
11091
11092 -- check whether patch can be applied
11093 SELECT evergreen.upgrade_deps_block_check('0837', :eg_version);
11094
11095 ALTER TABLE config.metabib_field ADD COLUMN joiner TEXT;
11096 UPDATE config.metabib_field SET joiner = ' -- ' WHERE field_class = 'subject' AND name NOT IN ('name', 'complete');
11097
11098 -- To avoid problems with altering a table column after doing an
11099 -- update.
11100 ALTER TABLE authority.control_set_authority_field DISABLE TRIGGER ALL;
11101
11102 ALTER TABLE authority.control_set_authority_field ADD COLUMN joiner TEXT;
11103 UPDATE authority.control_set_authority_field SET joiner = ' -- ' WHERE tag LIKE ANY (ARRAY['_4_','_5_','_8_']);
11104
11105 ALTER TABLE authority.control_set_authority_field ENABLE TRIGGER ALL;
11106
11107 -- Seed data will be generated from class <-> axis mapping
11108 CREATE TABLE authority.control_set_bib_field_metabib_field_map (
11109     id              SERIAL  PRIMARY KEY,
11110     bib_field       INT     NOT NULL REFERENCES authority.control_set_bib_field (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
11111     metabib_field   INT     NOT NULL REFERENCES config.metabib_field (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
11112     CONSTRAINT a_bf_mf_map_once UNIQUE (bib_field, metabib_field)
11113 );
11114
11115 CREATE VIEW authority.control_set_auth_field_metabib_field_map_main AS
11116     SELECT  DISTINCT b.authority_field, m.metabib_field
11117       FROM  authority.control_set_bib_field_metabib_field_map m JOIN authority.control_set_bib_field b ON (b.id = m.bib_field);
11118 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_main IS $$metabib fields for main entry auth fields$$;
11119
11120 CREATE VIEW authority.control_set_auth_field_metabib_field_map_refs_only AS
11121     SELECT  DISTINCT a.id AS authority_field, m.metabib_field
11122       FROM  authority.control_set_authority_field a
11123             JOIN authority.control_set_authority_field ame ON (a.main_entry = ame.id)
11124             JOIN authority.control_set_bib_field b ON (b.authority_field = ame.id)
11125             JOIN authority.control_set_bib_field_metabib_field_map mf ON (mf.bib_field = b.id)
11126             JOIN authority.control_set_auth_field_metabib_field_map_main m ON (ame.id = m.authority_field);
11127 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_refs_only IS $$metabib fields for NON-main entry auth fields$$;
11128
11129 CREATE VIEW authority.control_set_auth_field_metabib_field_map_refs AS
11130     SELECT * FROM authority.control_set_auth_field_metabib_field_map_main
11131         UNION
11132     SELECT * FROM authority.control_set_auth_field_metabib_field_map_refs_only;
11133 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_refs IS $$metabib fields for all auth fields$$;
11134
11135
11136 -- blind refs only is probably what we want for lookup in bib/auth browse
11137 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_refs_only AS
11138     SELECT  r.*
11139       FROM  authority.control_set_auth_field_metabib_field_map_refs_only r
11140             JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11141       WHERE linking_subfield IS NULL;
11142 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_refs_only IS $$metabib fields for NON-main entry auth fields that can't be linked to other records$$; -- '
11143
11144 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_refs AS
11145     SELECT  r.*
11146       FROM  authority.control_set_auth_field_metabib_field_map_refs r
11147             JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11148       WHERE linking_subfield IS NULL;
11149 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_refs IS $$metabib fields for all auth fields that can't be linked to other records$$; -- '
11150
11151 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_main AS
11152     SELECT  r.*
11153       FROM  authority.control_set_auth_field_metabib_field_map_main r
11154             JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11155       WHERE linking_subfield IS NULL;
11156 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_main IS $$metabib fields for main entry auth fields that can't be linked to other records$$; -- '
11157
11158 CREATE OR REPLACE FUNCTION authority.normalize_heading( marcxml TEXT, no_thesaurus BOOL ) RETURNS TEXT AS $func$
11159 DECLARE
11160     acsaf           authority.control_set_authority_field%ROWTYPE;
11161     tag_used        TEXT;
11162     nfi_used        TEXT;
11163     sf              TEXT;
11164     sf_node         TEXT;
11165     tag_node        TEXT;
11166     thes_code       TEXT;
11167     cset            INT;
11168     heading_text    TEXT;
11169     tmp_text        TEXT;
11170     first_sf        BOOL;
11171     auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
11172 BEGIN
11173     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
11174
11175     IF cset IS NULL THEN
11176         SELECT  control_set INTO cset
11177           FROM  authority.control_set_authority_field
11178           WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
11179           LIMIT 1;
11180     END IF;
11181
11182     thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
11183     IF thes_code IS NULL THEN
11184         thes_code := '|';
11185     ELSIF thes_code = 'z' THEN
11186         thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), '' );
11187     END IF;
11188
11189     heading_text := '';
11190     FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
11191         tag_used := acsaf.tag;
11192         nfi_used := acsaf.nfi;
11193         first_sf := TRUE;
11194
11195         FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml)) LOOP
11196             FOR sf_node IN SELECT unnest(oils_xpath('./*[contains("'||acsaf.sf_list||'",@code)]',tag_node)) LOOP
11197
11198                 tmp_text := oils_xpath_string('.', sf_node);
11199                 sf := oils_xpath_string('./@code', sf_node);
11200
11201                 IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
11202
11203                     tmp_text := SUBSTRING(
11204                         tmp_text FROM
11205                         COALESCE(
11206                             NULLIF(
11207                                 REGEXP_REPLACE(
11208                                     oils_xpath_string('./@ind'||nfi_used, tag_node),
11209                                     $$\D+$$,
11210                                     '',
11211                                     'g'
11212                                 ),
11213                                 ''
11214                             )::INT,
11215                             0
11216                         ) + 1
11217                     );
11218
11219                 END IF;
11220
11221                 first_sf := FALSE;
11222
11223                 IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
11224                     heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
11225                 END IF;
11226             END LOOP;
11227
11228             EXIT WHEN heading_text <> '';
11229         END LOOP;
11230
11231         EXIT WHEN heading_text <> '';
11232     END LOOP;
11233
11234     IF heading_text <> '' THEN
11235         IF no_thesaurus IS TRUE THEN
11236             heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
11237         ELSE
11238             heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
11239         END IF;
11240     ELSE
11241         heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
11242     END IF;
11243
11244     RETURN heading_text;
11245 END;
11246 $func$ LANGUAGE PLPGSQL IMMUTABLE;
11247
11248 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
11249 DECLARE
11250     res             authority.simple_heading%ROWTYPE;
11251     acsaf           authority.control_set_authority_field%ROWTYPE;
11252     tag_used        TEXT;
11253     nfi_used        TEXT;
11254     sf              TEXT;
11255     cset            INT;
11256     heading_text    TEXT;
11257     joiner_text    TEXT;
11258     sort_text       TEXT;
11259     tmp_text        TEXT;
11260     tmp_xml         TEXT;
11261     first_sf        BOOL;
11262     auth_id         INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
11263 BEGIN
11264
11265     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
11266
11267     IF cset IS NULL THEN
11268         SELECT  control_set INTO cset
11269           FROM  authority.control_set_authority_field
11270           WHERE tag IN ( SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
11271           LIMIT 1;
11272     END IF;
11273
11274     res.record := auth_id;
11275
11276     FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
11277
11278         res.atag := acsaf.id;
11279         tag_used := acsaf.tag;
11280         nfi_used := acsaf.nfi;
11281         joiner_text := COALESCE(acsaf.joiner, ' ');
11282
11283         FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)) LOOP
11284
11285             heading_text := COALESCE(
11286                 oils_xpath_string('./*[contains("'||acsaf.sf_list||'",@code)]', tmp_xml::TEXT, joiner_text),
11287                 ''
11288             );
11289
11290             IF nfi_used IS NOT NULL THEN
11291
11292                 sort_text := SUBSTRING(
11293                     heading_text FROM
11294                     COALESCE(
11295                         NULLIF(
11296                             REGEXP_REPLACE(
11297                                 oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
11298                                 $$\D+$$,
11299                                 '',
11300                                 'g'
11301                             ),
11302                             ''
11303                         )::INT,
11304                         0
11305                     ) + 1
11306                 );
11307
11308             ELSE
11309                 sort_text := heading_text;
11310             END IF;
11311
11312             IF heading_text IS NOT NULL AND heading_text <> '' THEN
11313                 res.value := heading_text;
11314                 res.sort_value := public.naco_normalize(sort_text);
11315                 res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
11316                 RETURN NEXT res;
11317             END IF;
11318
11319         END LOOP;
11320
11321     END LOOP;
11322
11323     RETURN;
11324 END;
11325 $func$ LANGUAGE PLPGSQL IMMUTABLE;
11326
11327 CREATE TABLE metabib.browse_entry_simple_heading_map (
11328     id BIGSERIAL PRIMARY KEY,
11329     entry BIGINT REFERENCES metabib.browse_entry (id),
11330     simple_heading BIGINT REFERENCES authority.simple_heading (id) ON DELETE CASCADE
11331 );
11332 CREATE INDEX browse_entry_sh_map_entry_idx ON metabib.browse_entry_simple_heading_map (entry);
11333 CREATE INDEX browse_entry_sh_map_sh_idx ON metabib.browse_entry_simple_heading_map (simple_heading);
11334
11335 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
11336 DECLARE
11337     bib     biblio.record_entry%ROWTYPE;
11338     idx     config.metabib_field%ROWTYPE;
11339     xfrm        config.xml_transform%ROWTYPE;
11340     prev_xfrm   TEXT;
11341     transformed_xml TEXT;
11342     xml_node    TEXT;
11343     xml_node_list   TEXT[];
11344     facet_text  TEXT;
11345     browse_text TEXT;
11346     sort_value  TEXT;
11347     raw_text    TEXT;
11348     curr_text   TEXT;
11349     joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
11350     authority_text TEXT;
11351     authority_link BIGINT;
11352     output_row  metabib.field_entry_template%ROWTYPE;
11353 BEGIN
11354
11355     -- Start out with no field-use bools set
11356     output_row.browse_field = FALSE;
11357     output_row.facet_field = FALSE;
11358     output_row.search_field = FALSE;
11359
11360     -- Get the record
11361     SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
11362
11363     -- Loop over the indexing entries
11364     FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
11365
11366         joiner := COALESCE(idx.joiner, default_joiner);
11367
11368         SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
11369
11370         -- See if we can skip the XSLT ... it's expensive
11371         IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
11372             -- Can't skip the transform
11373             IF xfrm.xslt <> '---' THEN
11374                 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
11375             ELSE
11376                 transformed_xml := bib.marc;
11377             END IF;
11378
11379             prev_xfrm := xfrm.name;
11380         END IF;
11381
11382         xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11383
11384         raw_text := NULL;
11385         FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
11386             CONTINUE WHEN xml_node !~ E'^\\s*<';
11387
11388             -- XXX much of this should be moved into oils_xpath_string...
11389             curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
11390                 oils_xpath( '//text()',
11391                     REGEXP_REPLACE(
11392                         REGEXP_REPLACE( -- This escapes all &s not followed by "amp;".  Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
11393                             REGEXP_REPLACE( -- This escapes embeded <s
11394                                 xml_node,
11395                                 $re$(>[^<]+)(<)([^>]+<)$re$,
11396                                 E'\\1&lt;\\3',
11397                                 'g'
11398                             ),
11399                             '&(?!amp;)',
11400                             '&amp;',
11401                             'g'
11402                         ),
11403                         E'\\s+',
11404                         ' ',
11405                         'g'
11406                     )
11407                 ), ' '), ''),
11408                 joiner
11409             );
11410
11411             CONTINUE WHEN curr_text IS NULL OR curr_text = '';
11412
11413             IF raw_text IS NOT NULL THEN
11414                 raw_text := raw_text || joiner;
11415             END IF;
11416
11417             raw_text := COALESCE(raw_text,'') || curr_text;
11418
11419             -- autosuggest/metabib.browse_entry
11420             IF idx.browse_field THEN
11421
11422                 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
11423                     browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11424                 ELSE
11425                     browse_text := curr_text;
11426                 END IF;
11427
11428                 IF idx.browse_sort_xpath IS NOT NULL AND
11429                     idx.browse_sort_xpath <> '' THEN
11430
11431                     sort_value := oils_xpath_string(
11432                         idx.browse_sort_xpath, xml_node, joiner,
11433                         ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
11434                     );
11435                 ELSE
11436                     sort_value := browse_text;
11437                 END IF;
11438
11439                 output_row.field_class = idx.field_class;
11440                 output_row.field = idx.id;
11441                 output_row.source = rid;
11442                 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
11443                 output_row.sort_value :=
11444                     public.naco_normalize(sort_value);
11445
11446                 output_row.authority := NULL;
11447
11448                 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
11449                     authority_text := oils_xpath_string(
11450                         idx.authority_xpath, xml_node, joiner,
11451                         ARRAY[
11452                             ARRAY[xfrm.prefix, xfrm.namespace_uri],
11453                             ARRAY['xlink','http://www.w3.org/1999/xlink']
11454                         ]
11455                     );
11456
11457                     IF authority_text ~ '^\d+$' THEN
11458                         authority_link := authority_text::BIGINT;
11459                         PERFORM * FROM authority.record_entry WHERE id = authority_link;
11460                         IF FOUND THEN
11461                             output_row.authority := authority_link;
11462                         END IF;
11463                     END IF;
11464
11465                 END IF;
11466
11467                 output_row.browse_field = TRUE;
11468                 RETURN NEXT output_row;
11469                 output_row.browse_field = FALSE;
11470                 output_row.sort_value := NULL;
11471             END IF;
11472
11473             -- insert raw node text for faceting
11474             IF idx.facet_field THEN
11475
11476                 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
11477                     facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11478                 ELSE
11479                     facet_text := curr_text;
11480                 END IF;
11481
11482                 output_row.field_class = idx.field_class;
11483                 output_row.field = -1 * idx.id;
11484                 output_row.source = rid;
11485                 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
11486
11487                 output_row.facet_field = TRUE;
11488                 RETURN NEXT output_row;
11489                 output_row.facet_field = FALSE;
11490             END IF;
11491
11492         END LOOP;
11493
11494         CONTINUE WHEN raw_text IS NULL OR raw_text = '';
11495
11496         -- insert combined node text for searching
11497         IF idx.search_field THEN
11498             output_row.field_class = idx.field_class;
11499             output_row.field = idx.id;
11500             output_row.source = rid;
11501             output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
11502
11503             output_row.search_field = TRUE;
11504             RETURN NEXT output_row;
11505             output_row.search_field = FALSE;
11506         END IF;
11507
11508     END LOOP;
11509
11510 END;
11511
11512 $func$ LANGUAGE PLPGSQL;
11513
11514 CREATE OR REPLACE
11515     FUNCTION metabib.autosuggest_prepare_tsquery(orig TEXT) RETURNS TEXT[] AS
11516 $$
11517 DECLARE
11518     orig_ended_in_space     BOOLEAN;
11519     result                  RECORD;
11520     plain                   TEXT;
11521     normalized              TEXT;
11522 BEGIN
11523     orig_ended_in_space := orig ~ E'\\s$';
11524
11525     orig := ARRAY_TO_STRING(
11526         evergreen.regexp_split_to_array(orig, E'\\W+'), ' '
11527     );
11528
11529     normalized := public.naco_normalize(orig); -- also trim()s
11530     plain := trim(orig);
11531
11532     IF NOT orig_ended_in_space THEN
11533         plain := plain || ':*';
11534         normalized := normalized || ':*';
11535     END IF;
11536
11537     plain := ARRAY_TO_STRING(
11538         evergreen.regexp_split_to_array(plain, E'\\s+'), ' & '
11539     );
11540     normalized := ARRAY_TO_STRING(
11541         evergreen.regexp_split_to_array(normalized, E'\\s+'), ' & '
11542     );
11543
11544     RETURN ARRAY[normalized, plain];
11545 END;
11546 $$ LANGUAGE PLPGSQL;
11547
11548 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE sees TEXT;
11549 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE asources INT;
11550 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE aaccurate TEXT;
11551
11552 CREATE OR REPLACE FUNCTION metabib.browse_bib_pivot(
11553     INT[],
11554     TEXT
11555 ) RETURNS BIGINT AS $p$
11556     SELECT  mbe.id
11557       FROM  metabib.browse_entry mbe
11558             JOIN metabib.browse_entry_def_map mbedm ON (
11559                 mbedm.entry = mbe.id
11560                 AND mbedm.def = ANY($1)
11561             )
11562       WHERE mbe.sort_value >= public.naco_normalize($2)
11563       ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11564 $p$ LANGUAGE SQL;
11565
11566 CREATE OR REPLACE FUNCTION metabib.browse_authority_pivot(
11567     INT[],
11568     TEXT
11569 ) RETURNS BIGINT AS $p$
11570     SELECT  mbe.id
11571       FROM  metabib.browse_entry mbe
11572             JOIN metabib.browse_entry_simple_heading_map mbeshm ON ( mbeshm.entry = mbe.id )
11573             JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11574             JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11575                 ash.atag = map.authority_field
11576                 AND map.metabib_field = ANY($1)
11577             )
11578       WHERE mbe.sort_value >= public.naco_normalize($2)
11579       ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11580 $p$ LANGUAGE SQL;
11581
11582 CREATE OR REPLACE FUNCTION metabib.browse_authority_refs_pivot(
11583     INT[],
11584     TEXT
11585 ) RETURNS BIGINT AS $p$
11586     SELECT  mbe.id
11587       FROM  metabib.browse_entry mbe
11588             JOIN metabib.browse_entry_simple_heading_map mbeshm ON ( mbeshm.entry = mbe.id )
11589             JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11590             JOIN authority.control_set_auth_field_metabib_field_map_refs_only map ON (
11591                 ash.atag = map.authority_field
11592                 AND map.metabib_field = ANY($1)
11593             )
11594       WHERE mbe.sort_value >= public.naco_normalize($2)
11595       ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11596 $p$ LANGUAGE SQL;
11597
11598 -- The drop is necessary because the language change from PLPGSQL to SQL
11599 -- carries with it name changes to the parameters
11600 DROP FUNCTION metabib.browse_pivot(INT[], TEXT);
11601 CREATE FUNCTION metabib.browse_pivot(
11602     INT[],
11603     TEXT
11604 ) RETURNS BIGINT AS $p$
11605     SELECT  id FROM metabib.browse_entry
11606       WHERE id IN (
11607                 metabib.browse_bib_pivot($1, $2),
11608                 metabib.browse_authority_refs_pivot($1,$2) -- only look in 4xx, 5xx, 7xx of authority
11609             )
11610       ORDER BY sort_value, value LIMIT 1;
11611 $p$ LANGUAGE SQL;
11612
11613 CREATE OR REPLACE FUNCTION metabib.staged_browse(
11614     query                   TEXT,
11615     fields                  INT[],
11616     context_org             INT,
11617     context_locations       INT[],
11618     staff                   BOOL,
11619     browse_superpage_size   INT,
11620     count_up_from_zero      BOOL,   -- if false, count down from -1
11621     result_limit            INT,
11622     next_pivot_pos          INT
11623 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
11624 DECLARE
11625     curs                    REFCURSOR;
11626     rec                     RECORD;
11627     qpfts_query             TEXT;
11628     aqpfts_query            TEXT;
11629     afields                 INT[];
11630     bfields                 INT[];
11631     result_row              metabib.flat_browse_entry_appearance%ROWTYPE;
11632     results_skipped         INT := 0;
11633     row_counter             INT := 0;
11634     row_number              INT;
11635     slice_start             INT;
11636     slice_end               INT;
11637     full_end                INT;
11638     all_records             BIGINT[];
11639     all_brecords             BIGINT[];
11640     all_arecords            BIGINT[];
11641     superpage_of_records    BIGINT[];
11642     superpage_size          INT;
11643 BEGIN
11644     IF count_up_from_zero THEN
11645         row_number := 0;
11646     ELSE
11647         row_number := -1;
11648     END IF;
11649
11650     OPEN curs FOR EXECUTE query;
11651
11652     LOOP
11653         FETCH curs INTO rec;
11654         IF NOT FOUND THEN
11655             IF result_row.pivot_point IS NOT NULL THEN
11656                 RETURN NEXT result_row;
11657             END IF;
11658             RETURN;
11659         END IF;
11660
11661
11662         -- Gather aggregate data based on the MBE row we're looking at now, authority axis
11663         SELECT INTO all_arecords, result_row.sees, afields
11664                 ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
11665                 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT aal.source), $$,$$), -- authority record ids
11666                 ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
11667
11668           FROM  metabib.browse_entry_simple_heading_map mbeshm
11669                 JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11670                 JOIN authority.authority_linking aal ON ( ash.record = aal.source )
11671                 JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
11672                 JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11673                     ash.atag = map.authority_field
11674                     AND map.metabib_field = ANY(fields)
11675                 )
11676           WHERE mbeshm.entry = rec.id;
11677
11678
11679         -- Gather aggregate data based on the MBE row we're looking at now, bib axis
11680         SELECT INTO all_brecords, result_row.authorities, bfields
11681                 ARRAY_AGG(DISTINCT source),
11682                 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT authority), $$,$$),
11683                 ARRAY_AGG(DISTINCT def)
11684           FROM  metabib.browse_entry_def_map
11685           WHERE entry = rec.id
11686                 AND def = ANY(fields);
11687
11688         SELECT INTO result_row.fields ARRAY_TO_STRING(ARRAY_AGG(DISTINCT x), $$,$$) FROM UNNEST(afields || bfields) x;
11689
11690         result_row.sources := 0;
11691         result_row.asources := 0;
11692
11693         -- Bib-linked vis checking
11694         IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
11695
11696             full_end := ARRAY_LENGTH(all_brecords, 1);
11697             superpage_size := COALESCE(browse_superpage_size, full_end);
11698             slice_start := 1;
11699             slice_end := superpage_size;
11700
11701             WHILE result_row.sources = 0 AND slice_start <= full_end LOOP
11702                 superpage_of_records := all_brecords[slice_start:slice_end];
11703                 qpfts_query :=
11704                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
11705                     '1::INT AS rel FROM (SELECT UNNEST(' ||
11706                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
11707
11708                 -- We use search.query_parser_fts() for visibility testing.
11709                 -- We're calling it once per browse-superpage worth of records
11710                 -- out of the set of records related to a given mbe, until we've
11711                 -- either exhausted that set of records or found at least 1
11712                 -- visible record.
11713
11714                 SELECT INTO result_row.sources visible
11715                     FROM search.query_parser_fts(
11716                         context_org, NULL, qpfts_query, NULL,
11717                         context_locations, 0, NULL, NULL, FALSE, staff, FALSE
11718                     ) qpfts
11719                     WHERE qpfts.rel IS NULL;
11720
11721                 slice_start := slice_start + superpage_size;
11722                 slice_end := slice_end + superpage_size;
11723             END LOOP;
11724
11725             -- Accurate?  Well, probably.
11726             result_row.accurate := browse_superpage_size IS NULL OR
11727                 browse_superpage_size >= full_end;
11728
11729         END IF;
11730
11731         -- Authority-linked vis checking
11732         IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
11733
11734             full_end := ARRAY_LENGTH(all_arecords, 1);
11735             superpage_size := COALESCE(browse_superpage_size, full_end);
11736             slice_start := 1;
11737             slice_end := superpage_size;
11738
11739             WHILE result_row.asources = 0 AND slice_start <= full_end LOOP
11740                 superpage_of_records := all_arecords[slice_start:slice_end];
11741                 qpfts_query :=
11742                     'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
11743                     '1::INT AS rel FROM (SELECT UNNEST(' ||
11744                     quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
11745
11746                 -- We use search.query_parser_fts() for visibility testing.
11747                 -- We're calling it once per browse-superpage worth of records
11748                 -- out of the set of records related to a given mbe, via
11749                 -- authority until we've either exhausted that set of records
11750                 -- or found at least 1 visible record.
11751
11752                 SELECT INTO result_row.asources visible
11753                     FROM search.query_parser_fts(
11754                         context_org, NULL, qpfts_query, NULL,
11755                         context_locations, 0, NULL, NULL, FALSE, staff, FALSE
11756                     ) qpfts
11757                     WHERE qpfts.rel IS NULL;
11758
11759                 slice_start := slice_start + superpage_size;
11760                 slice_end := slice_end + superpage_size;
11761             END LOOP;
11762
11763
11764             -- Accurate?  Well, probably.
11765             result_row.aaccurate := browse_superpage_size IS NULL OR
11766                 browse_superpage_size >= full_end;
11767
11768         END IF;
11769
11770         IF result_row.sources > 0 OR result_row.asources > 0 THEN
11771
11772             -- The function that calls this function needs row_number in order
11773             -- to correctly order results from two different runs of this
11774             -- functions.
11775             result_row.row_number := row_number;
11776
11777             -- Now, if row_counter is still less than limit, return a row.  If
11778             -- not, but it is less than next_pivot_pos, continue on without
11779             -- returning actual result rows until we find
11780             -- that next pivot, and return it.
11781
11782             IF row_counter < result_limit THEN
11783                 result_row.browse_entry := rec.id;
11784                 result_row.value := rec.value;
11785
11786                 RETURN NEXT result_row;
11787             ELSE
11788                 result_row.browse_entry := NULL;
11789                 result_row.authorities := NULL;
11790                 result_row.fields := NULL;
11791                 result_row.value := NULL;
11792                 result_row.sources := NULL;
11793                 result_row.sees := NULL;
11794                 result_row.accurate := NULL;
11795                 result_row.aaccurate := NULL;
11796                 result_row.pivot_point := rec.id;
11797
11798                 IF row_counter >= next_pivot_pos THEN
11799                     RETURN NEXT result_row;
11800                     RETURN;
11801                 END IF;
11802             END IF;
11803
11804             IF count_up_from_zero THEN
11805                 row_number := row_number + 1;
11806             ELSE
11807                 row_number := row_number - 1;
11808             END IF;
11809
11810             -- row_counter is different from row_number.
11811             -- It simply counts up from zero so that we know when
11812             -- we've reached our limit.
11813             row_counter := row_counter + 1;
11814         END IF;
11815     END LOOP;
11816 END;
11817 $p$ LANGUAGE PLPGSQL;
11818
11819 CREATE OR REPLACE FUNCTION metabib.browse(
11820     search_field            INT[],
11821     browse_term             TEXT,
11822     context_org             INT DEFAULT NULL,
11823     context_loc_group       INT DEFAULT NULL,
11824     staff                   BOOL DEFAULT FALSE,
11825     pivot_id                BIGINT DEFAULT NULL,
11826     result_limit            INT DEFAULT 10
11827 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
11828 DECLARE
11829     core_query              TEXT;
11830     back_query              TEXT;
11831     forward_query           TEXT;
11832     pivot_sort_value        TEXT;
11833     pivot_sort_fallback     TEXT;
11834     context_locations       INT[];
11835     browse_superpage_size   INT;
11836     results_skipped         INT := 0;
11837     back_limit              INT;
11838     back_to_pivot           INT;
11839     forward_limit           INT;
11840     forward_to_pivot        INT;
11841 BEGIN
11842     -- First, find the pivot if we were given a browse term but not a pivot.
11843     IF pivot_id IS NULL THEN
11844         pivot_id := metabib.browse_pivot(search_field, browse_term);
11845     END IF;
11846
11847     SELECT INTO pivot_sort_value, pivot_sort_fallback
11848         sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
11849
11850     -- Bail if we couldn't find a pivot.
11851     IF pivot_sort_value IS NULL THEN
11852         RETURN;
11853     END IF;
11854
11855     -- Transform the context_loc_group argument (if any) (logc at the
11856     -- TPAC layer) into a form we'll be able to use.
11857     IF context_loc_group IS NOT NULL THEN
11858         SELECT INTO context_locations ARRAY_AGG(location)
11859             FROM asset.copy_location_group_map
11860             WHERE lgroup = context_loc_group;
11861     END IF;
11862
11863     -- Get the configured size of browse superpages.
11864     SELECT INTO browse_superpage_size value     -- NULL ok
11865         FROM config.global_flag
11866         WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
11867
11868     -- First we're going to search backward from the pivot, then we're going
11869     -- to search forward.  In each direction, we need two limits.  At the
11870     -- lesser of the two limits, we delineate the edge of the result set
11871     -- we're going to return.  At the greater of the two limits, we find the
11872     -- pivot value that would represent an offset from the current pivot
11873     -- at a distance of one "page" in either direction, where a "page" is a
11874     -- result set of the size specified in the "result_limit" argument.
11875     --
11876     -- The two limits in each direction make four derived values in total,
11877     -- and we calculate them now.
11878     back_limit := CEIL(result_limit::FLOAT / 2);
11879     back_to_pivot := result_limit;
11880     forward_limit := result_limit / 2;
11881     forward_to_pivot := result_limit - 1;
11882
11883     -- This is the meat of the SQL query that finds browse entries.  We'll
11884     -- pass this to a function which uses it with a cursor, so that individual
11885     -- rows may be fetched in a loop until some condition is satisfied, without
11886     -- waiting for a result set of fixed size to be collected all at once.
11887     core_query := '
11888 SELECT  mbe.id,
11889         mbe.value,
11890         mbe.sort_value
11891   FROM  metabib.browse_entry mbe
11892   WHERE (
11893             EXISTS ( -- are there any bibs using this mbe via the requested fields?
11894                 SELECT  1
11895                   FROM  metabib.browse_entry_def_map mbedm
11896                   WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
11897                   LIMIT 1
11898             ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
11899                 SELECT  1
11900                   FROM  metabib.browse_entry_simple_heading_map mbeshm
11901                         JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11902                         JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11903                             ash.atag = map.authority_field
11904                             AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
11905                         )
11906                   WHERE mbeshm.entry = mbe.id
11907             )
11908         ) AND ';
11909
11910     -- This is the variant of the query for browsing backward.
11911     back_query := core_query ||
11912         ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
11913     ' ORDER BY mbe.sort_value DESC, mbe.value DESC ';
11914
11915     -- This variant browses forward.
11916     forward_query := core_query ||
11917         ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
11918     ' ORDER BY mbe.sort_value, mbe.value ';
11919
11920     -- We now call the function which applies a cursor to the provided
11921     -- queries, stopping at the appropriate limits and also giving us
11922     -- the next page's pivot.
11923     RETURN QUERY
11924         SELECT * FROM metabib.staged_browse(
11925             back_query, search_field, context_org, context_locations,
11926             staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
11927         ) UNION
11928         SELECT * FROM metabib.staged_browse(
11929             forward_query, search_field, context_org, context_locations,
11930             staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
11931         ) ORDER BY row_number DESC;
11932
11933 END;
11934 $p$ LANGUAGE PLPGSQL;
11935
11936 -- No 4XX inter-authority linking
11937 UPDATE authority.control_set_authority_field SET linking_subfield = NULL;
11938 UPDATE authority.control_set_authority_field SET linking_subfield = '0' WHERE tag LIKE ANY (ARRAY['5%','7%']);
11939
11940 -- Map between authority controlled bib fields and stock indexing metabib fields
11941 INSERT INTO authority.control_set_bib_field_metabib_field_map (bib_field, metabib_field)
11942     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11943       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11944       WHERE a.tag = '100' AND m.name = 'personal'
11945
11946         UNION
11947
11948     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11949       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11950       WHERE a.tag = '110' AND m.name = 'corporate'
11951
11952         UNION
11953
11954     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11955       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11956       WHERE a.tag = '111' AND m.name = 'conference'
11957
11958         UNION
11959
11960     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11961       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11962       WHERE a.tag = '130' AND m.name = 'uniform'
11963
11964         UNION
11965
11966     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11967       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11968       WHERE a.tag = '148' AND m.name = 'temporal'
11969
11970         UNION
11971
11972     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11973       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11974       WHERE a.tag = '150' AND m.name = 'topic'
11975
11976         UNION
11977
11978     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11979       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11980       WHERE a.tag = '151' AND m.name = 'geographic'
11981
11982         UNION
11983
11984     SELECT  DISTINCT b.id AS bib_field, m.id AS metabib_field
11985       FROM  authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
11986       WHERE a.tag = '155' AND m.name = 'genre' -- Just in case...
11987 ;
11988
11989 CREATE OR REPLACE FUNCTION authority.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
11990 DECLARE
11991     ashs    authority.simple_heading%ROWTYPE;
11992     mbe_row metabib.browse_entry%ROWTYPE;
11993     mbe_id  BIGINT;
11994     ash_id  BIGINT;
11995 BEGIN
11996
11997     IF NEW.deleted IS TRUE THEN -- If this authority is deleted
11998         DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
11999         DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
12000         DELETE FROM authority.simple_heading WHERE record = NEW.id;
12001           -- Should remove matching $0 from controlled fields at the same time?
12002
12003         -- XXX What do we about the actual linking subfields present in
12004         -- authority records that target this one when this happens?
12005         DELETE FROM authority.authority_linking
12006             WHERE source = NEW.id OR target = NEW.id;
12007
12008         RETURN NEW; -- and we're done
12009     END IF;
12010
12011     IF TG_OP = 'UPDATE' THEN -- re-ingest?
12012         PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
12013
12014         IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
12015             RETURN NEW;
12016         END IF;
12017
12018         -- Propagate these updates to any linked bib records
12019         PERFORM authority.propagate_changes(NEW.id) FROM authority.record_entry WHERE id = NEW.id;
12020
12021         DELETE FROM authority.simple_heading WHERE record = NEW.id;
12022         DELETE FROM authority.authority_linking WHERE source = NEW.id;
12023     END IF;
12024
12025     INSERT INTO authority.authority_linking (source, target, field)
12026         SELECT source, target, field FROM authority.calculate_authority_linking(
12027             NEW.id, NEW.control_set, NEW.marc::XML
12028         );
12029
12030     FOR ashs IN SELECT * FROM authority.simple_heading_set(NEW.marc) LOOP
12031
12032         INSERT INTO authority.simple_heading (record,atag,value,sort_value)
12033             VALUES (ashs.record, ashs.atag, ashs.value, ashs.sort_value);
12034         ash_id := CURRVAL('authority.simple_heading_id_seq'::REGCLASS);
12035
12036         SELECT INTO mbe_row * FROM metabib.browse_entry
12037             WHERE value = ashs.value AND sort_value = ashs.sort_value;
12038
12039         IF FOUND THEN
12040             mbe_id := mbe_row.id;
12041         ELSE
12042             INSERT INTO metabib.browse_entry
12043                 ( value, sort_value ) VALUES
12044                 ( ashs.value, ashs.sort_value );
12045
12046             mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
12047         END IF;
12048
12049         INSERT INTO metabib.browse_entry_simple_heading_map (entry,simple_heading) VALUES (mbe_id,ash_id);
12050
12051     END LOOP;
12052
12053     -- Flatten and insert the afr data
12054     PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
12055     IF NOT FOUND THEN
12056         PERFORM authority.reingest_authority_full_rec(NEW.id);
12057         PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
12058         IF NOT FOUND THEN
12059             PERFORM authority.reingest_authority_rec_descriptor(NEW.id);
12060         END IF;
12061     END IF;
12062
12063     RETURN NEW;
12064 END;
12065 $func$ LANGUAGE PLPGSQL;
12066
12067
12068
12069 -- check whether patch can be applied
12070 SELECT evergreen.upgrade_deps_block_check('0838', :eg_version);
12071
12072 DELETE FROM config.metabib_field_index_norm_map
12073     WHERE field = 25 AND norm IN (
12074         SELECT id
12075         FROM config.index_normalizer
12076         WHERE func IN ('search_normalize','split_date_range')
12077     );
12078
12079
12080 -- check whether patch can be applied
12081 SELECT evergreen.upgrade_deps_block_check('0839', :eg_version);
12082
12083 UPDATE config.metabib_field
12084 SET
12085     xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and starts-with(@type,'alternative')]$$,
12086     browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
12087     browse_xpath = NULL
12088 WHERE
12089     field_class = 'title' AND name = 'alternative' ;
12090
12091
12092 SELECT evergreen.upgrade_deps_block_check('0840', :eg_version);
12093
12094 INSERT INTO config.usr_setting_type (name,grp,opac_visible,label,description,datatype) VALUES (
12095     'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12096     'gui',
12097     FALSE,
12098     oils_i18n_gettext(
12099         'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12100         'Circulation Policy Configuration',
12101         'cust',
12102         'label'
12103     ),
12104     oils_i18n_gettext(
12105         'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12106         'Circulation Policy Configuration Column Settings',
12107         'cust',
12108         'description'
12109     ),
12110     'string'
12111 );
12112
12113
12114 ---- check whether patch can be applied
12115 --SELECT evergreen.upgrade_deps_block_check('0841', :eg_version);
12116 --
12117 --ALTER TABLE config.metabib_field_ts_map DROP CONSTRAINT metabib_field_ts_map_metabib_field_fkey;
12118 --ALTER TABLE config.metabib_search_alias DROP CONSTRAINT metabib_search_alias_field_fkey;
12119 --ALTER TABLE config.z3950_index_field_map DROP CONSTRAINT z3950_index_field_map_metabib_field_fkey;
12120 --ALTER TABLE metabib.browse_entry_def_map DROP CONSTRAINT browse_entry_def_map_def_fkey;
12121 --
12122 --ALTER TABLE config.metabib_field_ts_map ADD CONSTRAINT metabib_field_ts_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) DEFERRABLE INITIALLY DEFERRED;
12123 --ALTER TABLE config.metabib_search_alias ADD CONSTRAINT metabib_search_alias_field_fkey FOREIGN KEY (field) REFERENCES config.metabib_field(id) DEFERRABLE INITIALLY DEFERRED;
12124 --ALTER TABLE config.z3950_index_field_map ADD CONSTRAINT z3950_index_field_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) DEFERRABLE INITIALLY DEFERRED;
12125 --ALTER TABLE metabib.browse_entry_def_map ADD CONSTRAINT browse_entry_def_map_def_fkey FOREIGN KEY (def) REFERENCES config.metabib_field(id) DEFERRABLE INITIALLY DEFERRED;
12126 --
12127 --
12128 --DROP FUNCTION IF EXISTS config.modify_metabib_field(source INT, target INT);
12129 --CREATE FUNCTION config.modify_metabib_field(v_source INT, target INT) RETURNS INT AS $func$
12130 --DECLARE
12131 --    f_class TEXT;
12132 --    check_id INT;
12133 --    target_id INT;
12134 --BEGIN
12135 --    SELECT field_class INTO f_class FROM config.metabib_field WHERE id = v_source;
12136 --    IF NOT FOUND THEN
12137 --        RETURN 0;
12138 --    END IF;
12139 --    IF target IS NULL THEN
12140 --        target_id = v_source + 1000;
12141 --    ELSE
12142 --        target_id = target;
12143 --    END IF;
12144 --    SELECT id FROM config.metabib_field INTO check_id WHERE id = target_id;
12145 --    IF FOUND THEN
12146 --        RAISE NOTICE 'Cannot bump config.metabib_field.id from % to %; the target ID already exists.', v_source, target_id;
12147 --        RETURN 0;
12148 --    END IF;
12149 --    UPDATE config.metabib_field SET id = target_id WHERE id = v_source;
12150 --    EXECUTE ' UPDATE metabib.' || f_class || '_field_entry SET field = ' || target_id || ' WHERE field = ' || v_source;
12151 --    UPDATE config.metabib_field_ts_map SET metabib_field = target_id WHERE metabib_field = v_source;
12152 --    UPDATE config.metabib_field_index_norm_map SET field = target_id WHERE field = v_source;
12153 --    UPDATE search.relevance_adjustment SET field = target_id WHERE field = v_source;
12154 --    UPDATE config.metabib_search_alias SET field = target_id WHERE field = v_source;
12155 --    UPDATE config.z3950_index_field_map SET metabib_field = target_id WHERE metabib_field = v_source;
12156 --    UPDATE metabib.browse_entry_def_map SET def = target_id WHERE def = v_source;
12157 --    RETURN 1;
12158 --END;
12159 --$func$ LANGUAGE PLPGSQL;
12160 --
12161 --SELECT config.modify_metabib_field(id, NULL)
12162 --    FROM config.metabib_field
12163 --    WHERE id > 30;
12164 --
12165 --SELECT SETVAL('config.metabib_field_id_seq', GREATEST(1000, (SELECT MAX(id) FROM config.metabib_field)));
12166 --
12167 --
12168 ---- check whether patch can be applied
12169 --SELECT evergreen.upgrade_deps_block_check('0842', :eg_version);
12170 --
12171 ---- this upgrade is only for people coming from 2_3, and is a NO-OP for those on 2_4
12172 --ALTER TABLE config.metabib_field_ts_map DROP CONSTRAINT metabib_field_ts_map_metabib_field_fkey;
12173 --
12174 --ALTER TABLE config.metabib_field_ts_map ADD CONSTRAINT metabib_field_ts_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
12175 --
12176 --
12177 ---- check whether patch can be applied
12178 --SELECT evergreen.upgrade_deps_block_check('0843', :eg_version);
12179 --
12180 ---- this upgrade file serves 2 purposes:
12181 ---- 1) add ON UPDATE CASCADE for those upgrading 2_5/master
12182 ---- 2) alter config.z3950_index_field_map for those upgrading from 2_4 and previous (other lines
12183 ----    are no-ops in this case)
12184 --ALTER TABLE config.metabib_search_alias DROP CONSTRAINT metabib_search_alias_field_fkey;
12185 --ALTER TABLE config.z3950_index_field_map DROP CONSTRAINT z3950_index_field_map_metabib_field_fkey;
12186 --ALTER TABLE metabib.browse_entry_def_map DROP CONSTRAINT browse_entry_def_map_def_fkey;
12187 --
12188 --ALTER TABLE config.metabib_search_alias ADD CONSTRAINT metabib_search_alias_field_fkey FOREIGN KEY (field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
12189 --ALTER TABLE config.z3950_index_field_map ADD CONSTRAINT z3950_index_field_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
12190 --ALTER TABLE metabib.browse_entry_def_map ADD CONSTRAINT browse_entry_def_map_def_fkey FOREIGN KEY (def) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
12191
12192
12193 -- check whether patch can be applied
12194 SELECT evergreen.upgrade_deps_block_check('0844', :eg_version);
12195
12196 -- 953.data.MODS32-xsl.sql
12197 UPDATE config.xml_transform SET xslt=$$<?xml version="1.0" encoding="UTF-8"?>
12198 <xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
12199         <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
12200 <!--
12201 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements 
12202   with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
12203
12204 Revision 1.13 - Changed order of output under cartographics to reflect schema  2006/11/28 tmee
12205         
12206 Revision 1.12 - Updated to reflect MODS 3.2 Mapping  2006/10/11 tmee
12207                 
12208 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
12209       2006/04/08  jrad
12210
12211 Revision 1.10 MODS 3.1 revisions to language and classification elements  
12212                                 (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
12213                                 2006/02/06  ggar
12214
12215 Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
12216
12217 Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
12218
12219 Revision 1.7 2004/03/25 08:29 jrad
12220
12221 Revision 1.6 various validation fixes 2004/02/20 ntra
12222
12223 Revision 1.5  2003/10/02 16:18:58  ntra
12224 MODS2 to MODS3 updates, language unstacking and 
12225 de-duping, chopPunctuation expanded
12226
12227 Revision 1.3  2003/04/03 00:07:19  ntra
12228 Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
12229
12230 Revision 1.2  2003/03/24 19:37:42  ckeith
12231 Added Log Comment
12232
12233 -->
12234         <xsl:template match="/">
12235                 <xsl:choose>
12236                         <xsl:when test="//marc:collection">
12237                                 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
12238                                         <xsl:for-each select="//marc:collection/marc:record">
12239                                                 <mods version="3.2">
12240                                                         <xsl:call-template name="marcRecord"/>
12241                                                 </mods>
12242                                         </xsl:for-each>
12243                                 </modsCollection>
12244                         </xsl:when>
12245                         <xsl:otherwise>
12246                                 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
12247                                         <xsl:for-each select="//marc:record">
12248                                                 <xsl:call-template name="marcRecord"/>
12249                                         </xsl:for-each>
12250                                 </mods>
12251                         </xsl:otherwise>
12252                 </xsl:choose>
12253         </xsl:template>
12254         <xsl:template name="marcRecord">
12255                 <xsl:variable name="leader" select="marc:leader"/>
12256                 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
12257                 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
12258                 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
12259                 <xsl:variable name="typeOf008">
12260                         <xsl:choose>
12261                                 <xsl:when test="$leader6='a'">
12262                                         <xsl:choose>
12263                                                 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
12264                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
12265                                         </xsl:choose>
12266                                 </xsl:when>
12267                                 <xsl:when test="$leader6='t'">BK</xsl:when>
12268                                 <xsl:when test="$leader6='p'">MM</xsl:when>
12269                                 <xsl:when test="$leader6='m'">CF</xsl:when>
12270                                 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
12271                                 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
12272                                 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
12273                         </xsl:choose>
12274                 </xsl:variable>
12275                 <xsl:for-each select="marc:datafield[@tag='245']">
12276                         <titleInfo>
12277                                 <xsl:variable name="title">
12278                                         <xsl:choose>
12279                                                 <xsl:when test="marc:subfield[@code='b']">
12280                                                         <xsl:call-template name="specialSubfieldSelect">
12281                                                                 <xsl:with-param name="axis">b</xsl:with-param>
12282                                                                 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
12283                                                         </xsl:call-template>
12284                                                 </xsl:when>
12285                                                 <xsl:otherwise>
12286                                                         <xsl:call-template name="subfieldSelect">
12287                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
12288                                                         </xsl:call-template>
12289                                                 </xsl:otherwise>
12290                                         </xsl:choose>
12291                                 </xsl:variable>
12292                                 <xsl:variable name="titleChop">
12293                                         <xsl:call-template name="chopPunctuation">
12294                                                 <xsl:with-param name="chopString">
12295                                                         <xsl:value-of select="$title"/>
12296                                                 </xsl:with-param>
12297                                         </xsl:call-template>
12298                                 </xsl:variable>
12299                                 <xsl:choose>
12300                                         <xsl:when test="@ind2>0">
12301                                                 <nonSort>
12302                                                         <xsl:value-of select="substring($titleChop,1,@ind2)"/>
12303                                                 </nonSort>
12304                                                 <title>
12305                                                         <xsl:value-of select="substring($titleChop,@ind2+1)"/>
12306                                                 </title>
12307                                         </xsl:when>
12308                                         <xsl:otherwise>
12309                                                 <title>
12310                                                         <xsl:value-of select="$titleChop"/>
12311                                                 </title>
12312                                         </xsl:otherwise>
12313                                 </xsl:choose>
12314                                 <xsl:if test="marc:subfield[@code='b']">
12315                                         <subTitle>
12316                                                 <xsl:call-template name="chopPunctuation">
12317                                                         <xsl:with-param name="chopString">
12318                                                                 <xsl:call-template name="specialSubfieldSelect">
12319                                                                         <xsl:with-param name="axis">b</xsl:with-param>
12320                                                                         <xsl:with-param name="anyCodes">b</xsl:with-param>
12321                                                                         <xsl:with-param name="afterCodes">afgk</xsl:with-param>
12322                                                                 </xsl:call-template>
12323                                                         </xsl:with-param>
12324                                                 </xsl:call-template>
12325                                         </subTitle>
12326                                 </xsl:if>
12327                                 <xsl:call-template name="part"></xsl:call-template>
12328                         </titleInfo>
12329                         <!-- A form of title that ignores non-filing characters; useful
12330                                  for not converting "L'Oreal" into "L' Oreal" at index time -->
12331                         <titleNonfiling>
12332                                 <title>
12333                                         <xsl:call-template name="chopPunctuation">
12334                                                 <xsl:with-param name="chopString">
12335                                                         <xsl:call-template name="subfieldSelect">
12336                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
12337                                                         </xsl:call-template>
12338                                                 </xsl:with-param>
12339                                         </xsl:call-template>
12340                                 </title>
12341                                 <xsl:call-template name="part"></xsl:call-template>
12342                         </titleNonfiling>
12343                         <!-- hybrid of titleInfo and titleNonfiling which will give us a preformatted string (for punctuation)
12344                                  but also keep the nonSort stuff in a separate field (for sorting) -->
12345                         <titleBrowse>
12346                                 <xsl:variable name="titleBrowseChop">
12347                                         <xsl:call-template name="chopPunctuation">
12348                                                 <xsl:with-param name="chopString">
12349                                                         <xsl:call-template name="subfieldSelect">
12350                                                                 <xsl:with-param name="codes">abfgk</xsl:with-param>
12351                                                         </xsl:call-template>
12352                                                 </xsl:with-param>
12353                                         </xsl:call-template>
12354                                 </xsl:variable>
12355                                 <xsl:choose>
12356                                         <xsl:when test="@ind2>0">
12357                                                 <nonSort>
12358                                                         <xsl:value-of select="substring($titleBrowseChop,1,@ind2)"/>
12359                                                 </nonSort>
12360                                                 <title>
12361                                                         <xsl:value-of select="substring($titleBrowseChop,@ind2+1)"/>
12362                                                 </title>
12363                                         </xsl:when>
12364                                         <xsl:otherwise>
12365                                                 <title>
12366                                                         <xsl:value-of select="$titleBrowseChop"/>
12367                                                 </title>
12368                                         </xsl:otherwise>
12369                                 </xsl:choose>
12370                                 <xsl:call-template name="part"></xsl:call-template>
12371                         </titleBrowse>
12372                 </xsl:for-each>
12373                 <xsl:for-each select="marc:datafield[@tag='210']">
12374                         <titleInfo type="abbreviated">
12375                                 <title>
12376                                         <xsl:call-template name="chopPunctuation">
12377                                                 <xsl:with-param name="chopString">
12378                                                         <xsl:call-template name="subfieldSelect">
12379                                                                 <xsl:with-param name="codes">a</xsl:with-param>
12380                                                         </xsl:call-template>
12381                                                 </xsl:with-param>
12382                                         </xsl:call-template>
12383                                 </title>
12384                                 <xsl:call-template name="subtitle"/>
12385                         </titleInfo>
12386                 </xsl:for-each>
12387                 <xsl:for-each select="marc:datafield[@tag='242']">
12388                         <xsl:variable name="titleChop">
12389                                 <xsl:call-template name="chopPunctuation">
12390                                         <xsl:with-param name="chopString">
12391                                                 <xsl:call-template name="subfieldSelect">
12392                                                         <!-- 1/04 removed $h, b -->
12393                                                         <xsl:with-param name="codes">a</xsl:with-param>
12394                                                 </xsl:call-template>
12395                                         </xsl:with-param>
12396                                 </xsl:call-template>
12397                         </xsl:variable>
12398                         <titleInfo type="translated">
12399                                 <!--09/01/04 Added subfield $y-->
12400                                 <xsl:for-each select="marc:subfield[@code='y']">
12401                                         <xsl:attribute name="lang">
12402                                                 <xsl:value-of select="text()"/>
12403                                         </xsl:attribute>
12404                                 </xsl:for-each>
12405                                 <title>
12406                                         <xsl:value-of select="$titleChop" />
12407                                 </title>
12408                                 <!-- 1/04 fix -->
12409                                 <xsl:call-template name="subtitle"/>
12410                                 <xsl:call-template name="part"/>
12411                         </titleInfo>
12412                         <titleInfo type="translated-nfi">
12413                                 <xsl:for-each select="marc:subfield[@code='y']">
12414                                         <xsl:attribute name="lang">
12415                                                 <xsl:value-of select="text()"/>
12416                                         </xsl:attribute>
12417                                 </xsl:for-each>
12418                                 <xsl:choose>
12419                                         <xsl:when test="@ind2>0">
12420                                                 <nonSort>
12421                                                         <xsl:value-of select="substring($titleChop,1,@ind2)"/>
12422                                                 </nonSort>
12423                                                 <title>
12424                                                         <xsl:value-of select="substring($titleChop,@ind2+1)"/>
12425                                                 </title>
12426                                         </xsl:when>
12427                                         <xsl:otherwise>
12428                                                 <title>
12429                                                         <xsl:value-of select="$titleChop" />
12430                                                 </title>
12431                                         </xsl:otherwise>
12432                                 </xsl:choose>
12433                                 <xsl:call-template name="subtitle"/>
12434                                 <xsl:call-template name="part"/>
12435                         </titleInfo>
12436                 </xsl:for-each>
12437                 <xsl:for-each select="marc:datafield[@tag='246']">
12438                         <titleInfo type="alternative">
12439                                 <xsl:for-each select="marc:subfield[@code='i']">
12440                                         <xsl:attribute name="displayLabel">
12441                                                 <xsl:value-of select="text()"/>
12442                                         </xsl:attribute>
12443                                 </xsl:for-each>
12444                                 <title>
12445                                         <xsl:call-template name="chopPunctuation">
12446                                                 <xsl:with-param name="chopString">
12447                                                         <xsl:call-template name="subfieldSelect">
12448                                                                 <!-- 1/04 removed $h, $b -->
12449                                                                 <xsl:with-param name="codes">af</xsl:with-param>
12450                                                         </xsl:call-template>
12451                                                 </xsl:with-param>
12452                                         </xsl:call-template>
12453                                 </title>
12454                                 <xsl:call-template name="subtitle"/>
12455                                 <xsl:call-template name="part"/>
12456                         </titleInfo>
12457                 </xsl:for-each>
12458                 <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
12459                         <xsl:variable name="nfi">
12460                                 <xsl:choose>
12461                                         <xsl:when test="@tag='240'">
12462                                                 <xsl:value-of select="@ind2"/>
12463                                         </xsl:when>
12464                                         <xsl:otherwise>
12465                                                 <xsl:value-of select="@ind1"/>
12466                                         </xsl:otherwise>
12467                                 </xsl:choose>
12468                         </xsl:variable>
12469                         <xsl:variable name="titleChop">
12470                                 <xsl:call-template name="uri" />
12471                                 <xsl:variable name="str">
12472                                         <xsl:for-each select="marc:subfield">
12473                                                 <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
12474                                                         <xsl:value-of select="text()"/>
12475                                                         <xsl:text> </xsl:text>
12476                                                 </xsl:if>
12477                                         </xsl:for-each>
12478                                 </xsl:variable>
12479                                 <xsl:call-template name="chopPunctuation">
12480                                         <xsl:with-param name="chopString">
12481                                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
12482                                         </xsl:with-param>
12483                                 </xsl:call-template>
12484                         </xsl:variable>
12485                         <titleInfo type="uniform">
12486                                 <title>
12487                                         <xsl:value-of select="$titleChop"/>
12488                                 </title>
12489                                 <xsl:call-template name="part"/>
12490                         </titleInfo>
12491                         <titleInfo type="uniform-nfi">
12492                                 <xsl:choose>
12493                                         <xsl:when test="$nfi>0">
12494                                                 <nonSort>
12495                                                         <xsl:value-of select="substring($titleChop,1,$nfi)"/>
12496                                                 </nonSort>
12497                                                 <title>
12498                                                         <xsl:value-of select="substring($titleChop,$nfi+1)"/>
12499                                                 </title>
12500                                         </xsl:when>
12501                                         <xsl:otherwise>
12502                                                 <title>
12503                                                         <xsl:value-of select="$titleChop"/>
12504                                                 </title>
12505                                         </xsl:otherwise>
12506                                 </xsl:choose>
12507                                 <xsl:call-template name="part"/>
12508                         </titleInfo>
12509                 </xsl:for-each>
12510                 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
12511                         <xsl:variable name="titleChop">
12512                                 <xsl:call-template name="chopPunctuation">
12513                                         <xsl:with-param name="chopString">
12514                                                 <xsl:call-template name="subfieldSelect">
12515                                                         <xsl:with-param name="codes">ah</xsl:with-param>
12516                                                 </xsl:call-template>
12517                                         </xsl:with-param>
12518                                 </xsl:call-template>
12519                         </xsl:variable>
12520                         <titleInfo type="alternative">
12521                                 <title>
12522                                         <xsl:value-of select="$titleChop" />
12523                                 </title>
12524                                 <xsl:call-template name="part"/>
12525                         </titleInfo>
12526                         <titleInfo type="alternative-nfi">
12527                                 <xsl:choose>
12528                                         <xsl:when test="@ind1>0">
12529                                                 <nonSort>
12530                                                         <xsl:value-of select="substring($titleChop,1,@ind1)"/>
12531                                                 </nonSort>
12532                                                 <title>
12533                                                         <xsl:value-of select="substring($titleChop,@ind1+1)"/>
12534                                                 </title>
12535                                         </xsl:when>
12536                                         <xsl:otherwise>
12537                                                 <title>
12538                                                         <xsl:value-of select="$titleChop" />
12539                                                 </title>
12540                                         </xsl:otherwise>
12541                                 </xsl:choose>
12542                                 <xsl:call-template name="part"/>
12543                         </titleInfo>
12544                 </xsl:for-each>
12545                 <xsl:for-each select="marc:datafield[@tag='100']">
12546                         <name type="personal">
12547                                 <xsl:call-template name="uri" />
12548                                 <xsl:call-template name="nameABCDQ"/>
12549                                 <xsl:call-template name="affiliation"/>
12550                                 <role>
12551                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12552                                 </role>
12553                                 <xsl:call-template name="role"/>
12554                         </name>
12555                 </xsl:for-each>
12556                 <xsl:for-each select="marc:datafield[@tag='110']">
12557                         <name type="corporate">
12558                                 <xsl:call-template name="uri" />
12559                                 <xsl:call-template name="nameABCDN"/>
12560                                 <role>
12561                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12562                                 </role>
12563                                 <xsl:call-template name="role"/>
12564                         </name>
12565                 </xsl:for-each>
12566                 <xsl:for-each select="marc:datafield[@tag='111']">
12567                         <name type="conference">
12568                                 <xsl:call-template name="uri" />
12569                                 <xsl:call-template name="nameACDEQ"/>
12570                                 <role>
12571                                         <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12572                                 </role>
12573                                 <xsl:call-template name="role"/>
12574                         </name>
12575                 </xsl:for-each>
12576                 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
12577                         <name type="personal">
12578                                 <xsl:call-template name="uri" />
12579                                 <xsl:call-template name="nameABCDQ"/>
12580                                 <xsl:call-template name="affiliation"/>
12581                                 <xsl:call-template name="role"/>
12582                         </name>
12583                 </xsl:for-each>
12584                 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
12585                         <name type="corporate">
12586                                 <xsl:call-template name="uri" />
12587                                 <xsl:call-template name="nameABCDN"/>
12588                                 <xsl:call-template name="role"/>
12589                         </name>
12590                 </xsl:for-each>
12591                 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
12592                         <name type="conference">
12593                                 <xsl:call-template name="uri" />
12594                                 <xsl:call-template name="nameACDEQ"/>
12595                                 <xsl:call-template name="role"/>
12596                         </name>
12597                 </xsl:for-each>
12598                 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
12599                         <name>
12600                                 <xsl:if test="@ind1=1">
12601                                         <xsl:attribute name="type">
12602                                                 <xsl:text>personal</xsl:text>
12603                                         </xsl:attribute>
12604                                 </xsl:if>
12605                                 <namePart>
12606                                         <xsl:value-of select="marc:subfield[@code='a']"/>
12607                                 </namePart>
12608                                 <xsl:call-template name="role"/>
12609                         </name>
12610                 </xsl:for-each>
12611                 <typeOfResource>
12612                         <xsl:if test="$leader7='c'">
12613                                 <xsl:attribute name="collection">yes</xsl:attribute>
12614                         </xsl:if>
12615                         <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
12616                                 <xsl:attribute name="manuscript">yes</xsl:attribute>
12617                         </xsl:if>
12618                         <xsl:choose>
12619                                 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
12620                                 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
12621                                 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
12622                                 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
12623                                 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
12624                                 <xsl:when test="$leader6='k'">still image</xsl:when>
12625                                 <xsl:when test="$leader6='g'">moving image</xsl:when>
12626                                 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
12627                                 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
12628                                 <xsl:when test="$leader6='p'">mixed material</xsl:when>
12629                         </xsl:choose>
12630                 </typeOfResource>
12631                 <xsl:if test="substring($controlField008,26,1)='d'">
12632                         <genre authority="marc">globe</genre>
12633                 </xsl:if>
12634                 <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
12635                         <genre authority="marc">remote sensing image</genre>
12636                 </xsl:if>
12637                 <xsl:if test="$typeOf008='MP'">
12638                         <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
12639                         <xsl:choose>
12640                                 <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
12641                                         <genre authority="marc">map</genre>
12642                                 </xsl:when>
12643                                 <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
12644                                         <genre authority="marc">atlas</genre>
12645                                 </xsl:when>
12646                         </xsl:choose>
12647                 </xsl:if>
12648                 <xsl:if test="$typeOf008='SE'">
12649                         <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
12650                         <xsl:choose>
12651                                 <xsl:when test="$controlField008-21='d'">
12652                                         <genre authority="marc">database</genre>
12653                                 </xsl:when>
12654                                 <xsl:when test="$controlField008-21='l'">
12655                                         <genre authority="marc">loose-leaf</genre>
12656                                 </xsl:when>
12657                                 <xsl:when test="$controlField008-21='m'">
12658                                         <genre authority="marc">series</genre>
12659                                 </xsl:when>
12660                                 <xsl:when test="$controlField008-21='n'">
12661                                         <genre authority="marc">newspaper</genre>
12662                                 </xsl:when>
12663                                 <xsl:when test="$controlField008-21='p'">
12664                                         <genre authority="marc">periodical</genre>
12665                                 </xsl:when>
12666                                 <xsl:when test="$controlField008-21='w'">
12667                                         <genre authority="marc">web site</genre>
12668                                 </xsl:when>
12669                         </xsl:choose>
12670                 </xsl:if>
12671                 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
12672                         <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
12673                         <xsl:choose>
12674                                 <xsl:when test="contains($controlField008-24,'a')">
12675                                         <genre authority="marc">abstract or summary</genre>
12676                                 </xsl:when>
12677                                 <xsl:when test="contains($controlField008-24,'b')">
12678                                         <genre authority="marc">bibliography</genre>
12679                                 </xsl:when>
12680                                 <xsl:when test="contains($controlField008-24,'c')">
12681                                         <genre authority="marc">catalog</genre>
12682                                 </xsl:when>
12683                                 <xsl:when test="contains($controlField008-24,'d')">
12684                                         <genre authority="marc">dictionary</genre>
12685                                 </xsl:when>
12686                                 <xsl:when test="contains($controlField008-24,'e')">
12687                                         <genre authority="marc">encyclopedia</genre>
12688                                 </xsl:when>
12689                                 <xsl:when test="contains($controlField008-24,'f')">
12690                                         <genre authority="marc">handbook</genre>
12691                                 </xsl:when>
12692                                 <xsl:when test="contains($controlField008-24,'g')">
12693                                         <genre authority="marc">legal article</genre>
12694                                 </xsl:when>
12695                                 <xsl:when test="contains($controlField008-24,'i')">
12696                                         <genre authority="marc">index</genre>
12697                                 </xsl:when>
12698                                 <xsl:when test="contains($controlField008-24,'k')">
12699                                         <genre authority="marc">discography</genre>
12700                                 </xsl:when>
12701                                 <xsl:when test="contains($controlField008-24,'l')">
12702                                         <genre authority="marc">legislation</genre>
12703                                 </xsl:when>
12704                                 <xsl:when test="contains($controlField008-24,'m')">
12705                                         <genre authority="marc">theses</genre>
12706                                 </xsl:when>
12707                                 <xsl:when test="contains($controlField008-24,'n')">
12708                                         <genre authority="marc">survey of literature</genre>
12709                                 </xsl:when>
12710                                 <xsl:when test="contains($controlField008-24,'o')">
12711                                         <genre authority="marc">review</genre>
12712                                 </xsl:when>
12713                                 <xsl:when test="contains($controlField008-24,'p')">
12714                                         <genre authority="marc">programmed text</genre>
12715                                 </xsl:when>
12716                                 <xsl:when test="contains($controlField008-24,'q')">
12717                                         <genre authority="marc">filmography</genre>
12718                                 </xsl:when>
12719                                 <xsl:when test="contains($controlField008-24,'r')">
12720                                         <genre authority="marc">directory</genre>
12721                                 </xsl:when>
12722                                 <xsl:when test="contains($controlField008-24,'s')">
12723                                         <genre authority="marc">statistics</genre>
12724                                 </xsl:when>
12725                                 <xsl:when test="contains($controlField008-24,'t')">
12726                                         <genre authority="marc">technical report</genre>
12727                                 </xsl:when>
12728                                 <xsl:when test="contains($controlField008-24,'v')">
12729                                         <genre authority="marc">legal case and case notes</genre>
12730                                 </xsl:when>
12731                                 <xsl:when test="contains($controlField008-24,'w')">
12732                                         <genre authority="marc">law report or digest</genre>
12733                                 </xsl:when>
12734                                 <xsl:when test="contains($controlField008-24,'z')">
12735                                         <genre authority="marc">treaty</genre>
12736                                 </xsl:when>
12737                         </xsl:choose>
12738                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
12739                         <xsl:choose>
12740                                 <xsl:when test="$controlField008-29='1'">
12741                                         <genre authority="marc">conference publication</genre>
12742                                 </xsl:when>
12743                         </xsl:choose>
12744                 </xsl:if>
12745                 <xsl:if test="$typeOf008='CF'">
12746                         <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
12747                         <xsl:choose>
12748                                 <xsl:when test="$controlField008-26='a'">
12749                                         <genre authority="marc">numeric data</genre>
12750                                 </xsl:when>
12751                                 <xsl:when test="$controlField008-26='e'">
12752                                         <genre authority="marc">database</genre>
12753                                 </xsl:when>
12754                                 <xsl:when test="$controlField008-26='f'">
12755                                         <genre authority="marc">font</genre>
12756                                 </xsl:when>
12757                                 <xsl:when test="$controlField008-26='g'">
12758                                         <genre authority="marc">game</genre>
12759                                 </xsl:when>
12760                         </xsl:choose>
12761                 </xsl:if>
12762                 <xsl:if test="$typeOf008='BK'">
12763                         <xsl:if test="substring($controlField008,25,1)='j'">
12764                                 <genre authority="marc">patent</genre>
12765                         </xsl:if>
12766                         <xsl:if test="substring($controlField008,31,1)='1'">
12767                                 <genre authority="marc">festschrift</genre>
12768                         </xsl:if>
12769                         <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
12770                         <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
12771                                 <genre authority="marc">biography</genre>
12772                         </xsl:if>
12773                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
12774                         <xsl:choose>
12775                                 <xsl:when test="$controlField008-33='e'">
12776                                         <genre authority="marc">essay</genre>
12777                                 </xsl:when>
12778                                 <xsl:when test="$controlField008-33='d'">
12779                                         <genre authority="marc">drama</genre>
12780                                 </xsl:when>
12781                                 <xsl:when test="$controlField008-33='c'">
12782                                         <genre authority="marc">comic strip</genre>
12783                                 </xsl:when>
12784                                 <xsl:when test="$controlField008-33='l'">
12785                                         <genre authority="marc">fiction</genre>
12786                                 </xsl:when>
12787                                 <xsl:when test="$controlField008-33='h'">
12788                                         <genre authority="marc">humor, satire</genre>
12789                                 </xsl:when>
12790                                 <xsl:when test="$controlField008-33='i'">
12791                                         <genre authority="marc">letter</genre>
12792                                 </xsl:when>
12793                                 <xsl:when test="$controlField008-33='f'">
12794                                         <genre authority="marc">novel</genre>
12795                                 </xsl:when>
12796                                 <xsl:when test="$controlField008-33='j'">
12797                                         <genre authority="marc">short story</genre>
12798                                 </xsl:when>
12799                                 <xsl:when test="$controlField008-33='s'">
12800                                         <genre authority="marc">speech</genre>
12801                                 </xsl:when>
12802                         </xsl:choose>
12803                 </xsl:if>
12804                 <xsl:if test="$typeOf008='MU'">
12805                         <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
12806                         <xsl:if test="contains($controlField008-30-31,'b')">
12807                                 <genre authority="marc">biography</genre>
12808                         </xsl:if>
12809                         <xsl:if test="contains($controlField008-30-31,'c')">
12810                                 <genre authority="marc">conference publication</genre>
12811                         </xsl:if>
12812                         <xsl:if test="contains($controlField008-30-31,'d')">
12813                                 <genre authority="marc">drama</genre>
12814                         </xsl:if>
12815                         <xsl:if test="contains($controlField008-30-31,'e')">
12816                                 <genre authority="marc">essay</genre>
12817                         </xsl:if>
12818                         <xsl:if test="contains($controlField008-30-31,'f')">
12819                                 <genre authority="marc">fiction</genre>
12820                         </xsl:if>
12821                         <xsl:if test="contains($controlField008-30-31,'o')">
12822                                 <genre authority="marc">folktale</genre>
12823                         </xsl:if>
12824                         <xsl:if test="contains($controlField008-30-31,'h')">
12825                                 <genre authority="marc">history</genre>
12826                         </xsl:if>
12827                         <xsl:if test="contains($controlField008-30-31,'k')">
12828                                 <genre authority="marc">humor, satire</genre>
12829                         </xsl:if>
12830                         <xsl:if test="contains($controlField008-30-31,'m')">
12831                                 <genre authority="marc">memoir</genre>
12832                         </xsl:if>
12833                         <xsl:if test="contains($controlField008-30-31,'p')">
12834                                 <genre authority="marc">poetry</genre>
12835                         </xsl:if>
12836                         <xsl:if test="contains($controlField008-30-31,'r')">
12837                                 <genre authority="marc">rehearsal</genre>
12838                         </xsl:if>
12839                         <xsl:if test="contains($controlField008-30-31,'g')">
12840                                 <genre authority="marc">reporting</genre>
12841                         </xsl:if>
12842                         <xsl:if test="contains($controlField008-30-31,'s')">
12843                                 <genre authority="marc">sound</genre>
12844                         </xsl:if>
12845                         <xsl:if test="contains($controlField008-30-31,'l')">
12846                                 <genre authority="marc">speech</genre>
12847                         </xsl:if>
12848                 </xsl:if>
12849                 <xsl:if test="$typeOf008='VM'">
12850                         <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
12851                         <xsl:choose>
12852                                 <xsl:when test="$controlField008-33='a'">
12853                                         <genre authority="marc">art original</genre>
12854                                 </xsl:when>
12855                                 <xsl:when test="$controlField008-33='b'">
12856                                         <genre authority="marc">kit</genre>
12857                                 </xsl:when>
12858                                 <xsl:when test="$controlField008-33='c'">
12859                                         <genre authority="marc">art reproduction</genre>
12860                                 </xsl:when>
12861                                 <xsl:when test="$controlField008-33='d'">
12862                                         <genre authority="marc">diorama</genre>
12863                                 </xsl:when>
12864                                 <xsl:when test="$controlField008-33='f'">
12865                                         <genre authority="marc">filmstrip</genre>
12866                                 </xsl:when>
12867                                 <xsl:when test="$controlField008-33='g'">
12868                                         <genre authority="marc">legal article</genre>
12869                                 </xsl:when>
12870                                 <xsl:when test="$controlField008-33='i'">
12871                                         <genre authority="marc">picture</genre>
12872                                 </xsl:when>
12873                                 <xsl:when test="$controlField008-33='k'">
12874                                         <genre authority="marc">graphic</genre>
12875                                 </xsl:when>
12876                                 <xsl:when test="$controlField008-33='l'">
12877                                         <genre authority="marc">technical drawing</genre>
12878                                 </xsl:when>
12879                                 <xsl:when test="$controlField008-33='m'">
12880                                         <genre authority="marc">motion picture</genre>
12881                                 </xsl:when>
12882                                 <xsl:when test="$controlField008-33='n'">
12883                                         <genre authority="marc">chart</genre>
12884                                 </xsl:when>
12885                                 <xsl:when test="$controlField008-33='o'">
12886                                         <genre authority="marc">flash card</genre>
12887                                 </xsl:when>
12888                                 <xsl:when test="$controlField008-33='p'">
12889                                         <genre authority="marc">microscope slide</genre>
12890                                 </xsl:when>
12891                                 <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
12892                                         <genre authority="marc">model</genre>
12893                                 </xsl:when>
12894                                 <xsl:when test="$controlField008-33='r'">
12895                                         <genre authority="marc">realia</genre>
12896                                 </xsl:when>
12897                                 <xsl:when test="$controlField008-33='s'">
12898                                         <genre authority="marc">slide</genre>
12899                                 </xsl:when>
12900                                 <xsl:when test="$controlField008-33='t'">
12901                                         <genre authority="marc">transparency</genre>
12902                                 </xsl:when>
12903                                 <xsl:when test="$controlField008-33='v'">
12904                                         <genre authority="marc">videorecording</genre>
12905                                 </xsl:when>
12906                                 <xsl:when test="$controlField008-33='w'">
12907                                         <genre authority="marc">toy</genre>
12908                                 </xsl:when>
12909                         </xsl:choose>
12910                 </xsl:if>
12911                 <xsl:for-each select="marc:datafield[@tag=655]">
12912                         <genre authority="marc">
12913                                 <xsl:attribute name="authority">
12914                                         <xsl:value-of select="marc:subfield[@code='2']"/>
12915                                 </xsl:attribute>
12916                                 <xsl:call-template name="subfieldSelect">
12917                                         <xsl:with-param name="codes">abvxyz</xsl:with-param>
12918                                         <xsl:with-param name="delimeter">-</xsl:with-param>
12919                                 </xsl:call-template>
12920                         </genre>
12921                 </xsl:for-each>
12922                 <originInfo>
12923                         <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
12924                         <xsl:if test="translate($MARCpublicationCode,'|','')">
12925                                 <place>
12926                                         <placeTerm>
12927                                                 <xsl:attribute name="type">code</xsl:attribute>
12928                                                 <xsl:attribute name="authority">marccountry</xsl:attribute>
12929                                                 <xsl:value-of select="$MARCpublicationCode"/>
12930                                         </placeTerm>
12931                                 </place>
12932                         </xsl:if>
12933                         <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
12934                                 <place>
12935                                         <placeTerm>
12936                                                 <xsl:attribute name="type">code</xsl:attribute>
12937                                                 <xsl:attribute name="authority">iso3166</xsl:attribute>
12938                                                 <xsl:value-of select="."/>
12939                                         </placeTerm>
12940                                 </place>
12941                         </xsl:for-each>
12942                         <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
12943                                 <place>
12944                                         <placeTerm>
12945                                                 <xsl:attribute name="type">text</xsl:attribute>
12946                                                 <xsl:call-template name="chopPunctuationFront">
12947                                                         <xsl:with-param name="chopString">
12948                                                                 <xsl:call-template name="chopPunctuation">
12949                                                                         <xsl:with-param name="chopString" select="."/>
12950                                                                 </xsl:call-template>
12951                                                         </xsl:with-param>
12952                                                 </xsl:call-template>
12953                                         </placeTerm>
12954                                 </place>
12955                         </xsl:for-each>
12956                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
12957                                 <dateValid point="start">
12958                                         <xsl:value-of select="."/>
12959                                 </dateValid>
12960                         </xsl:for-each>
12961                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
12962                                 <dateValid point="end">
12963                                         <xsl:value-of select="."/>
12964                                 </dateValid>
12965                         </xsl:for-each>
12966                         <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
12967                                 <dateModified>
12968                                         <xsl:value-of select="."/>
12969                                 </dateModified>
12970                         </xsl:for-each>
12971                         <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
12972                                 <xsl:choose>
12973                                         <xsl:when test="@code='b'">
12974                                                 <publisher>
12975                                                         <xsl:call-template name="chopPunctuation">
12976                                                                 <xsl:with-param name="chopString" select="."/>
12977                                                                 <xsl:with-param name="punctuation">
12978                                                                         <xsl:text>:,;/ </xsl:text>
12979                                                                 </xsl:with-param>
12980                                                         </xsl:call-template>
12981                                                 </publisher>
12982                                         </xsl:when>
12983                                         <xsl:when test="@code='c'">
12984                                                 <dateIssued>
12985                                                         <xsl:call-template name="chopPunctuation">
12986                                                                 <xsl:with-param name="chopString" select="."/>
12987                                                         </xsl:call-template>
12988                                                 </dateIssued>
12989                                         </xsl:when>
12990                                         <xsl:when test="@code='g'">
12991                                                 <dateCreated>
12992                                                         <xsl:value-of select="."/>
12993                                                 </dateCreated>
12994                                         </xsl:when>
12995                                 </xsl:choose>
12996                         </xsl:for-each>
12997                         <xsl:variable name="dataField260c">
12998                                 <xsl:call-template name="chopPunctuation">
12999                                         <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
13000                                 </xsl:call-template>
13001                         </xsl:variable>
13002                         <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
13003                         <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
13004                         <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
13005                         <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
13006                                 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
13007                                         <dateIssued encoding="marc">
13008                                                 <xsl:value-of select="$controlField008-7-10"/>
13009                                         </dateIssued>
13010                                 </xsl:if>
13011                         </xsl:if>
13012                         <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
13013                                 <xsl:if test="$controlField008-7-10">
13014                                         <dateIssued encoding="marc" point="start">
13015                                                 <xsl:value-of select="$controlField008-7-10"/>
13016                                         </dateIssued>
13017                                 </xsl:if>
13018                         </xsl:if>
13019                         <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
13020                                 <xsl:if test="$controlField008-11-14">
13021                                         <dateIssued encoding="marc" point="end">
13022                                                 <xsl:value-of select="$controlField008-11-14"/>
13023                                         </dateIssued>
13024                                 </xsl:if>
13025                         </xsl:if>
13026                         <xsl:if test="$controlField008-6='q'">
13027                                 <xsl:if test="$controlField008-7-10">
13028                                         <dateIssued encoding="marc" point="start" qualifier="questionable">
13029                                                 <xsl:value-of select="$controlField008-7-10"/>
13030                                         </dateIssued>
13031                                 </xsl:if>
13032                         </xsl:if>
13033                         <xsl:if test="$controlField008-6='q'">
13034                                 <xsl:if test="$controlField008-11-14">
13035                                         <dateIssued encoding="marc" point="end" qualifier="questionable">
13036                                                 <xsl:value-of select="$controlField008-11-14"/>
13037                                         </dateIssued>
13038                                 </xsl:if>
13039                         </xsl:if>
13040                         <xsl:if test="$controlField008-6='t'">
13041                                 <xsl:if test="$controlField008-11-14">
13042                                         <copyrightDate encoding="marc">
13043                                                 <xsl:value-of select="$controlField008-11-14"/>
13044                                         </copyrightDate>
13045                                 </xsl:if>
13046                         </xsl:if>
13047                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
13048                                 <dateCaptured encoding="iso8601">
13049                                         <xsl:value-of select="."/>
13050                                 </dateCaptured>
13051                         </xsl:for-each>
13052                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
13053                                 <dateCaptured encoding="iso8601" point="start">
13054                                         <xsl:value-of select="."/>
13055                                 </dateCaptured>
13056                         </xsl:for-each>
13057                         <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
13058                                 <dateCaptured encoding="iso8601" point="end">
13059                                         <xsl:value-of select="."/>
13060                                 </dateCaptured>
13061                         </xsl:for-each>
13062                         <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
13063                                 <edition>
13064                                         <xsl:value-of select="."/>
13065                                 </edition>
13066                         </xsl:for-each>
13067                         <xsl:for-each select="marc:leader">
13068                                 <issuance>
13069                                         <xsl:choose>
13070                                                 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
13071                                                 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
13072                                         </xsl:choose>
13073                                 </issuance>
13074                         </xsl:for-each>
13075                         <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
13076                                 <frequency>
13077                                         <xsl:call-template name="subfieldSelect">
13078                                                 <xsl:with-param name="codes">ab</xsl:with-param>
13079                                         </xsl:call-template>
13080                                 </frequency>
13081                         </xsl:for-each>
13082                 </originInfo>
13083                 <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
13084                 <xsl:if test="$controlField008-35-37">
13085                         <language>
13086                                 <languageTerm authority="iso639-2b" type="code">
13087                                         <xsl:value-of select="substring($controlField008,36,3)"/>
13088                                 </languageTerm>
13089                         </language>
13090                 </xsl:if>
13091                 <xsl:for-each select="marc:datafield[@tag=041]">
13092                         <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
13093                                 <xsl:variable name="langCodes" select="."/>
13094                                 <xsl:choose>
13095                                         <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
13096                                                 <!-- not stacked but could be repeated -->
13097                                                 <xsl:call-template name="rfcLanguages">
13098                                                         <xsl:with-param name="nodeNum">
13099                                                                 <xsl:value-of select="1"/>
13100                                                         </xsl:with-param>
13101                                                         <xsl:with-param name="usedLanguages">
13102                                                                 <xsl:text></xsl:text>
13103                                                         </xsl:with-param>
13104                                                         <xsl:with-param name="controlField008-35-37">
13105                                                                 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
13106                                                         </xsl:with-param>
13107                                                 </xsl:call-template>
13108                                         </xsl:when>
13109                                         <xsl:otherwise>
13110                                                 <!-- iso -->
13111                                                 <xsl:variable name="allLanguages">
13112                                                         <xsl:copy-of select="$langCodes"></xsl:copy-of>
13113                                                 </xsl:variable>
13114                                                 <xsl:variable name="currentLanguage">
13115                                                         <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
13116                                                 </xsl:variable>
13117                                                 <xsl:call-template name="isoLanguage">
13118                                                         <xsl:with-param name="currentLanguage">
13119                                                                 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
13120                                                         </xsl:with-param>
13121                                                         <xsl:with-param name="remainingLanguages">
13122                                                                 <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
13123                                                         </xsl:with-param>
13124                                                         <xsl:with-param name="usedLanguages">
13125                                                                 <xsl:if test="$controlField008-35-37">
13126                                                                         <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
13127                                                                 </xsl:if>
13128                                                         </xsl:with-param>
13129                                                 </xsl:call-template>
13130                                         </xsl:otherwise>
13131                                 </xsl:choose>
13132                         </xsl:for-each>
13133                 </xsl:for-each>
13134                 <xsl:variable name="physicalDescription">
13135                         <!--3.2 change tmee 007/11 -->
13136                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
13137                                 <digitalOrigin>reformatted digital</digitalOrigin>
13138                         </xsl:if>
13139                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
13140                                 <digitalOrigin>digitized microfilm</digitalOrigin>
13141                         </xsl:if>
13142                         <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
13143                                 <digitalOrigin>digitized other analog</digitalOrigin>
13144                         </xsl:if>
13145                         <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
13146                         <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
13147                         <xsl:variable name="check008-23">
13148                                 <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
13149                                         <xsl:value-of select="true()"></xsl:value-of>
13150                                 </xsl:if>
13151                         </xsl:variable>
13152                         <xsl:variable name="check008-29">
13153                                 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
13154                                         <xsl:value-of select="true()"></xsl:value-of>
13155                                 </xsl:if>
13156                         </xsl:variable>
13157                         <xsl:choose>
13158                                 <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
13159                                         <form authority="marcform">braille</form>
13160                                 </xsl:when>
13161                                 <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
13162                                         <form authority="marcform">print</form>
13163                                 </xsl:when>
13164                                 <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
13165                                         <form authority="marcform">electronic</form>
13166                                 </xsl:when>
13167                                 <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
13168                                         <form authority="marcform">microfiche</form>
13169                                 </xsl:when>
13170                                 <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
13171                                         <form authority="marcform">microfilm</form>
13172                                 </xsl:when>
13173                         </xsl:choose>
13174                         <!-- 1/04 fix -->
13175                         <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
13176                                 <form authority="gmd">
13177                                         <xsl:call-template name="chopBrackets">
13178                                                 <xsl:with-param name="chopString">
13179                                                         <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
13180                                                 </xsl:with-param>
13181                                         </xsl:call-template>
13182                                 </form>
13183                         </xsl:if>
13184                         <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
13185                                 <form authority="gmd">
13186                                         <xsl:call-template name="chopBrackets">
13187                                                 <xsl:with-param name="chopString">
13188                                                         <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
13189                                                 </xsl:with-param>
13190                                         </xsl:call-template>
13191                                 </form>
13192                         </xsl:if>
13193                         <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
13194                                 <form authority="gmd">
13195                                         <xsl:call-template name="chopBrackets">
13196                                                 <xsl:with-param name="chopString">
13197                                                         <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
13198                                                 </xsl:with-param>
13199                                         </xsl:call-template>
13200                                 </form>
13201                         </xsl:if>
13202                         <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
13203                                 <form authority="gmd">
13204                                         <xsl:call-template name="chopBrackets">
13205                                                 <xsl:with-param name="chopString">
13206                                                         <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
13207                                                 </xsl:with-param>
13208                                         </xsl:call-template>
13209                                 </form>
13210                         </xsl:if>
13211                         <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
13212                                 <form authority="gmd">
13213                                         <xsl:call-template name="chopBrackets">
13214                                                 <xsl:with-param name="chopString">
13215                                                         <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
13216                                                 </xsl:with-param>
13217                                         </xsl:call-template>
13218                                 </form>
13219                         </xsl:if>
13220                         <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
13221                                 <form authority="gmd">
13222                                         <xsl:call-template name="chopBrackets">
13223                                                 <xsl:with-param name="chopString">
13224                                                         <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
13225                                                 </xsl:with-param>
13226                                         </xsl:call-template>
13227                                 </form>
13228                         </xsl:if>
13229                         <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
13230                                 <form>
13231                                         <xsl:value-of select="."></xsl:value-of>
13232                                 </form>
13233                         </xsl:for-each>
13234                         <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
13235                                 <xsl:choose>
13236                                         <xsl:when test="substring(text(),14,1)='a'">
13237                                                 <reformattingQuality>access</reformattingQuality>
13238                                         </xsl:when>
13239                                         <xsl:when test="substring(text(),14,1)='p'">
13240                                                 <reformattingQuality>preservation</reformattingQuality>
13241                                         </xsl:when>
13242                                         <xsl:when test="substring(text(),14,1)='r'">
13243                                                 <reformattingQuality>replacement</reformattingQuality>
13244                                         </xsl:when>
13245                                 </xsl:choose>
13246                         </xsl:for-each>
13247                         <!--3.2 change tmee 007/01 -->
13248                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
13249                                 <form authority="smd">chip cartridge</form>
13250                         </xsl:if>
13251                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
13252                                 <form authority="smd">computer optical disc cartridge</form>
13253                         </xsl:if>
13254                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
13255                                 <form authority="smd">magnetic disc</form>
13256                         </xsl:if>
13257                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
13258                                 <form authority="smd">magneto-optical disc</form>
13259                         </xsl:if>
13260                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
13261                                 <form authority="smd">optical disc</form>
13262                         </xsl:if>
13263                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
13264                                 <form authority="smd">remote</form>
13265                         </xsl:if>
13266                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
13267                                 <form authority="smd">tape cartridge</form>
13268                         </xsl:if>
13269                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
13270                                 <form authority="smd">tape cassette</form>
13271                         </xsl:if>
13272                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
13273                                 <form authority="smd">tape reel</form>
13274                         </xsl:if>
13275                         
13276                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
13277                                 <form authority="smd">celestial globe</form>
13278                         </xsl:if>
13279                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
13280                                 <form authority="smd">earth moon globe</form>
13281                         </xsl:if>
13282                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
13283                                 <form authority="smd">planetary or lunar globe</form>
13284                         </xsl:if>
13285                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
13286                                 <form authority="smd">terrestrial globe</form>
13287                         </xsl:if>
13288                         
13289                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
13290                                 <form authority="smd">kit</form>
13291                         </xsl:if>
13292                         
13293                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
13294                                 <form authority="smd">atlas</form>
13295                         </xsl:if>
13296                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
13297                                 <form authority="smd">diagram</form>
13298                         </xsl:if>
13299                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
13300                                 <form authority="smd">map</form>
13301                         </xsl:if>
13302                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
13303                                 <form authority="smd">model</form>
13304                         </xsl:if>
13305                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
13306                                 <form authority="smd">profile</form>
13307                         </xsl:if>
13308                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
13309                                 <form authority="smd">remote-sensing image</form>
13310                         </xsl:if>
13311                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
13312                                 <form authority="smd">section</form>
13313                         </xsl:if>
13314                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
13315                                 <form authority="smd">view</form>
13316                         </xsl:if>
13317                         
13318                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
13319                                 <form authority="smd">aperture card</form>
13320                         </xsl:if>
13321                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
13322                                 <form authority="smd">microfiche</form>
13323                         </xsl:if>
13324                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
13325                                 <form authority="smd">microfiche cassette</form>
13326                         </xsl:if>
13327                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
13328                                 <form authority="smd">microfilm cartridge</form>
13329                         </xsl:if>
13330                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
13331                                 <form authority="smd">microfilm cassette</form>
13332                         </xsl:if>
13333                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
13334                                 <form authority="smd">microfilm reel</form>
13335                         </xsl:if>
13336                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
13337                                 <form authority="smd">microopaque</form>
13338                         </xsl:if>
13339                         
13340                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
13341                                 <form authority="smd">film cartridge</form>
13342                         </xsl:if>
13343                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
13344                                 <form authority="smd">film cassette</form>
13345                         </xsl:if>
13346                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
13347                                 <form authority="smd">film reel</form>
13348                         </xsl:if>
13349                         
13350                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
13351                                 <form authority="smd">chart</form>
13352                         </xsl:if>
13353                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
13354                                 <form authority="smd">collage</form>
13355                         </xsl:if>
13356                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
13357                                 <form authority="smd">drawing</form>
13358                         </xsl:if>
13359                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
13360                                 <form authority="smd">flash card</form>
13361                         </xsl:if>
13362                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
13363                                 <form authority="smd">painting</form>
13364                         </xsl:if>
13365                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
13366                                 <form authority="smd">photomechanical print</form>
13367                         </xsl:if>
13368                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
13369                                 <form authority="smd">photonegative</form>
13370                         </xsl:if>
13371                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
13372                                 <form authority="smd">photoprint</form>
13373                         </xsl:if>
13374                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
13375                                 <form authority="smd">picture</form>
13376                         </xsl:if>
13377                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
13378                                 <form authority="smd">print</form>
13379                         </xsl:if>
13380                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
13381                                 <form authority="smd">technical drawing</form>
13382                         </xsl:if>
13383                         
13384                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
13385                                 <form authority="smd">notated music</form>
13386                         </xsl:if>
13387                         
13388                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
13389                                 <form authority="smd">filmslip</form>
13390                         </xsl:if>
13391                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
13392                                 <form authority="smd">filmstrip cartridge</form>
13393                         </xsl:if>
13394                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
13395                                 <form authority="smd">filmstrip roll</form>
13396                         </xsl:if>
13397                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
13398                                 <form authority="smd">other filmstrip type</form>
13399                         </xsl:if>
13400                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
13401                                 <form authority="smd">slide</form>
13402                         </xsl:if>
13403                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
13404                                 <form authority="smd">transparency</form>
13405                         </xsl:if>
13406                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
13407                                 <form authority="smd">remote-sensing image</form>
13408                         </xsl:if>
13409                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
13410                                 <form authority="smd">cylinder</form>
13411                         </xsl:if>
13412                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
13413                                 <form authority="smd">roll</form>
13414                         </xsl:if>
13415                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
13416                                 <form authority="smd">sound cartridge</form>
13417                         </xsl:if>
13418                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
13419                                 <form authority="smd">sound cassette</form>
13420                         </xsl:if>
13421                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
13422                                 <form authority="smd">sound disc</form>
13423                         </xsl:if>
13424                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
13425                                 <form authority="smd">sound-tape reel</form>
13426                         </xsl:if>
13427                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
13428                                 <form authority="smd">sound-track film</form>
13429                         </xsl:if>
13430                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
13431                                 <form authority="smd">wire recording</form>
13432                         </xsl:if>
13433                         
13434                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
13435                                 <form authority="smd">braille</form>
13436                         </xsl:if>
13437                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
13438                                 <form authority="smd">combination</form>
13439                         </xsl:if>
13440                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
13441                                 <form authority="smd">moon</form>
13442                         </xsl:if>
13443                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
13444                                 <form authority="smd">tactile, with no writing system</form>
13445                         </xsl:if>
13446                         
13447                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
13448                                 <form authority="smd">braille</form>
13449                         </xsl:if>
13450                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
13451                                 <form authority="smd">large print</form>
13452                         </xsl:if>
13453                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
13454                                 <form authority="smd">regular print</form>
13455                         </xsl:if>
13456                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
13457                                 <form authority="smd">text in looseleaf binder</form>
13458                         </xsl:if>
13459                         
13460                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
13461                                 <form authority="smd">videocartridge</form>
13462                         </xsl:if>
13463                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
13464                                 <form authority="smd">videocassette</form>
13465                         </xsl:if>
13466                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
13467                                 <form authority="smd">videodisc</form>
13468                         </xsl:if>
13469                         <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
13470                                 <form authority="smd">videoreel</form>
13471                         </xsl:if>
13472                         
13473                         <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
13474                                 <internetMediaType>
13475                                         <xsl:value-of select="."></xsl:value-of>
13476                                 </internetMediaType>
13477                         </xsl:for-each>
13478                         <xsl:for-each select="marc:datafield[@tag=300]">
13479                                 <extent>
13480                                         <xsl:call-template name="subfieldSelect">
13481                                                 <xsl:with-param name="codes">abce</xsl:with-param>
13482                                         </xsl:call-template>
13483                                 </extent>
13484                         </xsl:for-each>
13485                 </xsl:variable>
13486                 <xsl:if test="string-length(normalize-space($physicalDescription))">
13487                         <physicalDescription>
13488                                 <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
13489                         </physicalDescription>
13490                 </xsl:if>
13491                 <xsl:for-each select="marc:datafield[@tag=520]">
13492                         <abstract>
13493                                 <xsl:call-template name="uri"></xsl:call-template>
13494                                 <xsl:call-template name="subfieldSelect">
13495                                         <xsl:with-param name="codes">ab</xsl:with-param>
13496                                 </xsl:call-template>
13497                         </abstract>
13498                 </xsl:for-each>
13499                 <xsl:for-each select="marc:datafield[@tag=505]">
13500                         <tableOfContents>
13501                                 <xsl:call-template name="uri"></xsl:call-template>
13502                                 <xsl:call-template name="subfieldSelect">
13503                                         <xsl:with-param name="codes">agrt</xsl:with-param>
13504                                 </xsl:call-template>
13505                         </tableOfContents>
13506                 </xsl:for-each>
13507                 <xsl:for-each select="marc:datafield[@tag=521]">
13508                         <targetAudience>
13509                                 <xsl:call-template name="subfieldSelect">
13510                                         <xsl:with-param name="codes">ab</xsl:with-param>
13511                                 </xsl:call-template>
13512                         </targetAudience>
13513                 </xsl:for-each>
13514                 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
13515                         <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
13516                         <xsl:choose>
13517                                 <!-- 01/04 fix -->
13518                                 <xsl:when test="$controlField008-22='d'">
13519                                         <targetAudience authority="marctarget">adolescent</targetAudience>
13520                                 </xsl:when>
13521                                 <xsl:when test="$controlField008-22='e'">
13522                                         <targetAudience authority="marctarget">adult</targetAudience>
13523                                 </xsl:when>
13524                                 <xsl:when test="$controlField008-22='g'">
13525                                         <targetAudience authority="marctarget">general</targetAudience>
13526                                 </xsl:when>
13527                                 <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
13528                                         <targetAudience authority="marctarget">juvenile</targetAudience>
13529                                 </xsl:when>
13530                                 <xsl:when test="$controlField008-22='a'">
13531                                         <targetAudience authority="marctarget">preschool</targetAudience>
13532                                 </xsl:when>
13533                                 <xsl:when test="$controlField008-22='f'">
13534                                         <targetAudience authority="marctarget">specialized</targetAudience>
13535                                 </xsl:when>
13536                         </xsl:choose>
13537                 </xsl:if>
13538                 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
13539                         <note type="statement of responsibility">
13540                                 <xsl:value-of select="."></xsl:value-of>
13541                         </note>
13542                 </xsl:for-each>
13543                 <xsl:for-each select="marc:datafield[@tag=500]">
13544                         <note>
13545                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13546                                 <xsl:call-template name="uri"></xsl:call-template>
13547                         </note>
13548                 </xsl:for-each>
13549                 
13550                 <!--3.2 change tmee additional note fields-->
13551                 
13552                 <xsl:for-each select="marc:datafield[@tag=506]">
13553                         <note type="restrictions">
13554                                 <xsl:call-template name="uri"></xsl:call-template>
13555                                 <xsl:variable name="str">
13556                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13557                                                 <xsl:value-of select="."></xsl:value-of>
13558                                                 <xsl:text> </xsl:text>
13559                                         </xsl:for-each>
13560                                 </xsl:variable>
13561                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13562                         </note>
13563                 </xsl:for-each>
13564                 
13565                 <xsl:for-each select="marc:datafield[@tag=510]">
13566                         <note  type="citation/reference">
13567                                 <xsl:call-template name="uri"></xsl:call-template>
13568                                 <xsl:variable name="str">
13569                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13570                                                 <xsl:value-of select="."></xsl:value-of>
13571                                                 <xsl:text> </xsl:text>
13572                                         </xsl:for-each>
13573                                 </xsl:variable>
13574                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13575                         </note>
13576                 </xsl:for-each>
13577                 
13578                         
13579                 <xsl:for-each select="marc:datafield[@tag=511]">
13580                         <note type="performers">
13581                                 <xsl:call-template name="uri"></xsl:call-template>
13582                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13583                         </note>
13584                 </xsl:for-each>
13585                 <xsl:for-each select="marc:datafield[@tag=518]">
13586                         <note type="venue">
13587                                 <xsl:call-template name="uri"></xsl:call-template>
13588                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13589                         </note>
13590                 </xsl:for-each>
13591                 
13592                 <xsl:for-each select="marc:datafield[@tag=530]">
13593                         <note  type="additional physical form">
13594                                 <xsl:call-template name="uri"></xsl:call-template>
13595                                 <xsl:variable name="str">
13596                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13597                                                 <xsl:value-of select="."></xsl:value-of>
13598                                                 <xsl:text> </xsl:text>
13599                                         </xsl:for-each>
13600                                 </xsl:variable>
13601                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13602                         </note>
13603                 </xsl:for-each>
13604                 
13605                 <xsl:for-each select="marc:datafield[@tag=533]">
13606                         <note  type="reproduction">
13607                                 <xsl:call-template name="uri"></xsl:call-template>
13608                                 <xsl:variable name="str">
13609                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13610                                                 <xsl:value-of select="."></xsl:value-of>
13611                                                 <xsl:text> </xsl:text>
13612                                         </xsl:for-each>
13613                                 </xsl:variable>
13614                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13615                         </note>
13616                 </xsl:for-each>
13617                 
13618                 <xsl:for-each select="marc:datafield[@tag=534]">
13619                         <note  type="original version">
13620                                 <xsl:call-template name="uri"></xsl:call-template>
13621                                 <xsl:variable name="str">
13622                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13623                                                 <xsl:value-of select="."></xsl:value-of>
13624                                                 <xsl:text> </xsl:text>
13625                                         </xsl:for-each>
13626                                 </xsl:variable>
13627                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13628                         </note>
13629                 </xsl:for-each>
13630                 
13631                 <xsl:for-each select="marc:datafield[@tag=538]">
13632                         <note  type="system details">
13633                                 <xsl:call-template name="uri"></xsl:call-template>
13634                                 <xsl:variable name="str">
13635                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13636                                                 <xsl:value-of select="."></xsl:value-of>
13637                                                 <xsl:text> </xsl:text>
13638                                         </xsl:for-each>
13639                                 </xsl:variable>
13640                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13641                         </note>
13642                 </xsl:for-each>
13643                 
13644                 <xsl:for-each select="marc:datafield[@tag=583]">
13645                         <note type="action">
13646                                 <xsl:call-template name="uri"></xsl:call-template>
13647                                 <xsl:variable name="str">
13648                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13649                                                 <xsl:value-of select="."></xsl:value-of>
13650                                                 <xsl:text> </xsl:text>
13651                                         </xsl:for-each>
13652                                 </xsl:variable>
13653                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13654                         </note>
13655                 </xsl:for-each>
13656                 
13657
13658                 
13659                 
13660                 
13661                 <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or  @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
13662                         <note>
13663                                 <xsl:call-template name="uri"></xsl:call-template>
13664                                 <xsl:variable name="str">
13665                                         <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13666                                                 <xsl:value-of select="."></xsl:value-of>
13667                                                 <xsl:text> </xsl:text>
13668                                         </xsl:for-each>
13669                                 </xsl:variable>
13670                                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13671                         </note>
13672                 </xsl:for-each>
13673                 <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
13674                         <subject>
13675                                 <cartographics>
13676                                         <coordinates>
13677                                                 <xsl:call-template name="subfieldSelect">
13678                                                         <xsl:with-param name="codes">defg</xsl:with-param>
13679                                                 </xsl:call-template>
13680                                         </coordinates>
13681                                 </cartographics>
13682                         </subject>
13683                 </xsl:for-each>
13684                 <xsl:for-each select="marc:datafield[@tag=043]">
13685                         <subject>
13686                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
13687                                         <geographicCode>
13688                                                 <xsl:attribute name="authority">
13689                                                         <xsl:if test="@code='a'">
13690                                                                 <xsl:text>marcgac</xsl:text>
13691                                                         </xsl:if>
13692                                                         <xsl:if test="@code='b'">
13693                                                                 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
13694                                                         </xsl:if>
13695                                                         <xsl:if test="@code='c'">
13696                                                                 <xsl:text>iso3166</xsl:text>
13697                                                         </xsl:if>
13698                                                 </xsl:attribute>
13699                                                 <xsl:value-of select="self::marc:subfield"></xsl:value-of>
13700                                         </geographicCode>
13701                                 </xsl:for-each>
13702                         </subject>
13703                 </xsl:for-each>
13704                 <!-- tmee 2006/11/27 -->
13705                 <xsl:for-each select="marc:datafield[@tag=255]">
13706                         <subject>
13707                                 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
13708                                 <cartographics>
13709                                         <xsl:if test="@code='a'">
13710                                                 <scale>
13711                                                         <xsl:value-of select="."></xsl:value-of>
13712                                                 </scale>
13713                                         </xsl:if>
13714                                         <xsl:if test="@code='b'">
13715                                                 <projection>
13716                                                         <xsl:value-of select="."></xsl:value-of>
13717                                                 </projection>
13718                                         </xsl:if>
13719                                         <xsl:if test="@code='c'">
13720                                                 <coordinates>
13721                                                         <xsl:value-of select="."></xsl:value-of>
13722                                                 </coordinates>
13723                                         </xsl:if>
13724                                 </cartographics>
13725                                 </xsl:for-each>
13726                         </subject>
13727                 </xsl:for-each>
13728                                 
13729                 <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
13730                 <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
13731                 <xsl:for-each select="marc:datafield[@tag=752]">
13732                         <subject>
13733                                 <hierarchicalGeographic>
13734                                         <xsl:for-each select="marc:subfield[@code='a']">
13735                                                 <country>
13736                                                         <xsl:call-template name="chopPunctuation">
13737                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
13738                                                         </xsl:call-template>
13739                                                 </country>
13740                                         </xsl:for-each>
13741                                         <xsl:for-each select="marc:subfield[@code='b']">
13742                                                 <state>
13743                                                         <xsl:call-template name="chopPunctuation">
13744                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
13745                                                         </xsl:call-template>
13746                                                 </state>
13747                                         </xsl:for-each>
13748                                         <xsl:for-each select="marc:subfield[@code='c']">
13749                                                 <county>
13750                                                         <xsl:call-template name="chopPunctuation">
13751                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
13752                                                         </xsl:call-template>
13753                                                 </county>
13754                                         </xsl:for-each>
13755                                         <xsl:for-each select="marc:subfield[@code='d']">
13756                                                 <city>
13757                                                         <xsl:call-template name="chopPunctuation">
13758                                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
13759                                                         </xsl:call-template>
13760                                                 </city>
13761                                         </xsl:for-each>
13762                                 </hierarchicalGeographic>
13763                         </subject>
13764                 </xsl:for-each>
13765                 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
13766                         <subject>
13767                                 <xsl:choose>
13768                                         <xsl:when test="@ind1=2">
13769                                                 <temporal encoding="iso8601" point="start">
13770                                                         <xsl:call-template name="chopPunctuation">
13771                                                                 <xsl:with-param name="chopString">
13772                                                                         <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
13773                                                                 </xsl:with-param>
13774                                                         </xsl:call-template>
13775                                                 </temporal>
13776                                                 <temporal encoding="iso8601" point="end">
13777                                                         <xsl:call-template name="chopPunctuation">
13778                                                                 <xsl:with-param name="chopString">
13779                                                                         <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
13780                                                                 </xsl:with-param>
13781                                                         </xsl:call-template>
13782                                                 </temporal>
13783                                         </xsl:when>
13784                                         <xsl:otherwise>
13785                                                 <xsl:for-each select="marc:subfield[@code='b']">
13786                                                         <temporal encoding="iso8601">
13787                                                                 <xsl:call-template name="chopPunctuation">
13788                                                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
13789                                                                 </xsl:call-template>
13790                                                         </temporal>
13791                                                 </xsl:for-each>
13792                                         </xsl:otherwise>
13793                                 </xsl:choose>
13794                         </subject>
13795                 </xsl:for-each>
13796                 <xsl:for-each select="marc:datafield[@tag=050]">
13797                         <xsl:for-each select="marc:subfield[@code='b']">
13798                                 <classification authority="lcc">
13799                                         <xsl:if test="../marc:subfield[@code='3']">
13800                                                 <xsl:attribute name="displayLabel">
13801                                                         <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
13802                                                 </xsl:attribute>
13803                                         </xsl:if>
13804                                         <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
13805                                         <xsl:text> </xsl:text>
13806                                         <xsl:value-of select="text()"></xsl:value-of>
13807                                 </classification>
13808                         </xsl:for-each>
13809                         <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
13810                                 <classification authority="lcc">
13811                                         <xsl:if test="../marc:subfield[@code='3']">
13812                                                 <xsl:attribute name="displayLabel">
13813                                                         <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
13814                                                 </xsl:attribute>
13815                                         </xsl:if>
13816                                         <xsl:value-of select="text()"></xsl:value-of>
13817                                 </classification>
13818                         </xsl:for-each>
13819                 </xsl:for-each>
13820                 <xsl:for-each select="marc:datafield[@tag=082]">
13821                         <classification authority="ddc">
13822                                 <xsl:if test="marc:subfield[@code='2']">
13823                                         <xsl:attribute name="edition">
13824                                                 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13825                                         </xsl:attribute>
13826                                 </xsl:if>
13827                                 <xsl:call-template name="subfieldSelect">
13828                                         <xsl:with-param name="codes">ab</xsl:with-param>
13829                                 </xsl:call-template>
13830                         </classification>
13831                 </xsl:for-each>
13832                 <xsl:for-each select="marc:datafield[@tag=080]">
13833                         <classification authority="udc">
13834                                 <xsl:call-template name="subfieldSelect">
13835                                         <xsl:with-param name="codes">abx</xsl:with-param>
13836                                 </xsl:call-template>
13837                         </classification>
13838                 </xsl:for-each>
13839                 <xsl:for-each select="marc:datafield[@tag=060]">
13840                         <classification authority="nlm">
13841                                 <xsl:call-template name="subfieldSelect">
13842                                         <xsl:with-param name="codes">ab</xsl:with-param>
13843                                 </xsl:call-template>
13844                         </classification>
13845                 </xsl:for-each>
13846                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
13847                         <classification authority="sudocs">
13848                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13849                         </classification>
13850                 </xsl:for-each>
13851                 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
13852                         <classification authority="candoc">
13853                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13854                         </classification>
13855                 </xsl:for-each>
13856                 <xsl:for-each select="marc:datafield[@tag=086]">
13857                         <classification>
13858                                 <xsl:attribute name="authority">
13859                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13860                                 </xsl:attribute>
13861                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13862                         </classification>
13863                 </xsl:for-each>
13864                 <xsl:for-each select="marc:datafield[@tag=084]">
13865                         <classification>
13866                                 <xsl:attribute name="authority">
13867                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13868                                 </xsl:attribute>
13869                                 <xsl:call-template name="subfieldSelect">
13870                                         <xsl:with-param name="codes">ab</xsl:with-param>
13871                                 </xsl:call-template>
13872                         </classification>
13873                 </xsl:for-each>
13874                 <xsl:for-each select="marc:datafield[@tag=440]">
13875                         <relatedItem type="series">
13876                                 <xsl:variable name="titleChop">
13877                                         <xsl:call-template name="chopPunctuation">
13878                                                 <xsl:with-param name="chopString">
13879                                                         <xsl:call-template name="subfieldSelect">
13880                                                                 <xsl:with-param name="codes">av</xsl:with-param>
13881                                                         </xsl:call-template>
13882                                                 </xsl:with-param>
13883                                         </xsl:call-template>
13884                                 </xsl:variable>
13885                                 <titleInfo>
13886                                         <title>
13887                                                 <xsl:value-of select="$titleChop" />
13888                                         </title>
13889                                         <xsl:call-template name="part"></xsl:call-template>
13890                                 </titleInfo>
13891                                 <titleInfo type="nfi">
13892                                         <xsl:choose>
13893                                                 <xsl:when test="@ind2>0">
13894                                                         <nonSort>
13895                                                                 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
13896                                                         </nonSort>
13897                                                         <title>
13898                                                                 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
13899                                                         </title>
13900                                                         <xsl:call-template name="part"/>
13901                                                 </xsl:when>
13902                                                 <xsl:otherwise>
13903                                                         <title>
13904                                                                 <xsl:value-of select="$titleChop" />
13905                                                         </title>
13906                                                 </xsl:otherwise>
13907                                         </xsl:choose>
13908                                         <xsl:call-template name="part"></xsl:call-template>
13909                                 </titleInfo>
13910                         </relatedItem>
13911                 </xsl:for-each>
13912                 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
13913                         <relatedItem type="series">
13914                                 <titleInfo>
13915                                         <title>
13916                                                 <xsl:call-template name="chopPunctuation">
13917                                                         <xsl:with-param name="chopString">
13918                                                                 <xsl:call-template name="subfieldSelect">
13919                                                                         <xsl:with-param name="codes">av</xsl:with-param>
13920                                                                 </xsl:call-template>
13921                                                         </xsl:with-param>
13922                                                 </xsl:call-template>
13923                                         </title>
13924                                         <xsl:call-template name="part"></xsl:call-template>
13925                                 </titleInfo>
13926                         </relatedItem>
13927                 </xsl:for-each>
13928                 <xsl:for-each select="marc:datafield[@tag=510]">
13929                         <relatedItem type="isReferencedBy">
13930                                 <note>
13931                                         <xsl:call-template name="subfieldSelect">
13932                                                 <xsl:with-param name="codes">abcx3</xsl:with-param>
13933                                         </xsl:call-template>
13934                                 </note>
13935                         </relatedItem>
13936                 </xsl:for-each>
13937                 <xsl:for-each select="marc:datafield[@tag=534]">
13938                         <relatedItem type="original">
13939                                 <xsl:call-template name="relatedTitle"></xsl:call-template>
13940                                 <xsl:call-template name="relatedName"></xsl:call-template>
13941                                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
13942                                         <originInfo>
13943                                                 <xsl:for-each select="marc:subfield[@code='c']">
13944                                                         <publisher>
13945                                                                 <xsl:value-of select="."></xsl:value-of>
13946                                                         </publisher>
13947                                                 </xsl:for-each>
13948                                                 <xsl:for-each select="marc:subfield[@code='b']">
13949                                                         <edition>
13950                                                                 <xsl:value-of select="."></xsl:value-of>
13951                                                         </edition>
13952                                                 </xsl:for-each>
13953                                         </originInfo>
13954                                 </xsl:if>
13955                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
13956                                 <xsl:for-each select="marc:subfield[@code='z']">
13957                                         <identifier type="isbn">
13958                                                 <xsl:value-of select="."></xsl:value-of>
13959                                         </identifier>
13960                                 </xsl:for-each>
13961                                 <xsl:call-template name="relatedNote"></xsl:call-template>
13962                         </relatedItem>
13963                 </xsl:for-each>
13964                 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
13965                         <relatedItem>
13966                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
13967                                 <titleInfo>
13968                                         <title>
13969                                                 <xsl:call-template name="chopPunctuation">
13970                                                         <xsl:with-param name="chopString">
13971                                                                 <xsl:call-template name="specialSubfieldSelect">
13972                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
13973                                                                         <xsl:with-param name="axis">t</xsl:with-param>
13974                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
13975                                                                 </xsl:call-template>
13976                                                         </xsl:with-param>
13977                                                 </xsl:call-template>
13978                                         </title>
13979                                         <xsl:call-template name="part"></xsl:call-template>
13980                                 </titleInfo>
13981                                 <name type="personal">
13982                                         <namePart>
13983                                                 <xsl:call-template name="specialSubfieldSelect">
13984                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
13985                                                         <xsl:with-param name="axis">t</xsl:with-param>
13986                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
13987                                                 </xsl:call-template>
13988                                         </namePart>
13989                                         <xsl:call-template name="termsOfAddress"></xsl:call-template>
13990                                         <xsl:call-template name="nameDate"></xsl:call-template>
13991                                         <xsl:call-template name="role"></xsl:call-template>
13992                                 </name>
13993                                 <xsl:call-template name="relatedForm"></xsl:call-template>
13994                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
13995                         </relatedItem>
13996                 </xsl:for-each>
13997                 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
13998                         <relatedItem>
13999                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14000                                 <titleInfo>
14001                                         <title>
14002                                                 <xsl:call-template name="chopPunctuation">
14003                                                         <xsl:with-param name="chopString">
14004                                                                 <xsl:call-template name="specialSubfieldSelect">
14005                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
14006                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14007                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
14008                                                                 </xsl:call-template>
14009                                                         </xsl:with-param>
14010                                                 </xsl:call-template>
14011                                         </title>
14012                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14013                                 </titleInfo>
14014                                 <name type="corporate">
14015                                         <xsl:for-each select="marc:subfield[@code='a']">
14016                                                 <namePart>
14017                                                         <xsl:value-of select="."></xsl:value-of>
14018                                                 </namePart>
14019                                         </xsl:for-each>
14020                                         <xsl:for-each select="marc:subfield[@code='b']">
14021                                                 <namePart>
14022                                                         <xsl:value-of select="."></xsl:value-of>
14023                                                 </namePart>
14024                                         </xsl:for-each>
14025                                         <xsl:variable name="tempNamePart">
14026                                                 <xsl:call-template name="specialSubfieldSelect">
14027                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
14028                                                         <xsl:with-param name="axis">t</xsl:with-param>
14029                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
14030                                                 </xsl:call-template>
14031                                         </xsl:variable>
14032                                         <xsl:if test="normalize-space($tempNamePart)">
14033                                                 <namePart>
14034                                                         <xsl:value-of select="$tempNamePart"></xsl:value-of>
14035                                                 </namePart>
14036                                         </xsl:if>
14037                                         <xsl:call-template name="role"></xsl:call-template>
14038                                 </name>
14039                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14040                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14041                         </relatedItem>
14042                 </xsl:for-each>
14043                 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
14044                         <relatedItem>
14045                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14046                                 <titleInfo>
14047                                         <title>
14048                                                 <xsl:call-template name="chopPunctuation">
14049                                                         <xsl:with-param name="chopString">
14050                                                                 <xsl:call-template name="specialSubfieldSelect">
14051                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
14052                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14053                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
14054                                                                 </xsl:call-template>
14055                                                         </xsl:with-param>
14056                                                 </xsl:call-template>
14057                                         </title>
14058                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14059                                 </titleInfo>
14060                                 <name type="conference">
14061                                         <namePart>
14062                                                 <xsl:call-template name="specialSubfieldSelect">
14063                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
14064                                                         <xsl:with-param name="axis">t</xsl:with-param>
14065                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
14066                                                 </xsl:call-template>
14067                                         </namePart>
14068                                 </name>
14069                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14070                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14071                         </relatedItem>
14072                 </xsl:for-each>
14073                 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
14074                         <relatedItem>
14075                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14076                                 <titleInfo>
14077                                         <title>
14078                                                 <xsl:call-template name="chopPunctuation">
14079                                                         <xsl:with-param name="chopString">
14080                                                                 <xsl:call-template name="subfieldSelect">
14081                                                                         <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
14082                                                                 </xsl:call-template>
14083                                                         </xsl:with-param>
14084                                                 </xsl:call-template>
14085                                         </title>
14086                                         <xsl:call-template name="part"></xsl:call-template>
14087                                 </titleInfo>
14088                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14089                                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14090                         </relatedItem>
14091                 </xsl:for-each>
14092                 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
14093                         <relatedItem>
14094                                 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14095                                 <xsl:variable name="titleChop">
14096                                         <xsl:call-template name="chopPunctuation">
14097                                                 <xsl:with-param name="chopString">
14098                                                         <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
14099                                                 </xsl:with-param>
14100                                         </xsl:call-template>
14101                                 </xsl:variable>
14102                                 <titleInfo>
14103                                         <title>
14104                                                 <xsl:value-of select="$titleChop" />
14105                                         </title>
14106                                         <xsl:call-template name="part"></xsl:call-template>
14107                                 </titleInfo>
14108                                 <titleInfo type="nfi">
14109                                         <xsl:choose>
14110                                                 <xsl:when test="@ind1>0">
14111                                                         <nonSort>
14112                                                                 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
14113                                                         </nonSort>
14114                                                         <title>
14115                                                                 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
14116                                                         </title>
14117                                                 </xsl:when>
14118                                                 <xsl:otherwise>
14119                                                         <title>
14120                                                                 <xsl:value-of select="$titleChop" />
14121                                                         </title>
14122                                                 </xsl:otherwise>
14123                                         </xsl:choose>
14124                                         <xsl:call-template name="part"></xsl:call-template>
14125                                 </titleInfo>
14126                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14127                         </relatedItem>
14128                 </xsl:for-each>
14129                 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
14130                         <relatedItem type="series">
14131                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14132                         </relatedItem>
14133                 </xsl:for-each>
14134                 <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
14135                         <relatedItem>
14136                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14137                         </relatedItem>
14138                 </xsl:for-each>
14139                 <xsl:for-each select="marc:datafield[@tag=775]">
14140                         <relatedItem type="otherVersion">
14141                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14142                         </relatedItem>
14143                 </xsl:for-each>
14144                 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
14145                         <relatedItem type="constituent">
14146                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14147                         </relatedItem>
14148                 </xsl:for-each>
14149                 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
14150                         <relatedItem type="host">
14151                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14152                         </relatedItem>
14153                 </xsl:for-each>
14154                 <xsl:for-each select="marc:datafield[@tag=776]">
14155                         <relatedItem type="otherFormat">
14156                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14157                         </relatedItem>
14158                 </xsl:for-each>
14159                 <xsl:for-each select="marc:datafield[@tag=780]">
14160                         <relatedItem type="preceding">
14161                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14162                         </relatedItem>
14163                 </xsl:for-each>
14164                 <xsl:for-each select="marc:datafield[@tag=785]">
14165                         <relatedItem type="succeeding">
14166                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14167                         </relatedItem>
14168                 </xsl:for-each>
14169                 <xsl:for-each select="marc:datafield[@tag=786]">
14170                         <relatedItem type="original">
14171                                 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14172                         </relatedItem>
14173                 </xsl:for-each>
14174                 <xsl:for-each select="marc:datafield[@tag=800]">
14175                         <relatedItem type="series">
14176                                 <titleInfo>
14177                                         <title>
14178                                                 <xsl:call-template name="chopPunctuation">
14179                                                         <xsl:with-param name="chopString">
14180                                                                 <xsl:call-template name="specialSubfieldSelect">
14181                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
14182                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14183                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
14184                                                                 </xsl:call-template>
14185                                                         </xsl:with-param>
14186                                                 </xsl:call-template>
14187                                         </title>
14188                                         <xsl:call-template name="part"></xsl:call-template>
14189                                 </titleInfo>
14190                                 <name type="personal">
14191                                         <namePart>
14192                                                 <xsl:call-template name="chopPunctuation">
14193                                                         <xsl:with-param name="chopString">
14194                                                                 <xsl:call-template name="specialSubfieldSelect">
14195                                                                         <xsl:with-param name="anyCodes">aq</xsl:with-param>
14196                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14197                                                                         <xsl:with-param name="beforeCodes">g</xsl:with-param>
14198                                                                 </xsl:call-template>
14199                                                         </xsl:with-param>
14200                                                 </xsl:call-template>
14201                                         </namePart>
14202                                         <xsl:call-template name="termsOfAddress"></xsl:call-template>
14203                                         <xsl:call-template name="nameDate"></xsl:call-template>
14204                                         <xsl:call-template name="role"></xsl:call-template>
14205                                 </name>
14206                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14207                         </relatedItem>
14208                 </xsl:for-each>
14209                 <xsl:for-each select="marc:datafield[@tag=810]">
14210                         <relatedItem type="series">
14211                                 <titleInfo>
14212                                         <title>
14213                                                 <xsl:call-template name="chopPunctuation">
14214                                                         <xsl:with-param name="chopString">
14215                                                                 <xsl:call-template name="specialSubfieldSelect">
14216                                                                         <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
14217                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14218                                                                         <xsl:with-param name="afterCodes">dg</xsl:with-param>
14219                                                                 </xsl:call-template>
14220                                                         </xsl:with-param>
14221                                                 </xsl:call-template>
14222                                         </title>
14223                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14224                                 </titleInfo>
14225                                 <name type="corporate">
14226                                         <xsl:for-each select="marc:subfield[@code='a']">
14227                                                 <namePart>
14228                                                         <xsl:value-of select="."></xsl:value-of>
14229                                                 </namePart>
14230                                         </xsl:for-each>
14231                                         <xsl:for-each select="marc:subfield[@code='b']">
14232                                                 <namePart>
14233                                                         <xsl:value-of select="."></xsl:value-of>
14234                                                 </namePart>
14235                                         </xsl:for-each>
14236                                         <namePart>
14237                                                 <xsl:call-template name="specialSubfieldSelect">
14238                                                         <xsl:with-param name="anyCodes">c</xsl:with-param>
14239                                                         <xsl:with-param name="axis">t</xsl:with-param>
14240                                                         <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
14241                                                 </xsl:call-template>
14242                                         </namePart>
14243                                         <xsl:call-template name="role"></xsl:call-template>
14244                                 </name>
14245                                 <xsl:call-template name="relatedForm"></xsl:call-template>
14246                         </relatedItem>
14247                 </xsl:for-each>
14248                 <xsl:for-each select="marc:datafield[@tag=811]">
14249                         <relatedItem type="series">
14250                                 <titleInfo>
14251                                         <title>
14252                                                 <xsl:call-template name="chopPunctuation">
14253                                                         <xsl:with-param name="chopString">
14254                                                                 <xsl:call-template name="specialSubfieldSelect">
14255                                                                         <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
14256                                                                         <xsl:with-param name="axis">t</xsl:with-param>
14257                                                                         <xsl:with-param name="afterCodes">g</xsl:with-param>
14258                                                                 </xsl:call-template>
14259                                                         </xsl:with-param>
14260                                                 </xsl:call-template>
14261                                         </title>
14262                                         <xsl:call-template name="relatedPartNumName"/>
14263                                 </titleInfo>
14264                                 <name type="conference">
14265                                         <namePart>
14266                                                 <xsl:call-template name="specialSubfieldSelect">
14267                                                         <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
14268                                                         <xsl:with-param name="axis">t</xsl:with-param>
14269                                                         <xsl:with-param name="beforeCodes">gn</xsl:with-param>
14270                                                 </xsl:call-template>
14271                                         </namePart>
14272                                         <xsl:call-template name="role"/>
14273                                 </name>
14274                                 <xsl:call-template name="relatedForm"/>
14275                         </relatedItem>
14276                 </xsl:for-each>
14277                 <xsl:for-each select="marc:datafield[@tag='830']">
14278                         <relatedItem type="series">
14279                                 <xsl:variable name="titleChop">
14280                                         <xsl:call-template name="chopPunctuation">
14281                                                 <xsl:with-param name="chopString">
14282                                                         <xsl:call-template name="subfieldSelect">
14283                                                                 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
14284                                                         </xsl:call-template>
14285                                                 </xsl:with-param>
14286                                         </xsl:call-template>
14287                                 </xsl:variable>
14288                                 <titleInfo>
14289                                         <title>
14290                                                 <xsl:value-of select="$titleChop" />
14291                                         </title>
14292                                         <xsl:call-template name="part"/>
14293                                 </titleInfo>
14294                                 <titleInfo type="nfi">
14295                                         <xsl:choose>
14296                                                 <xsl:when test="@ind2>0">
14297                                                         <nonSort>
14298                                                                 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
14299                                                         </nonSort>
14300                                                         <title>
14301                                                                 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
14302                                                         </title>
14303                                                 </xsl:when>
14304                                                 <xsl:otherwise>
14305                                                         <title>
14306                                                                 <xsl:value-of select="$titleChop" />
14307                                                         </title>
14308                                                 </xsl:otherwise>
14309                                         </xsl:choose>
14310                                         <xsl:call-template name="part"/>
14311                                 </titleInfo>
14312                                 <xsl:call-template name="relatedForm"/>
14313                         </relatedItem>
14314                 </xsl:for-each>
14315                 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
14316                         <relatedItem>
14317                                 <internetMediaType>
14318                                         <xsl:value-of select="."/>
14319                                 </internetMediaType>
14320                         </relatedItem>
14321                 </xsl:for-each>
14322                 <xsl:for-each select="marc:datafield[@tag='020']">
14323                         <xsl:call-template name="isInvalid">
14324                                 <xsl:with-param name="type">isbn</xsl:with-param>
14325                         </xsl:call-template>
14326                         <xsl:if test="marc:subfield[@code='a']">
14327                                 <identifier type="isbn">
14328                                         <xsl:value-of select="marc:subfield[@code='a']"/>
14329                                 </identifier>
14330                         </xsl:if>
14331                 </xsl:for-each>
14332                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
14333                         <xsl:call-template name="isInvalid">
14334                                 <xsl:with-param name="type">isrc</xsl:with-param>
14335                         </xsl:call-template>
14336                         <xsl:if test="marc:subfield[@code='a']">
14337                                 <identifier type="isrc">
14338                                         <xsl:value-of select="marc:subfield[@code='a']"/>
14339                                 </identifier>
14340                         </xsl:if>
14341                 </xsl:for-each>
14342                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
14343                         <xsl:call-template name="isInvalid">
14344                                 <xsl:with-param name="type">ismn</xsl:with-param>
14345                         </xsl:call-template>
14346                         <xsl:if test="marc:subfield[@code='a']">
14347                                 <identifier type="ismn">
14348                                         <xsl:value-of select="marc:subfield[@code='a']"/>
14349                                 </identifier>
14350                         </xsl:if>
14351                 </xsl:for-each>
14352                 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
14353                         <xsl:call-template name="isInvalid">
14354                                 <xsl:with-param name="type">sici</xsl:with-param>
14355                         </xsl:call-template>
14356                         <identifier type="sici">
14357                                 <xsl:call-template name="subfieldSelect">
14358                                         <xsl:with-param name="codes">ab</xsl:with-param>
14359                                 </xsl:call-template>
14360                         </identifier>
14361                 </xsl:for-each>
14362                 <xsl:for-each select="marc:datafield[@tag='022']">
14363                         <xsl:call-template name="isInvalid">
14364                                 <xsl:with-param name="type">issn</xsl:with-param>
14365                         </xsl:call-template>
14366                         <identifier type="issn">
14367                                 <xsl:value-of select="marc:subfield[@code='a']"/>
14368                         </identifier>
14369                 </xsl:for-each>
14370                 <xsl:for-each select="marc:datafield[@tag='010']">
14371                         <xsl:call-template name="isInvalid">
14372                                 <xsl:with-param name="type">lccn</xsl:with-param>
14373                         </xsl:call-template>
14374                         <identifier type="lccn">
14375                                 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
14376                         </identifier>
14377                 </xsl:for-each>
14378                 <xsl:for-each select="marc:datafield[@tag='028']">
14379                         <identifier>
14380                                 <xsl:attribute name="type">
14381                                         <xsl:choose>
14382                                                 <xsl:when test="@ind1='0'">issue number</xsl:when>
14383                                                 <xsl:when test="@ind1='1'">matrix number</xsl:when>
14384                                                 <xsl:when test="@ind1='2'">music plate</xsl:when>
14385                                                 <xsl:when test="@ind1='3'">music publisher</xsl:when>
14386                                                 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
14387                                         </xsl:choose>
14388                                 </xsl:attribute>
14389                                 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
14390                                 <xsl:call-template name="subfieldSelect">
14391                                         <xsl:with-param name="codes">
14392                                                 <xsl:choose>
14393                                                         <xsl:when test="@ind1='0'">ba</xsl:when>
14394                                                         <xsl:otherwise>ab</xsl:otherwise>
14395                                                 </xsl:choose>
14396                                         </xsl:with-param>
14397                                 </xsl:call-template>
14398                         </identifier>
14399                 </xsl:for-each>
14400                 <xsl:for-each select="marc:datafield[@tag='037']">
14401                         <identifier type="stock number">
14402                                 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
14403                                 <xsl:call-template name="subfieldSelect">
14404                                         <xsl:with-param name="codes">ab</xsl:with-param>
14405                                 </xsl:call-template>
14406                         </identifier>
14407                 </xsl:for-each>
14408                 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
14409                         <identifier>
14410                                 <xsl:attribute name="type">
14411                                         <xsl:choose>
14412                                                 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
14413                                                 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
14414                                                 <xsl:otherwise>uri</xsl:otherwise>
14415                                         </xsl:choose>
14416                                 </xsl:attribute>
14417                                 <xsl:choose>
14418                                         <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
14419                                                 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
14420                                         </xsl:when>
14421                                         <xsl:otherwise>
14422                                                 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
14423                                         </xsl:otherwise>
14424                                 </xsl:choose>
14425                         </identifier>
14426                         <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
14427                                 <identifier type="hdl">
14428                                         <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
14429                                                 <xsl:attribute name="displayLabel">
14430                                                         <xsl:call-template name="subfieldSelect">
14431                                                                 <xsl:with-param name="codes">y3z</xsl:with-param>
14432                                                         </xsl:call-template>
14433                                                 </xsl:attribute>
14434                                         </xsl:if>
14435                                         <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
14436                                 </identifier>
14437                         </xsl:if>
14438                 </xsl:for-each>
14439                 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
14440                         <identifier type="upc">
14441                                 <xsl:call-template name="isInvalid"/>
14442                                 <xsl:value-of select="marc:subfield[@code='a']"/>
14443                         </identifier>
14444                 </xsl:for-each>
14445                 <!-- 1/04 fix added $y -->
14446                 <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
14447                         <location>
14448                                 <url>
14449                                         <xsl:if test="marc:subfield[@code='y' or @code='3']">
14450                                                 <xsl:attribute name="displayLabel">
14451                                                         <xsl:call-template name="subfieldSelect">
14452                                                                 <xsl:with-param name="codes">y3</xsl:with-param>
14453                                                         </xsl:call-template>
14454                                                 </xsl:attribute>
14455                                         </xsl:if>
14456                                         <xsl:if test="marc:subfield[@code='z' ]">
14457                                                 <xsl:attribute name="note">
14458                                                         <xsl:call-template name="subfieldSelect">
14459                                                                 <xsl:with-param name="codes">z</xsl:with-param>
14460                                                         </xsl:call-template>
14461                                                 </xsl:attribute>
14462                                         </xsl:if>
14463                                         <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
14464
14465                                 </url>
14466                         </location>
14467                 </xsl:for-each>
14468                         
14469                         <!-- 3.2 change tmee 856z  -->
14470
14471                 
14472                 <xsl:for-each select="marc:datafield[@tag=852]">
14473                         <location>
14474                                 <physicalLocation>
14475                                         <xsl:call-template name="displayLabel"></xsl:call-template>
14476                                         <xsl:call-template name="subfieldSelect">
14477                                                 <xsl:with-param name="codes">abje</xsl:with-param>
14478                                         </xsl:call-template>
14479                                 </physicalLocation>
14480                         </location>
14481                 </xsl:for-each>
14482                 <xsl:for-each select="marc:datafield[@tag=506]">
14483                         <accessCondition type="restrictionOnAccess">
14484                                 <xsl:call-template name="subfieldSelect">
14485                                         <xsl:with-param name="codes">abcd35</xsl:with-param>
14486                                 </xsl:call-template>
14487                         </accessCondition>
14488                 </xsl:for-each>
14489                 <xsl:for-each select="marc:datafield[@tag=540]">
14490                         <accessCondition type="useAndReproduction">
14491                                 <xsl:call-template name="subfieldSelect">
14492                                         <xsl:with-param name="codes">abcde35</xsl:with-param>
14493                                 </xsl:call-template>
14494                         </accessCondition>
14495                 </xsl:for-each>
14496                 <recordInfo>
14497                         <xsl:for-each select="marc:datafield[@tag=040]">
14498                                 <recordContentSource authority="marcorg">
14499                                         <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
14500                                 </recordContentSource>
14501                         </xsl:for-each>
14502                         <xsl:for-each select="marc:controlfield[@tag=008]">
14503                                 <recordCreationDate encoding="marc">
14504                                         <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
14505                                 </recordCreationDate>
14506                         </xsl:for-each>
14507                         <xsl:for-each select="marc:controlfield[@tag=005]">
14508                                 <recordChangeDate encoding="iso8601">
14509                                         <xsl:value-of select="."></xsl:value-of>
14510                                 </recordChangeDate>
14511                         </xsl:for-each>
14512                         <xsl:for-each select="marc:controlfield[@tag=001]">
14513                                 <recordIdentifier>
14514                                         <xsl:if test="../marc:controlfield[@tag=003]">
14515                                                 <xsl:attribute name="source">
14516                                                         <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
14517                                                 </xsl:attribute>
14518                                         </xsl:if>
14519                                         <xsl:value-of select="."></xsl:value-of>
14520                                 </recordIdentifier>
14521                         </xsl:for-each>
14522                         <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
14523                                 <languageOfCataloging>
14524                                         <languageTerm authority="iso639-2b" type="code">
14525                                                 <xsl:value-of select="."></xsl:value-of>
14526                                         </languageTerm>
14527                                 </languageOfCataloging>
14528                         </xsl:for-each>
14529                 </recordInfo>
14530         </xsl:template>
14531         <xsl:template name="displayForm">
14532                 <xsl:for-each select="marc:subfield[@code='c']">
14533                         <displayForm>
14534                                 <xsl:value-of select="."></xsl:value-of>
14535                         </displayForm>
14536                 </xsl:for-each>
14537         </xsl:template>
14538         <xsl:template name="affiliation">
14539                 <xsl:for-each select="marc:subfield[@code='u']">
14540                         <affiliation>
14541                                 <xsl:value-of select="."></xsl:value-of>
14542                         </affiliation>
14543                 </xsl:for-each>
14544         </xsl:template>
14545         <xsl:template name="uri">
14546                 <xsl:for-each select="marc:subfield[@code='u']">
14547                         <xsl:attribute name="xlink:href">
14548                                 <xsl:value-of select="."></xsl:value-of>
14549                         </xsl:attribute>
14550                 </xsl:for-each>
14551                 <xsl:for-each select="marc:subfield[@code='0']">
14552                         <xsl:choose>
14553                                 <xsl:when test="contains(text(), ')')">
14554                                         <xsl:attribute name="xlink:href">
14555                                                 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
14556                                         </xsl:attribute>
14557                                 </xsl:when>
14558                                 <xsl:otherwise>
14559                                         <xsl:attribute name="xlink:href">
14560                                                 <xsl:value-of select="."></xsl:value-of>
14561                                         </xsl:attribute>
14562                                 </xsl:otherwise>
14563                         </xsl:choose>
14564                 </xsl:for-each>
14565         </xsl:template>
14566         <xsl:template name="role">
14567                 <xsl:for-each select="marc:subfield[@code='e']">
14568                         <role>
14569                                 <roleTerm type="text">
14570                                         <xsl:value-of select="."></xsl:value-of>
14571                                 </roleTerm>
14572                         </role>
14573                 </xsl:for-each>
14574                 <xsl:for-each select="marc:subfield[@code='4']">
14575                         <role>
14576                                 <roleTerm authority="marcrelator" type="code">
14577                                         <xsl:value-of select="."></xsl:value-of>
14578                                 </roleTerm>
14579                         </role>
14580                 </xsl:for-each>
14581         </xsl:template>
14582         <xsl:template name="part">
14583                 <xsl:variable name="partNumber">
14584                         <xsl:call-template name="specialSubfieldSelect">
14585                                 <xsl:with-param name="axis">n</xsl:with-param>
14586                                 <xsl:with-param name="anyCodes">n</xsl:with-param>
14587                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14588                         </xsl:call-template>
14589                 </xsl:variable>
14590                 <xsl:variable name="partName">
14591                         <xsl:call-template name="specialSubfieldSelect">
14592                                 <xsl:with-param name="axis">p</xsl:with-param>
14593                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
14594                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14595                         </xsl:call-template>
14596                 </xsl:variable>
14597                 <xsl:if test="string-length(normalize-space($partNumber))">
14598                         <partNumber>
14599                                 <xsl:call-template name="chopPunctuation">
14600                                         <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
14601                                 </xsl:call-template>
14602                         </partNumber>
14603                 </xsl:if>
14604                 <xsl:if test="string-length(normalize-space($partName))">
14605                         <partName>
14606                                 <xsl:call-template name="chopPunctuation">
14607                                         <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
14608                                 </xsl:call-template>
14609                         </partName>
14610                 </xsl:if>
14611         </xsl:template>
14612         <xsl:template name="relatedPart">
14613                 <xsl:if test="@tag=773">
14614                         <xsl:for-each select="marc:subfield[@code='g']">
14615                                 <part>
14616                                         <text>
14617                                                 <xsl:value-of select="."></xsl:value-of>
14618                                         </text>
14619                                 </part>
14620                         </xsl:for-each>
14621                         <xsl:for-each select="marc:subfield[@code='q']">
14622                                 <part>
14623                                         <xsl:call-template name="parsePart"></xsl:call-template>
14624                                 </part>
14625                         </xsl:for-each>
14626                 </xsl:if>
14627         </xsl:template>
14628         <xsl:template name="relatedPartNumName">
14629                 <xsl:variable name="partNumber">
14630                         <xsl:call-template name="specialSubfieldSelect">
14631                                 <xsl:with-param name="axis">g</xsl:with-param>
14632                                 <xsl:with-param name="anyCodes">g</xsl:with-param>
14633                                 <xsl:with-param name="afterCodes">pst</xsl:with-param>
14634                         </xsl:call-template>
14635                 </xsl:variable>
14636                 <xsl:variable name="partName">
14637                         <xsl:call-template name="specialSubfieldSelect">
14638                                 <xsl:with-param name="axis">p</xsl:with-param>
14639                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
14640                                 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14641                         </xsl:call-template>
14642                 </xsl:variable>
14643                 <xsl:if test="string-length(normalize-space($partNumber))">
14644                         <partNumber>
14645                                 <xsl:value-of select="$partNumber"></xsl:value-of>
14646                         </partNumber>
14647                 </xsl:if>
14648                 <xsl:if test="string-length(normalize-space($partName))">
14649                         <partName>
14650                                 <xsl:value-of select="$partName"></xsl:value-of>
14651                         </partName>
14652                 </xsl:if>
14653         </xsl:template>
14654         <xsl:template name="relatedName">
14655                 <xsl:for-each select="marc:subfield[@code='a']">
14656                         <name>
14657                                 <namePart>
14658                                         <xsl:value-of select="."></xsl:value-of>
14659                                 </namePart>
14660                         </name>
14661                 </xsl:for-each>
14662         </xsl:template>
14663         <xsl:template name="relatedForm">
14664                 <xsl:for-each select="marc:subfield[@code='h']">
14665                         <physicalDescription>
14666                                 <form>
14667                                         <xsl:value-of select="."></xsl:value-of>
14668                                 </form>
14669                         </physicalDescription>
14670                 </xsl:for-each>
14671         </xsl:template>
14672         <xsl:template name="relatedExtent">
14673                 <xsl:for-each select="marc:subfield[@code='h']">
14674                         <physicalDescription>
14675                                 <extent>
14676                                         <xsl:value-of select="."></xsl:value-of>
14677                                 </extent>
14678                         </physicalDescription>
14679                 </xsl:for-each>
14680         </xsl:template>
14681         <xsl:template name="relatedNote">
14682                 <xsl:for-each select="marc:subfield[@code='n']">
14683                         <note>
14684                                 <xsl:value-of select="."></xsl:value-of>
14685                         </note>
14686                 </xsl:for-each>
14687         </xsl:template>
14688         <xsl:template name="relatedSubject">
14689                 <xsl:for-each select="marc:subfield[@code='j']">
14690                         <subject>
14691                                 <temporal encoding="iso8601">
14692                                         <xsl:call-template name="chopPunctuation">
14693                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
14694                                         </xsl:call-template>
14695                                 </temporal>
14696                         </subject>
14697                 </xsl:for-each>
14698         </xsl:template>
14699         <xsl:template name="relatedIdentifierISSN">
14700                 <xsl:for-each select="marc:subfield[@code='x']">
14701                         <identifier type="issn">
14702                                 <xsl:value-of select="."></xsl:value-of>
14703                         </identifier>
14704                 </xsl:for-each>
14705         </xsl:template>
14706         <xsl:template name="relatedIdentifierLocal">
14707                 <xsl:for-each select="marc:subfield[@code='w']">
14708                         <identifier type="local">
14709                                 <xsl:value-of select="."></xsl:value-of>
14710                         </identifier>
14711                 </xsl:for-each>
14712         </xsl:template>
14713         <xsl:template name="relatedIdentifier">
14714                 <xsl:for-each select="marc:subfield[@code='o']">
14715                         <identifier>
14716                                 <xsl:value-of select="."></xsl:value-of>
14717                         </identifier>
14718                 </xsl:for-each>
14719         </xsl:template>
14720         <xsl:template name="relatedItem76X-78X">
14721                 <xsl:call-template name="displayLabel"></xsl:call-template>
14722                 <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
14723                 <xsl:call-template name="relatedName"></xsl:call-template>
14724                 <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
14725                 <xsl:call-template name="relatedLanguage"></xsl:call-template>
14726                 <xsl:call-template name="relatedExtent"></xsl:call-template>
14727                 <xsl:call-template name="relatedNote"></xsl:call-template>
14728                 <xsl:call-template name="relatedSubject"></xsl:call-template>
14729                 <xsl:call-template name="relatedIdentifier"></xsl:call-template>
14730                 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14731                 <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
14732                 <xsl:call-template name="relatedPart"></xsl:call-template>
14733         </xsl:template>
14734         <xsl:template name="subjectGeographicZ">
14735                 <geographic>
14736                         <xsl:call-template name="chopPunctuation">
14737                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
14738                         </xsl:call-template>
14739                 </geographic>
14740         </xsl:template>
14741         <xsl:template name="subjectTemporalY">
14742                 <temporal>
14743                         <xsl:call-template name="chopPunctuation">
14744                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
14745                         </xsl:call-template>
14746                 </temporal>
14747         </xsl:template>
14748         <xsl:template name="subjectTopic">
14749                 <topic>
14750                         <xsl:call-template name="chopPunctuation">
14751                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
14752                         </xsl:call-template>
14753                 </topic>
14754         </xsl:template> 
14755         <!-- 3.2 change tmee 6xx $v genre -->
14756         <xsl:template name="subjectGenre">
14757                 <genre>
14758                         <xsl:call-template name="chopPunctuation">
14759                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
14760                         </xsl:call-template>
14761                 </genre>
14762         </xsl:template>
14763         
14764         <xsl:template name="nameABCDN">
14765                 <xsl:for-each select="marc:subfield[@code='a']">
14766                         <namePart>
14767                                 <xsl:call-template name="chopPunctuation">
14768                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
14769                                 </xsl:call-template>
14770                         </namePart>
14771                 </xsl:for-each>
14772                 <xsl:for-each select="marc:subfield[@code='b']">
14773                         <namePart>
14774                                 <xsl:value-of select="."></xsl:value-of>
14775                         </namePart>
14776                 </xsl:for-each>
14777                 <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
14778                         <namePart>
14779                                 <xsl:call-template name="subfieldSelect">
14780                                         <xsl:with-param name="codes">cdn</xsl:with-param>
14781                                 </xsl:call-template>
14782                         </namePart>
14783                 </xsl:if>
14784         </xsl:template>
14785         <xsl:template name="nameABCDQ">
14786                 <namePart>
14787                         <xsl:call-template name="chopPunctuation">
14788                                 <xsl:with-param name="chopString">
14789                                         <xsl:call-template name="subfieldSelect">
14790                                                 <xsl:with-param name="codes">aq</xsl:with-param>
14791                                         </xsl:call-template>
14792                                 </xsl:with-param>
14793                                 <xsl:with-param name="punctuation">
14794                                         <xsl:text>:,;/ </xsl:text>
14795                                 </xsl:with-param>
14796                         </xsl:call-template>
14797                 </namePart>
14798                 <xsl:call-template name="termsOfAddress"></xsl:call-template>
14799                 <xsl:call-template name="nameDate"></xsl:call-template>
14800         </xsl:template>
14801         <xsl:template name="nameACDEQ">
14802                 <namePart>
14803                         <xsl:call-template name="subfieldSelect">
14804                                 <xsl:with-param name="codes">acdeq</xsl:with-param>
14805                         </xsl:call-template>
14806                 </namePart>
14807         </xsl:template>
14808         <xsl:template name="constituentOrRelatedType">
14809                 <xsl:if test="@ind2=2">
14810                         <xsl:attribute name="type">constituent</xsl:attribute>
14811                 </xsl:if>
14812         </xsl:template>
14813         <xsl:template name="relatedTitle">
14814                 <xsl:for-each select="marc:subfield[@code='t']">
14815                         <titleInfo>
14816                                 <title>
14817                                         <xsl:call-template name="chopPunctuation">
14818                                                 <xsl:with-param name="chopString">
14819                                                         <xsl:value-of select="."></xsl:value-of>
14820                                                 </xsl:with-param>
14821                                         </xsl:call-template>
14822                                 </title>
14823                         </titleInfo>
14824                 </xsl:for-each>
14825         </xsl:template>
14826         <xsl:template name="relatedTitle76X-78X">
14827                 <xsl:for-each select="marc:subfield[@code='t']">
14828                         <titleInfo>
14829                                 <title>
14830                                         <xsl:call-template name="chopPunctuation">
14831                                                 <xsl:with-param name="chopString">
14832                                                         <xsl:value-of select="."></xsl:value-of>
14833                                                 </xsl:with-param>
14834                                         </xsl:call-template>
14835                                 </title>
14836                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14837                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14838                                 </xsl:if>
14839                         </titleInfo>
14840                 </xsl:for-each>
14841                 <xsl:for-each select="marc:subfield[@code='p']">
14842                         <titleInfo type="abbreviated">
14843                                 <title>
14844                                         <xsl:call-template name="chopPunctuation">
14845                                                 <xsl:with-param name="chopString">
14846                                                         <xsl:value-of select="."></xsl:value-of>
14847                                                 </xsl:with-param>
14848                                         </xsl:call-template>
14849                                 </title>
14850                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14851                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14852                                 </xsl:if>
14853                         </titleInfo>
14854                 </xsl:for-each>
14855                 <xsl:for-each select="marc:subfield[@code='s']">
14856                         <titleInfo type="uniform">
14857                                 <title>
14858                                         <xsl:call-template name="chopPunctuation">
14859                                                 <xsl:with-param name="chopString">
14860                                                         <xsl:value-of select="."></xsl:value-of>
14861                                                 </xsl:with-param>
14862                                         </xsl:call-template>
14863                                 </title>
14864                                 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14865                                         <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14866                                 </xsl:if>
14867                         </titleInfo>
14868                 </xsl:for-each>
14869         </xsl:template>
14870         <xsl:template name="relatedOriginInfo">
14871                 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
14872                         <originInfo>
14873                                 <xsl:if test="@tag=775">
14874                                         <xsl:for-each select="marc:subfield[@code='f']">
14875                                                 <place>
14876                                                         <placeTerm>
14877                                                                 <xsl:attribute name="type">code</xsl:attribute>
14878                                                                 <xsl:attribute name="authority">marcgac</xsl:attribute>
14879                                                                 <xsl:value-of select="."></xsl:value-of>
14880                                                         </placeTerm>
14881                                                 </place>
14882                                         </xsl:for-each>
14883                                 </xsl:if>
14884                                 <xsl:for-each select="marc:subfield[@code='d']">
14885                                         <publisher>
14886                                                 <xsl:value-of select="."></xsl:value-of>
14887                                         </publisher>
14888                                 </xsl:for-each>
14889                                 <xsl:for-each select="marc:subfield[@code='b']">
14890                                         <edition>
14891                                                 <xsl:value-of select="."></xsl:value-of>
14892                                         </edition>
14893                                 </xsl:for-each>
14894                         </originInfo>
14895                 </xsl:if>
14896         </xsl:template>
14897         <xsl:template name="relatedLanguage">
14898                 <xsl:for-each select="marc:subfield[@code='e']">
14899                         <xsl:call-template name="getLanguage">
14900                                 <xsl:with-param name="langString">
14901                                         <xsl:value-of select="."></xsl:value-of>
14902                                 </xsl:with-param>
14903                         </xsl:call-template>
14904                 </xsl:for-each>
14905         </xsl:template>
14906         <xsl:template name="nameDate">
14907                 <xsl:for-each select="marc:subfield[@code='d']">
14908                         <namePart type="date">
14909                                 <xsl:call-template name="chopPunctuation">
14910                                         <xsl:with-param name="chopString" select="."></xsl:with-param>
14911                                 </xsl:call-template>
14912                         </namePart>
14913                 </xsl:for-each>
14914         </xsl:template>
14915         <xsl:template name="subjectAuthority">
14916                 <xsl:if test="@ind2!=4">
14917                         <xsl:if test="@ind2!=' '">
14918                                 <xsl:if test="@ind2!=8">
14919                                         <xsl:if test="@ind2!=9">
14920                                                 <xsl:attribute name="authority">
14921                                                         <xsl:choose>
14922                                                                 <xsl:when test="@ind2=0">lcsh</xsl:when>
14923                                                                 <xsl:when test="@ind2=1">lcshac</xsl:when>
14924                                                                 <xsl:when test="@ind2=2">mesh</xsl:when>
14925                                                                 <!-- 1/04 fix -->
14926                                                                 <xsl:when test="@ind2=3">nal</xsl:when>
14927                                                                 <xsl:when test="@ind2=5">csh</xsl:when>
14928                                                                 <xsl:when test="@ind2=6">rvm</xsl:when>
14929                                                                 <xsl:when test="@ind2=7">
14930                                                                         <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
14931                                                                 </xsl:when>
14932                                                         </xsl:choose>
14933                                                 </xsl:attribute>
14934                                         </xsl:if>
14935                                 </xsl:if>
14936                         </xsl:if>
14937                 </xsl:if>
14938         </xsl:template>
14939         <xsl:template name="subjectAnyOrder">
14940                 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
14941                         <xsl:choose>
14942                                 <xsl:when test="@code='v'">
14943                                         <xsl:call-template name="subjectGenre"></xsl:call-template>
14944                                 </xsl:when>
14945                                 <xsl:when test="@code='x'">
14946                                         <xsl:call-template name="subjectTopic"></xsl:call-template>
14947                                 </xsl:when>
14948                                 <xsl:when test="@code='y'">
14949                                         <xsl:call-template name="subjectTemporalY"></xsl:call-template>
14950                                 </xsl:when>
14951                                 <xsl:when test="@code='z'">
14952                                         <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
14953                                 </xsl:when>
14954                         </xsl:choose>
14955                 </xsl:for-each>
14956         </xsl:template>
14957         <xsl:template name="specialSubfieldSelect">
14958                 <xsl:param name="anyCodes"></xsl:param>
14959                 <xsl:param name="axis"></xsl:param>
14960                 <xsl:param name="beforeCodes"></xsl:param>
14961                 <xsl:param name="afterCodes"></xsl:param>
14962                 <xsl:variable name="str">
14963                         <xsl:for-each select="marc:subfield">
14964                                 <xsl:if test="contains($anyCodes, @code)      or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis])      or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
14965                                         <xsl:value-of select="text()"></xsl:value-of>
14966                                         <xsl:text> </xsl:text>
14967                                 </xsl:if>
14968                         </xsl:for-each>
14969                 </xsl:variable>
14970                 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
14971         </xsl:template>
14972         
14973         <!-- 3.2 change tmee 6xx $v genre -->
14974         <xsl:template match="marc:datafield[@tag=600]">
14975                 <subject>
14976                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
14977                         <name type="personal">
14978                                 <xsl:call-template name="uri" />
14979                                 <namePart>
14980                                         <xsl:call-template name="chopPunctuation">
14981                                                 <xsl:with-param name="chopString">
14982                                                         <xsl:call-template name="subfieldSelect">
14983                                                                 <xsl:with-param name="codes">aq</xsl:with-param>
14984                                                         </xsl:call-template>
14985                                                 </xsl:with-param>
14986                                         </xsl:call-template>
14987                                 </namePart>
14988                                 <xsl:call-template name="termsOfAddress"></xsl:call-template>
14989                                 <xsl:call-template name="nameDate"></xsl:call-template>
14990                                 <xsl:call-template name="affiliation"></xsl:call-template>
14991                                 <xsl:call-template name="role"></xsl:call-template>
14992                         </name>
14993                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
14994                 </subject>
14995         </xsl:template>
14996         <xsl:template match="marc:datafield[@tag=610]">
14997                 <subject>
14998                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
14999                         <name type="corporate">
15000                                 <xsl:call-template name="uri" />
15001                                 <xsl:for-each select="marc:subfield[@code='a']">
15002                                         <namePart>
15003                                                 <xsl:value-of select="."></xsl:value-of>
15004                                         </namePart>
15005                                 </xsl:for-each>
15006                                 <xsl:for-each select="marc:subfield[@code='b']">
15007                                         <namePart>
15008                                                 <xsl:value-of select="."></xsl:value-of>
15009                                         </namePart>
15010                                 </xsl:for-each>
15011                                 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
15012                                         <namePart>
15013                                                 <xsl:call-template name="subfieldSelect">
15014                                                         <xsl:with-param name="codes">cdnp</xsl:with-param>
15015                                                 </xsl:call-template>
15016                                         </namePart>
15017                                 </xsl:if>
15018                                 <xsl:call-template name="role"></xsl:call-template>
15019                         </name>
15020                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15021                 </subject>
15022         </xsl:template>
15023         <xsl:template match="marc:datafield[@tag=611]">
15024                 <subject>
15025                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
15026                         <name type="conference">
15027                                 <xsl:call-template name="uri" />
15028                                 <namePart>
15029                                         <xsl:call-template name="subfieldSelect">
15030                                                 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
15031                                         </xsl:call-template>
15032                                 </namePart>
15033                                 <xsl:for-each select="marc:subfield[@code='4']">
15034                                         <role>
15035                                                 <roleTerm authority="marcrelator" type="code">
15036                                                         <xsl:value-of select="."></xsl:value-of>
15037                                                 </roleTerm>
15038                                         </role>
15039                                 </xsl:for-each>
15040                         </name>
15041                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15042                 </subject>
15043         </xsl:template>
15044         <xsl:template match="marc:datafield[@tag=630]">
15045                 <subject>
15046                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
15047                         <xsl:variable name="titleChop">
15048                                 <xsl:call-template name="chopPunctuation">
15049                                         <xsl:with-param name="chopString">
15050                                                 <xsl:call-template name="subfieldSelect">
15051                                                         <xsl:with-param name="codes">adfhklor</xsl:with-param>
15052                                                 </xsl:call-template>
15053                                         </xsl:with-param>
15054                                 </xsl:call-template>
15055                         </xsl:variable>
15056                         <titleInfo>
15057                                 <title>
15058                                         <xsl:value-of select="$titleChop" />
15059                                 </title>
15060                                 <xsl:call-template name="part"></xsl:call-template>
15061                         </titleInfo>
15062                         <titleInfo type="nfi">
15063                                 <xsl:choose>
15064                                         <xsl:when test="@ind1>0">
15065                                                 <nonSort>
15066                                                         <xsl:value-of select="substring($titleChop,1,@ind1)"/>
15067                                                 </nonSort>
15068                                                 <title>
15069                                                         <xsl:value-of select="substring($titleChop,@ind1+1)"/>
15070                                                 </title>
15071                                                 <xsl:call-template name="part"/>
15072                                         </xsl:when>
15073                                         <xsl:otherwise>
15074                                                 <title>
15075                                                         <xsl:value-of select="$titleChop" />
15076                                                 </title>
15077                                         </xsl:otherwise>
15078                                 </xsl:choose>
15079                                 <xsl:call-template name="part"></xsl:call-template>
15080                         </titleInfo>
15081                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15082                 </subject>
15083         </xsl:template>
15084         <xsl:template match="marc:datafield[@tag=650]">
15085                 <subject>
15086                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
15087                         <topic>
15088                                 <xsl:call-template name="uri" />
15089                                 <xsl:call-template name="chopPunctuation">
15090                                         <xsl:with-param name="chopString">
15091                                                 <xsl:call-template name="subfieldSelect">
15092                                                         <xsl:with-param name="codes">abcd</xsl:with-param>
15093                                                 </xsl:call-template>
15094                                         </xsl:with-param>
15095                                 </xsl:call-template>
15096                         </topic>
15097                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15098                 </subject>
15099         </xsl:template>
15100         <xsl:template match="marc:datafield[@tag=651]">
15101                 <subject>
15102                         <xsl:call-template name="subjectAuthority"></xsl:call-template>
15103                         <xsl:for-each select="marc:subfield[@code='a']">
15104                                 <geographic>
15105                                         <xsl:call-template name="uri" />
15106                                         <xsl:call-template name="chopPunctuation">
15107                                                 <xsl:with-param name="chopString" select="."></xsl:with-param>
15108                                         </xsl:call-template>
15109                                 </geographic>
15110                         </xsl:for-each>
15111                         <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15112                 </subject>
15113         </xsl:template>
15114         <xsl:template match="marc:datafield[@tag=653]">
15115                 <subject>
15116                         <xsl:for-each select="marc:subfield[@code='a']">
15117                                 <topic>
15118                                         <xsl:call-template name="uri" />
15119                                         <xsl:value-of select="."></xsl:value-of>
15120                                 </topic>
15121                         </xsl:for-each>
15122                 </subject>
15123         </xsl:template>
15124         <xsl:template match="marc:datafield[@tag=656]">
15125                 <subject>
15126                         <xsl:if test="marc:subfield[@code=2]">
15127                                 <xsl:attribute name="authority">
15128                                         <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
15129                                 </xsl:attribute>
15130                         </xsl:if>
15131                         <occupation>
15132                                 <xsl:call-template name="uri" />
15133                                 <xsl:call-template name="chopPunctuation">
15134                                         <xsl:with-param name="chopString">
15135                                                 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
15136                                         </xsl:with-param>
15137                                 </xsl:call-template>
15138                         </occupation>
15139                 </subject>
15140         </xsl:template>
15141         <xsl:template name="termsOfAddress">
15142                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
15143                         <namePart type="termsOfAddress">
15144                                 <xsl:call-template name="chopPunctuation">
15145                                         <xsl:with-param name="chopString">
15146                                                 <xsl:call-template name="subfieldSelect">
15147                                                         <xsl:with-param name="codes">bc</xsl:with-param>
15148                                                 </xsl:call-template>
15149                                         </xsl:with-param>
15150                                 </xsl:call-template>
15151                         </namePart>
15152                 </xsl:if>
15153         </xsl:template>
15154         <xsl:template name="displayLabel">
15155                 <xsl:if test="marc:subfield[@code='i']">
15156                         <xsl:attribute name="displayLabel">
15157                                 <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
15158                         </xsl:attribute>
15159                 </xsl:if>
15160                 <xsl:if test="marc:subfield[@code='3']">
15161                         <xsl:attribute name="displayLabel">
15162                                 <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
15163                         </xsl:attribute>
15164                 </xsl:if>
15165         </xsl:template>
15166         <xsl:template name="isInvalid">
15167                 <xsl:param name="type"/>
15168                 <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
15169                         <identifier>
15170                                 <xsl:attribute name="type">
15171                                         <xsl:value-of select="$type"/>
15172                                 </xsl:attribute>
15173                                 <xsl:attribute name="invalid">
15174                                         <xsl:text>yes</xsl:text>
15175                                 </xsl:attribute>
15176                                 <xsl:if test="marc:subfield[@code='z']">
15177                                         <xsl:value-of select="marc:subfield[@code='z']"/>
15178                                 </xsl:if>
15179                                 <xsl:if test="marc:subfield[@code='y']">
15180                                         <xsl:value-of select="marc:subfield[@code='y']"/>
15181                                 </xsl:if>
15182                         </identifier>
15183                 </xsl:if>
15184         </xsl:template>
15185         <xsl:template name="subtitle">
15186                 <xsl:if test="marc:subfield[@code='b']">
15187                         <subTitle>
15188                                 <xsl:call-template name="chopPunctuation">
15189                                         <xsl:with-param name="chopString">
15190                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
15191                                                 <!--<xsl:call-template name="subfieldSelect">
15192                                                         <xsl:with-param name="codes">b</xsl:with-param>                                                                 
15193                                                 </xsl:call-template>-->
15194                                         </xsl:with-param>
15195                                 </xsl:call-template>
15196                         </subTitle>
15197                 </xsl:if>
15198         </xsl:template>
15199         <xsl:template name="script">
15200                 <xsl:param name="scriptCode"></xsl:param>
15201                 <xsl:attribute name="script">
15202                         <xsl:choose>
15203                                 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
15204                                 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
15205                                 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
15206                                 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
15207                                 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
15208                                 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
15209                         </xsl:choose>
15210                 </xsl:attribute>
15211         </xsl:template>
15212         <xsl:template name="parsePart">
15213                 <!-- assumes 773$q= 1:2:3<4
15214                      with up to 3 levels and one optional start page
15215                 -->
15216                 <xsl:variable name="level1">
15217                         <xsl:choose>
15218                                 <xsl:when test="contains(text(),':')">
15219                                         <!-- 1:2 -->
15220                                         <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
15221                                 </xsl:when>
15222                                 <xsl:when test="not(contains(text(),':'))">
15223                                         <!-- 1 or 1<3 -->
15224                                         <xsl:if test="contains(text(),'&lt;')">
15225                                                 <!-- 1<3 -->
15226                                                 <xsl:value-of select="substring-before(text(),'&lt;')"></xsl:value-of>
15227                                         </xsl:if>
15228                                         <xsl:if test="not(contains(text(),'&lt;'))">
15229                                                 <!-- 1 -->
15230                                                 <xsl:value-of select="text()"></xsl:value-of>
15231                                         </xsl:if>
15232                                 </xsl:when>
15233                         </xsl:choose>
15234                 </xsl:variable>
15235                 <xsl:variable name="sici2">
15236                         <xsl:choose>
15237                                 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
15238                                         <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
15239                                 </xsl:when>
15240                                 <xsl:otherwise>
15241                                         <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
15242                                 </xsl:otherwise>
15243                         </xsl:choose>
15244                 </xsl:variable>
15245                 <xsl:variable name="level2">
15246                         <xsl:choose>
15247                                 <xsl:when test="contains($sici2,':')">
15248                                         <!--  2:3<4  -->
15249                                         <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
15250                                 </xsl:when>
15251                                 <xsl:when test="contains($sici2,'&lt;')">
15252                                         <!-- 1: 2<4 -->
15253                                         <xsl:value-of select="substring-before($sici2,'&lt;')"></xsl:value-of>
15254                                 </xsl:when>
15255                                 <xsl:otherwise>
15256                                         <xsl:value-of select="$sici2"></xsl:value-of>
15257                                         <!-- 1:2 -->
15258                                 </xsl:otherwise>
15259                         </xsl:choose>
15260                 </xsl:variable>
15261                 <xsl:variable name="sici3">
15262                         <xsl:choose>
15263                                 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
15264                                         <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
15265                                 </xsl:when>
15266                                 <xsl:otherwise>
15267                                         <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
15268                                 </xsl:otherwise>
15269                         </xsl:choose>
15270                 </xsl:variable>
15271                 <xsl:variable name="level3">
15272                         <xsl:choose>
15273                                 <xsl:when test="contains($sici3,'&lt;')">
15274                                         <!-- 2<4 -->
15275                                         <xsl:value-of select="substring-before($sici3,'&lt;')"></xsl:value-of>
15276                                 </xsl:when>
15277                                 <xsl:otherwise>
15278                                         <xsl:value-of select="$sici3"></xsl:value-of>
15279                                         <!-- 3 -->
15280                                 </xsl:otherwise>
15281                         </xsl:choose>
15282                 </xsl:variable>
15283                 <xsl:variable name="page">
15284                         <xsl:if test="contains(text(),'&lt;')">
15285                                 <xsl:value-of select="substring-after(text(),'&lt;')"></xsl:value-of>
15286                         </xsl:if>
15287                 </xsl:variable>
15288                 <xsl:if test="$level1">
15289                         <detail level="1">
15290                                 <number>
15291                                         <xsl:value-of select="$level1"></xsl:value-of>
15292                                 </number>
15293                         </detail>
15294                 </xsl:if>
15295                 <xsl:if test="$level2">
15296                         <detail level="2">
15297                                 <number>
15298                                         <xsl:value-of select="$level2"></xsl:value-of>
15299                                 </number>
15300                         </detail>
15301                 </xsl:if>
15302                 <xsl:if test="$level3">
15303                         <detail level="3">
15304                                 <number>
15305                                         <xsl:value-of select="$level3"></xsl:value-of>
15306                                 </number>
15307                         </detail>
15308                 </xsl:if>
15309                 <xsl:if test="$page">
15310                         <extent unit="page">
15311                                 <start>
15312                                         <xsl:value-of select="$page"></xsl:value-of>
15313                                 </start>
15314                         </extent>
15315                 </xsl:if>
15316         </xsl:template>
15317         <xsl:template name="getLanguage">
15318                 <xsl:param name="langString"></xsl:param>
15319                 <xsl:param name="controlField008-35-37"></xsl:param>
15320                 <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
15321                 <xsl:choose>
15322                         <xsl:when test="$length=0"></xsl:when>
15323                         <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
15324                                 <xsl:call-template name="getLanguage">
15325                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
15326                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
15327                                 </xsl:call-template>
15328                         </xsl:when>
15329                         <xsl:otherwise>
15330                                 <language>
15331                                         <languageTerm authority="iso639-2b" type="code">
15332                                                 <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
15333                                         </languageTerm>
15334                                 </language>
15335                                 <xsl:call-template name="getLanguage">
15336                                         <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
15337                                         <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
15338                                 </xsl:call-template>
15339                         </xsl:otherwise>
15340                 </xsl:choose>
15341         </xsl:template>
15342         <xsl:template name="isoLanguage">
15343                 <xsl:param name="currentLanguage"></xsl:param>
15344                 <xsl:param name="usedLanguages"></xsl:param>
15345                 <xsl:param name="remainingLanguages"></xsl:param>
15346                 <xsl:choose>
15347                         <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
15348                         <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
15349                                 <language>
15350                                         <xsl:if test="@code!='a'">
15351                                                 <xsl:attribute name="objectPart">
15352                                                         <xsl:choose>
15353                                                                 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
15354                                                                 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
15355                                                                 <xsl:when test="@code='e'">libretto</xsl:when>
15356                                                                 <xsl:when test="@code='f'">table of contents</xsl:when>
15357                                                                 <xsl:when test="@code='g'">accompanying material</xsl:when>
15358                                                                 <xsl:when test="@code='h'">translation</xsl:when>
15359                                                         </xsl:choose>
15360                                                 </xsl:attribute>
15361                                         </xsl:if>
15362                                         <languageTerm authority="iso639-2b" type="code">
15363                                                 <xsl:value-of select="$currentLanguage"></xsl:value-of>
15364                                         </languageTerm>
15365                                 </language>
15366                                 <xsl:call-template name="isoLanguage">
15367                                         <xsl:with-param name="currentLanguage">
15368                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
15369                                         </xsl:with-param>
15370                                         <xsl:with-param name="usedLanguages">
15371                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
15372                                         </xsl:with-param>
15373                                         <xsl:with-param name="remainingLanguages">
15374                                                 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
15375                                         </xsl:with-param>
15376                                 </xsl:call-template>
15377                         </xsl:when>
15378                         <xsl:otherwise>
15379                                 <xsl:call-template name="isoLanguage">
15380                                         <xsl:with-param name="currentLanguage">
15381                                                 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
15382                                         </xsl:with-param>
15383                                         <xsl:with-param name="usedLanguages">
15384                                                 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
15385                                         </xsl:with-param>
15386                                         <xsl:with-param name="remainingLanguages">
15387                                                 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
15388                                         </xsl:with-param>
15389                                 </xsl:call-template>
15390                         </xsl:otherwise>
15391                 </xsl:choose>
15392         </xsl:template>
15393         <xsl:template name="chopBrackets">
15394                 <xsl:param name="chopString"></xsl:param>
15395                 <xsl:variable name="string">
15396                         <xsl:call-template name="chopPunctuation">
15397                                 <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
15398                         </xsl:call-template>
15399                 </xsl:variable>
15400                 <xsl:if test="substring($string, 1,1)='['">
15401                         <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
15402                 </xsl:if>
15403                 <xsl:if test="substring($string, 1,1)!='['">
15404                         <xsl:value-of select="$string"></xsl:value-of>
15405                 </xsl:if>
15406         </xsl:template>
15407         <xsl:template name="rfcLanguages">
15408                 <xsl:param name="nodeNum"></xsl:param>
15409                 <xsl:param name="usedLanguages"></xsl:param>
15410                 <xsl:param name="controlField008-35-37"></xsl:param>
15411                 <xsl:variable name="currentLanguage" select="."></xsl:variable>
15412                 <xsl:choose>
15413                         <xsl:when test="not($currentLanguage)"></xsl:when>
15414                         <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
15415                                 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
15416                                         <language>
15417                                                 <xsl:if test="@code!='a'">
15418                                                         <xsl:attribute name="objectPart">
15419                                                                 <xsl:choose>
15420                                                                         <xsl:when test="@code='b'">summary or subtitle</xsl:when>
15421                                                                         <xsl:when test="@code='d'">sung or spoken text</xsl:when>
15422                                                                         <xsl:when test="@code='e'">libretto</xsl:when>
15423                                                                         <xsl:when test="@code='f'">table of contents</xsl:when>
15424                                                                         <xsl:when test="@code='g'">accompanying material</xsl:when>
15425                                                                         <xsl:when test="@code='h'">translation</xsl:when>
15426                                                                 </xsl:choose>
15427                                                         </xsl:attribute>
15428                                                 </xsl:if>
15429                                                 <languageTerm authority="rfc3066" type="code">
15430                                                         <xsl:value-of select="$currentLanguage"/>
15431                                                 </languageTerm>
15432                                         </language>
15433                                 </xsl:if>
15434                         </xsl:when>
15435                         <xsl:otherwise>
15436                         </xsl:otherwise>
15437                 </xsl:choose>
15438         </xsl:template>
15439         <xsl:template name="datafield">
15440                 <xsl:param name="tag"/>
15441                 <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
15442                 <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
15443                 <xsl:param name="subfields"/>
15444                 <xsl:element name="marc:datafield">
15445                         <xsl:attribute name="tag">
15446                                 <xsl:value-of select="$tag"/>
15447                         </xsl:attribute>
15448                         <xsl:attribute name="ind1">
15449                                 <xsl:value-of select="$ind1"/>
15450                         </xsl:attribute>
15451                         <xsl:attribute name="ind2">
15452                                 <xsl:value-of select="$ind2"/>
15453                         </xsl:attribute>
15454                         <xsl:copy-of select="$subfields"/>
15455                 </xsl:element>
15456         </xsl:template>
15457
15458         <xsl:template name="subfieldSelect">
15459                 <xsl:param name="codes"/>
15460                 <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
15461                 <xsl:variable name="str">
15462                         <xsl:for-each select="marc:subfield">
15463                                 <xsl:if test="contains($codes, @code)">
15464                                         <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
15465                                 </xsl:if>
15466                         </xsl:for-each>
15467                 </xsl:variable>
15468                 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
15469         </xsl:template>
15470
15471         <xsl:template name="buildSpaces">
15472                 <xsl:param name="spaces"/>
15473                 <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
15474                 <xsl:if test="$spaces>0">
15475                         <xsl:value-of select="$char"/>
15476                         <xsl:call-template name="buildSpaces">
15477                                 <xsl:with-param name="spaces" select="$spaces - 1"/>
15478                                 <xsl:with-param name="char" select="$char"/>
15479                         </xsl:call-template>
15480                 </xsl:if>
15481         </xsl:template>
15482
15483         <xsl:template name="chopPunctuation">
15484                 <xsl:param name="chopString"/>
15485                 <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
15486                 <xsl:variable name="length" select="string-length($chopString)"/>
15487                 <xsl:choose>
15488                         <xsl:when test="$length=0"/>
15489                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
15490                                 <xsl:call-template name="chopPunctuation">
15491                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
15492                                         <xsl:with-param name="punctuation" select="$punctuation"/>
15493                                 </xsl:call-template>
15494                         </xsl:when>
15495                         <xsl:when test="not($chopString)"/>
15496                         <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
15497                 </xsl:choose>
15498         </xsl:template>
15499
15500         <xsl:template name="chopPunctuationFront">
15501                 <xsl:param name="chopString"/>
15502                 <xsl:variable name="length" select="string-length($chopString)"/>
15503                 <xsl:choose>
15504                         <xsl:when test="$length=0"/>
15505                         <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
15506                                 <xsl:call-template name="chopPunctuationFront">
15507                                         <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
15508                                 </xsl:call-template>
15509                         </xsl:when>
15510                         <xsl:when test="not($chopString)"/>
15511                         <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
15512                 </xsl:choose>
15513         </xsl:template>
15514 </xsl:stylesheet>$$ WHERE name = 'mods32';
15515
15516 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
15517 DECLARE
15518     bib     biblio.record_entry%ROWTYPE;
15519     idx     config.metabib_field%ROWTYPE;
15520     xfrm        config.xml_transform%ROWTYPE;
15521     prev_xfrm   TEXT;
15522     transformed_xml TEXT;
15523     xml_node    TEXT;
15524     xml_node_list   TEXT[];
15525     facet_text  TEXT;
15526     browse_text TEXT;
15527     sort_value  TEXT;
15528     raw_text    TEXT;
15529     curr_text   TEXT;
15530     joiner      TEXT := default_joiner; -- XXX will index defs supply a joiner?
15531     authority_text TEXT;
15532     authority_link BIGINT;
15533     output_row  metabib.field_entry_template%ROWTYPE;
15534 BEGIN
15535
15536     -- Start out with no field-use bools set
15537     output_row.browse_field = FALSE;
15538     output_row.facet_field = FALSE;
15539     output_row.search_field = FALSE;
15540
15541     -- Get the record
15542     SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
15543
15544     -- Loop over the indexing entries
15545     FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
15546
15547         joiner := COALESCE(idx.joiner, default_joiner);
15548
15549         SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
15550
15551         -- See if we can skip the XSLT ... it's expensive
15552         IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
15553             -- Can't skip the transform
15554             IF xfrm.xslt <> '---' THEN
15555                 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
15556             ELSE
15557                 transformed_xml := bib.marc;
15558             END IF;
15559
15560             prev_xfrm := xfrm.name;
15561         END IF;
15562
15563         xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15564
15565         raw_text := NULL;
15566         FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
15567             CONTINUE WHEN xml_node !~ E'^\\s*<';
15568
15569             -- XXX much of this should be moved into oils_xpath_string...
15570             curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
15571                 oils_xpath( '//text()',
15572                     REGEXP_REPLACE(
15573                         REGEXP_REPLACE( -- This escapes all &s not followed by "amp;".  Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
15574                             REGEXP_REPLACE( -- This escapes embeded <s
15575                                 xml_node,
15576                                 $re$(>[^<]+)(<)([^>]+<)$re$,
15577                                 E'\\1&lt;\\3',
15578                                 'g'
15579                             ),
15580                             '&(?!amp;)',
15581                             '&amp;',
15582                             'g'
15583                         ),
15584                         E'\\s+',
15585                         ' ',
15586                         'g'
15587                     )
15588                 ), ' '), ''),
15589                 joiner
15590             );
15591
15592             CONTINUE WHEN curr_text IS NULL OR curr_text = '';
15593
15594             IF raw_text IS NOT NULL THEN
15595                 raw_text := raw_text || joiner;
15596             END IF;
15597
15598             raw_text := COALESCE(raw_text,'') || curr_text;
15599
15600             -- autosuggest/metabib.browse_entry
15601             IF idx.browse_field THEN
15602
15603                 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
15604                     browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15605                 ELSE
15606                     browse_text := curr_text;
15607                 END IF;
15608
15609                 IF idx.browse_sort_xpath IS NOT NULL AND
15610                     idx.browse_sort_xpath <> '' THEN
15611
15612                     sort_value := oils_xpath_string(
15613                         idx.browse_sort_xpath, xml_node, joiner,
15614                         ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
15615                     );
15616                 ELSE
15617                     sort_value := browse_text;
15618                 END IF;
15619
15620                 output_row.field_class = idx.field_class;
15621                 output_row.field = idx.id;
15622                 output_row.source = rid;
15623                 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
15624                 output_row.sort_value :=
15625                     public.naco_normalize(sort_value);
15626
15627                 output_row.authority := NULL;
15628
15629                 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
15630                     authority_text := oils_xpath_string(
15631                         idx.authority_xpath, xml_node, joiner,
15632                         ARRAY[
15633                             ARRAY[xfrm.prefix, xfrm.namespace_uri],
15634                             ARRAY['xlink','http://www.w3.org/1999/xlink']
15635                         ]
15636                     );
15637
15638                     IF authority_text ~ '^\d+$' THEN
15639                         authority_link := authority_text::BIGINT;
15640                         PERFORM * FROM authority.record_entry WHERE id = authority_link;
15641                         IF FOUND THEN
15642                             output_row.authority := authority_link;
15643                         END IF;
15644                     END IF;
15645
15646                 END IF;
15647
15648                 output_row.browse_field = TRUE;
15649                 -- Returning browse rows with search_field = true for search+browse
15650                 -- configs allows us to retain granularity of being able to search
15651                 -- browse fields with "starts with" type operators (for example, for
15652                 -- titles of songs in music albums)
15653                 IF idx.search_field THEN
15654                     output_row.search_field = TRUE;
15655                 END IF;
15656                 RETURN NEXT output_row;
15657                 output_row.browse_field = FALSE;
15658                 output_row.search_field = FALSE;
15659                 output_row.sort_value := NULL;
15660             END IF;
15661
15662             -- insert raw node text for faceting
15663             IF idx.facet_field THEN
15664
15665                 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
15666                     facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15667                 ELSE
15668                     facet_text := curr_text;
15669                 END IF;
15670
15671                 output_row.field_class = idx.field_class;
15672                 output_row.field = -1 * idx.id;
15673                 output_row.source = rid;
15674                 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
15675
15676                 output_row.facet_field = TRUE;
15677                 RETURN NEXT output_row;
15678                 output_row.facet_field = FALSE;
15679             END IF;
15680
15681         END LOOP;
15682
15683         CONTINUE WHEN raw_text IS NULL OR raw_text = '';
15684
15685         -- insert combined node text for searching
15686         IF idx.search_field THEN
15687             output_row.field_class = idx.field_class;
15688             output_row.field = idx.id;
15689             output_row.source = rid;
15690             output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
15691
15692             output_row.search_field = TRUE;
15693             RETURN NEXT output_row;
15694             output_row.search_field = FALSE;
15695         END IF;
15696
15697     END LOOP;
15698
15699 END;
15700
15701 $func$ LANGUAGE PLPGSQL;
15702
15703
15704 CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( bib_id BIGINT, skip_facet BOOL DEFAULT FALSE, skip_browse BOOL DEFAULT FALSE, skip_search BOOL DEFAULT FALSE ) RETURNS VOID AS $func$
15705 DECLARE
15706     fclass          RECORD;
15707     ind_data        metabib.field_entry_template%ROWTYPE;
15708     mbe_row         metabib.browse_entry%ROWTYPE;
15709     mbe_id          BIGINT;
15710     b_skip_facet    BOOL;
15711     b_skip_browse   BOOL;
15712     b_skip_search   BOOL;
15713     value_prepped   TEXT;
15714 BEGIN
15715
15716     SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
15717     SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
15718     SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name =  'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
15719
15720     PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
15721     IF NOT FOUND THEN
15722         IF NOT b_skip_search THEN
15723             FOR fclass IN SELECT * FROM config.metabib_class LOOP
15724                 -- RAISE NOTICE 'Emptying out %', fclass.name;
15725                 EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
15726             END LOOP;
15727         END IF;
15728         IF NOT b_skip_facet THEN
15729             DELETE FROM metabib.facet_entry WHERE source = bib_id;
15730         END IF;
15731         IF NOT b_skip_browse THEN
15732             DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
15733         END IF;
15734     END IF;
15735
15736     FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id ) LOOP
15737         IF ind_data.field < 0 THEN
15738             ind_data.field = -1 * ind_data.field;
15739         END IF;
15740
15741         IF ind_data.facet_field AND NOT b_skip_facet THEN
15742             INSERT INTO metabib.facet_entry (field, source, value)
15743                 VALUES (ind_data.field, ind_data.source, ind_data.value);
15744         END IF;
15745
15746         IF ind_data.browse_field AND NOT b_skip_browse THEN
15747             -- A caveat about this SELECT: this should take care of replacing
15748             -- old mbe rows when data changes, but not if normalization (by
15749             -- which I mean specifically the output of
15750             -- evergreen.oils_tsearch2()) changes.  It may or may not be
15751             -- expensive to add a comparison of index_vector to index_vector
15752             -- to the WHERE clause below.
15753
15754             value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
15755             SELECT INTO mbe_row * FROM metabib.browse_entry
15756                 WHERE value = value_prepped AND sort_value = ind_data.sort_value;
15757
15758             IF FOUND THEN
15759                 mbe_id := mbe_row.id;
15760             ELSE
15761                 INSERT INTO metabib.browse_entry
15762                     ( value, sort_value ) VALUES
15763                     ( value_prepped, ind_data.sort_value );
15764
15765                 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
15766             END IF;
15767
15768             INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
15769                 VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
15770         END IF;
15771
15772         IF ind_data.search_field AND NOT b_skip_search THEN
15773             -- Avoid inserting duplicate rows
15774             EXECUTE 'SELECT 1 FROM metabib.' || ind_data.field_class ||
15775                 '_field_entry WHERE field = $1 AND source = $2 AND value = $3'
15776                 INTO mbe_id USING ind_data.field, ind_data.source, ind_data.value;
15777                 -- RAISE NOTICE 'Search for an already matching row returned %', mbe_id;
15778             IF mbe_id IS NULL THEN
15779                 EXECUTE $$
15780                 INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
15781                     VALUES ($$ ||
15782                         quote_literal(ind_data.field) || $$, $$ ||
15783                         quote_literal(ind_data.source) || $$, $$ ||
15784                         quote_literal(ind_data.value) ||
15785                     $$);$$;
15786             END IF;
15787         END IF;
15788
15789     END LOOP;
15790
15791     IF NOT b_skip_search THEN
15792         PERFORM metabib.update_combined_index_vectors(bib_id);
15793     END IF;
15794
15795     RETURN;
15796 END;
15797 $func$ LANGUAGE PLPGSQL;
15798
15799 -- Don't use Title Proper search field as the browse field
15800 UPDATE config.metabib_field SET browse_field = FALSE, browse_xpath = NULL, browse_sort_xpath = NULL WHERE id = 6;
15801
15802 -- Create a new Title Proper browse config
15803 INSERT INTO config.metabib_field ( id, field_class, name, label, format, xpath, search_field, authority_xpath, browse_field, browse_sort_xpath ) VALUES
15804     (31, 'title', 'browse', oils_i18n_gettext(31, 'Title Proper (Browse)', 'cmf', 'label'), 'mods32', $$//mods32:mods/mods32:titleBrowse$$, FALSE, '//@xlink:href', TRUE, $$*[local-name() != "nonSort"]$$ );
15805
15806 SELECT evergreen.upgrade_deps_block_check('0845', :eg_version);
15807
15808 ALTER FUNCTION metabib.browse_pivot (integer[], text) STABLE;
15809 ALTER FUNCTION metabib.browse_bib_pivot (integer[], text) STABLE;
15810 ALTER FUNCTION metabib.browse_authority_pivot (integer[], text) STABLE;
15811 ALTER FUNCTION metabib.browse_authority_refs_pivot (integer[], text) STABLE;
15812
15813
15814 SELECT evergreen.upgrade_deps_block_check('0846', :eg_version);
15815
15816 CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT, force_add INT ) RETURNS TEXT AS $_$
15817
15818     use MARC::Record;
15819     use MARC::File::XML (BinaryEncoding => 'UTF-8');
15820     use MARC::Charset;
15821     use strict;
15822
15823     MARC::Charset->assume_unicode(1);
15824
15825     my $target_xml = shift;
15826     my $source_xml = shift;
15827     my $field_spec = shift;
15828     my $force_add = shift || 0;
15829
15830     my $target_r = MARC::Record->new_from_xml( $target_xml );
15831     my $source_r = MARC::Record->new_from_xml( $source_xml );
15832
15833     return $target_xml unless ($target_r && $source_r);
15834
15835     my @field_list = split(',', $field_spec);
15836
15837     my %fields;
15838     for my $f (@field_list) {
15839         $f =~ s/^\s*//; $f =~ s/\s*$//;
15840         if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
15841             my $field = $1;
15842             $field =~ s/\s+//;
15843             my $sf = $2;
15844             $sf =~ s/\s+//;
15845             my $match = $3;
15846             $match =~ s/^\s*//; $match =~ s/\s*$//;
15847             $fields{$field} = { sf => [ split('', $sf) ] };
15848             if ($match) {
15849                 my ($msf,$mre) = split('~', $match);
15850                 if (length($msf) > 0 and length($mre) > 0) {
15851                     $msf =~ s/^\s*//; $msf =~ s/\s*$//;
15852                     $mre =~ s/^\s*//; $mre =~ s/\s*$//;
15853                     $fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
15854                 }
15855             }
15856         }
15857     }
15858
15859     for my $f ( keys %fields) {
15860         if ( @{$fields{$f}{sf}} ) {
15861             for my $from_field ($source_r->field( $f )) {
15862                 my @tos = $target_r->field( $f );
15863                 if (!@tos) {
15864                     next if (exists($fields{$f}{match}) and !$force_add);
15865                     my @new_fields = map { $_->clone } $source_r->field( $f );
15866                     $target_r->insert_fields_ordered( @new_fields );
15867                 } else {
15868                     for my $to_field (@tos) {
15869                         if (exists($fields{$f}{match})) {
15870                             next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
15871                         }
15872                         for my $old_sf ($from_field->subfields) {
15873                             $to_field->add_subfields( @$old_sf ) if grep(/$$old_sf[0]/,@{$fields{$f}{sf}});
15874                         }
15875                     }
15876                 }
15877             }
15878         } else {
15879             my @new_fields = map { $_->clone } $source_r->field( $f );
15880             $target_r->insert_fields_ordered( @new_fields );
15881         }
15882     }
15883
15884     $target_xml = $target_r->as_xml_record;
15885     $target_xml =~ s/^<\?.+?\?>$//mo;
15886     $target_xml =~ s/\n//sgo;
15887     $target_xml =~ s/>\s+</></sgo;
15888
15889     return $target_xml;
15890
15891 $_$ LANGUAGE PLPERLU;
15892
15893
15894
15895 SELECT evergreen.upgrade_deps_block_check('0847', :eg_version);
15896
15897 CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$
15898 DECLARE
15899     cset                INT;
15900     main_entry          authority.control_set_authority_field%ROWTYPE;
15901     bib_field           authority.control_set_bib_field%ROWTYPE;
15902     auth_id             INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
15903     tmp_data            XML;
15904     replace_data        XML[] DEFAULT '{}'::XML[];
15905     replace_rules       TEXT[] DEFAULT '{}'::TEXT[];
15906     auth_field          XML[];
15907     auth_i1             TEXT;
15908     auth_i2             TEXT;
15909 BEGIN
15910     IF auth_id IS NULL THEN
15911         RETURN NULL;
15912     END IF;
15913
15914     -- Default to the LoC controll set
15915     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
15916
15917     -- if none, make a best guess
15918     IF cset IS NULL THEN
15919         SELECT  control_set INTO cset
15920           FROM  authority.control_set_authority_field
15921           WHERE tag IN (
15922                     SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
15923                       FROM  authority.record_entry
15924                       WHERE id = auth_id
15925                 )
15926           LIMIT 1;
15927     END IF;
15928
15929     -- if STILL none, no-op change
15930     IF cset IS NULL THEN
15931         RETURN XMLELEMENT(
15932             name record,
15933             XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
15934             XMLELEMENT( name leader, '00881nam a2200193   4500'),
15935             XMLELEMENT(
15936                 name datafield,
15937                 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
15938                 XMLELEMENT(
15939                                       name subfield,
15940                     XMLATTRIBUTES('d' AS code),
15941                     '901c'
15942                 )
15943             )
15944         )::TEXT;
15945     END IF;
15946
15947     FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP
15948         auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML);
15949         auth_i1 = (XPATH('@ind1',auth_field[1]))[1];
15950         auth_i2 = (XPATH('@ind2',auth_field[1]))[1];
15951         IF ARRAY_LENGTH(auth_field,1) > 0 THEN
15952             FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
15953                 SELECT XMLELEMENT( -- XMLAGG avoids magical <element> creation, but requires unnest subquery
15954                     name datafield,
15955                     XMLATTRIBUTES(bib_field.tag AS tag, auth_i1 AS ind1, auth_i2 AS ind2),
15956                     XMLAGG(UNNEST)
15957                 ) INTO tmp_data FROM UNNEST(XPATH('//*[local-name()="subfield"]', auth_field[1]));
15958                 replace_data := replace_data || tmp_data;
15959                 replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
15960                 tmp_data = NULL;
15961             END LOOP;
15962             EXIT;
15963         END IF;
15964     END LOOP;
15965
15966     SELECT XMLAGG(UNNEST) INTO tmp_data FROM UNNEST(replace_data);
15967
15968     RETURN XMLELEMENT(
15969         name record,
15970         XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
15971         XMLELEMENT( name leader, '00881nam a2200193   4500'),
15972         tmp_data,
15973         XMLELEMENT(
15974             name datafield,
15975                          XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
15976             XMLELEMENT(
15977                 name subfield,
15978                 XMLATTRIBUTES('r' AS code),
15979                 ARRAY_TO_STRING(replace_rules,',')
15980             )
15981         )
15982     )::TEXT;
15983 END;
15984 $f$ STABLE LANGUAGE PLPGSQL;
15985
15986 SELECT evergreen.upgrade_deps_block_check('0827', :eg_version);
15987 SET CONSTRAINTS ALL IMMEDIATE;
15988 -- otherwise, the ALTER TABLE statement below
15989 -- will fail with pending trigger events.
15990 ALTER TABLE action_trigger.event_definition ADD COLUMN repeat_delay INTERVAL;
15991
15992 COMMIT;
15993
15994 \qecho
15995 \qecho
15996 \qecho **** Certain improvements in 2.5, particularly browse, require a reingest
15997 \qecho **** of all records.  In order to allow this to continue without locking
15998 \qecho **** your entire bibliographic data set, consider generating SQL scripts
15999 \qecho **** with the following queries, then running those via psql:
16000 \qecho
16001 \qecho **** If you require a more responsive catalog/database while reingesting,
16002 \qecho **** consider adding 'pg_sleep()' calls between each reingest select or
16003 \qecho **** update.
16004 \qecho
16005 \qecho '\\t'
16006 \qecho '\\o /tmp/reingest_2.5_bib_recs.sql'
16007 \qecho 'SELECT ''select metabib.reingest_metabib_field_entries('' || id || '');'' FROM biblio.record_entry WHERE NOT DELETED AND id > 0;'
16008 \qecho
16009 \qecho '\\o /tmp/reingest_2.5_auth_recs.sql'
16010 \qecho 'SELECT ''-- Grab current setting'';'
16011 \qecho 'SELECT ''\\set force_reingest '' || enabled FROM config.internal_flag WHERE name = ''ingest.reingest.force_on_same_marc'';'
16012 \qecho 'SELECT ''update config.internal_flag set enabled = true where name = ''''ingest.reingest.force_on_same_marc'''';'';'
16013 \qecho 'SELECT ''update authority.record_entry set id = id where id = '' || id || '';'' FROM authority.record_entry WHERE NOT DELETED;'
16014 \qecho 'SELECT ''-- Restore previous setting'';'
16015 \qecho 'SELECT ''update config.internal_flag set enabled = :force_reingest where name = \'\'ingest.reingest.force_on_same_marc\'\';'';'
16016 \qecho '\\o'
16017 \qecho '\\t'