]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/3.7.2-3.7.3-upgrade-db.sql
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 3.7.2-3.7.3-upgrade-db.sql
1 --Upgrade Script for 3.7.2 to 3.7.3
2 \set eg_version '''3.7.3'''
3 BEGIN;
4 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.7.3', :eg_version);
5
6 SELECT evergreen.upgrade_deps_block_check('1306', :eg_version);
7
8 -- We don't pass this function arrays with nulls, so we save 5% not testing for that
9 CREATE OR REPLACE FUNCTION evergreen.text_array_merge_unique (
10     TEXT[], TEXT[]
11 ) RETURNS TEXT[] AS $F$
12     SELECT NULLIF(ARRAY(
13         SELECT * FROM UNNEST($1) x
14             UNION
15         SELECT * FROM UNNEST($2) y
16     ),'{}');
17 $F$ LANGUAGE SQL;
18
19 CREATE OR REPLACE FUNCTION search.symspell_build_raw_entry (
20     raw_input       TEXT,
21     source_class    TEXT,
22     no_limit        BOOL DEFAULT FALSE,
23     prefix_length   INT DEFAULT 6,
24     maxED           INT DEFAULT 3
25 ) RETURNS SETOF search.symspell_dictionary AS $F$
26 DECLARE
27     key         TEXT;
28     del_key     TEXT;
29     key_list    TEXT[];
30     entry       search.symspell_dictionary%ROWTYPE;
31 BEGIN
32     key := raw_input;
33
34     IF NOT no_limit AND CHARACTER_LENGTH(raw_input) > prefix_length THEN
35         key := SUBSTRING(key FROM 1 FOR prefix_length);
36         key_list := ARRAY[raw_input, key];
37     ELSE
38         key_list := ARRAY[key];
39     END IF;
40
41     FOREACH del_key IN ARRAY key_list LOOP
42         -- skip empty keys
43         CONTINUE WHEN del_key IS NULL OR CHARACTER_LENGTH(del_key) = 0;
44
45         entry.prefix_key := del_key;
46
47         entry.keyword_count := 0;
48         entry.title_count := 0;
49         entry.author_count := 0;
50         entry.subject_count := 0;
51         entry.series_count := 0;
52         entry.identifier_count := 0;
53
54         entry.keyword_suggestions := '{}';
55         entry.title_suggestions := '{}';
56         entry.author_suggestions := '{}';
57         entry.subject_suggestions := '{}';
58         entry.series_suggestions := '{}';
59         entry.identifier_suggestions := '{}';
60
61         IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
62         IF source_class = 'title' THEN entry.title_suggestions := ARRAY[raw_input]; END IF;
63         IF source_class = 'author' THEN entry.author_suggestions := ARRAY[raw_input]; END IF;
64         IF source_class = 'subject' THEN entry.subject_suggestions := ARRAY[raw_input]; END IF;
65         IF source_class = 'series' THEN entry.series_suggestions := ARRAY[raw_input]; END IF;
66         IF source_class = 'identifier' THEN entry.identifier_suggestions := ARRAY[raw_input]; END IF;
67         IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
68
69         IF del_key = raw_input THEN
70             IF source_class = 'keyword' THEN entry.keyword_count := 1; END IF;
71             IF source_class = 'title' THEN entry.title_count := 1; END IF;
72             IF source_class = 'author' THEN entry.author_count := 1; END IF;
73             IF source_class = 'subject' THEN entry.subject_count := 1; END IF;
74             IF source_class = 'series' THEN entry.series_count := 1; END IF;
75             IF source_class = 'identifier' THEN entry.identifier_count := 1; END IF;
76         END IF;
77
78         RETURN NEXT entry;
79     END LOOP;
80
81     FOR del_key IN SELECT x FROM UNNEST(search.symspell_generate_edits(key, 1, maxED)) x LOOP
82
83         -- skip empty keys
84         CONTINUE WHEN del_key IS NULL OR CHARACTER_LENGTH(del_key) = 0;
85         -- skip suggestions that are already too long for the prefix key
86         CONTINUE WHEN CHARACTER_LENGTH(del_key) <= (prefix_length - maxED) AND CHARACTER_LENGTH(raw_input) > prefix_length;
87
88         entry.keyword_suggestions := '{}';
89         entry.title_suggestions := '{}';
90         entry.author_suggestions := '{}';
91         entry.subject_suggestions := '{}';
92         entry.series_suggestions := '{}';
93         entry.identifier_suggestions := '{}';
94
95         IF source_class = 'keyword' THEN entry.keyword_count := 0; END IF;
96         IF source_class = 'title' THEN entry.title_count := 0; END IF;
97         IF source_class = 'author' THEN entry.author_count := 0; END IF;
98         IF source_class = 'subject' THEN entry.subject_count := 0; END IF;
99         IF source_class = 'series' THEN entry.series_count := 0; END IF;
100         IF source_class = 'identifier' THEN entry.identifier_count := 0; END IF;
101
102         entry.prefix_key := del_key;
103
104         IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
105         IF source_class = 'title' THEN entry.title_suggestions := ARRAY[raw_input]; END IF;
106         IF source_class = 'author' THEN entry.author_suggestions := ARRAY[raw_input]; END IF;
107         IF source_class = 'subject' THEN entry.subject_suggestions := ARRAY[raw_input]; END IF;
108         IF source_class = 'series' THEN entry.series_suggestions := ARRAY[raw_input]; END IF;
109         IF source_class = 'identifier' THEN entry.identifier_suggestions := ARRAY[raw_input]; END IF;
110         IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
111
112         RETURN NEXT entry;
113     END LOOP;
114
115 END;
116 $F$ LANGUAGE PLPGSQL STRICT IMMUTABLE;
117
118 CREATE OR REPLACE FUNCTION search.symspell_build_entries (
119     full_input      TEXT,
120     source_class    TEXT,
121     old_input       TEXT DEFAULT NULL,
122     include_phrases BOOL DEFAULT FALSE
123 ) RETURNS SETOF search.symspell_dictionary AS $F$
124 DECLARE
125     prefix_length   INT;
126     maxED           INT;
127     word_list   TEXT[];
128     input       TEXT;
129     word        TEXT;
130     entry       search.symspell_dictionary;
131 BEGIN
132     IF full_input IS NOT NULL THEN
133         SELECT value::INT INTO prefix_length FROM config.internal_flag WHERE name = 'symspell.prefix_length' AND enabled;
134         prefix_length := COALESCE(prefix_length, 6);
135
136         SELECT value::INT INTO maxED FROM config.internal_flag WHERE name = 'symspell.max_edit_distance' AND enabled;
137         maxED := COALESCE(maxED, 3);
138
139         input := evergreen.lowercase(full_input);
140         word_list := ARRAY_AGG(x) FROM search.symspell_parse_words_distinct(input) x;
141         IF word_list IS NULL THEN
142             RETURN;
143         END IF;
144     
145         IF CARDINALITY(word_list) > 1 AND include_phrases THEN
146             RETURN QUERY SELECT * FROM search.symspell_build_raw_entry(input, source_class, TRUE, prefix_length, maxED);
147         END IF;
148
149         FOREACH word IN ARRAY word_list LOOP
150             -- Skip words that have runs of 5 or more digits (I'm looking at you, ISxNs)
151             CONTINUE WHEN CHARACTER_LENGTH(word) > 4 AND word ~ '\d{5,}';
152             RETURN QUERY SELECT * FROM search.symspell_build_raw_entry(word, source_class, FALSE, prefix_length, maxED);
153         END LOOP;
154     END IF;
155
156     IF old_input IS NOT NULL THEN
157         input := evergreen.lowercase(old_input);
158
159         FOR word IN SELECT x FROM search.symspell_parse_words_distinct(input) x LOOP
160             -- similarly skip words that have 5 or more digits here to
161             -- avoid adding erroneous prefix deletion entries to the dictionary
162             CONTINUE WHEN CHARACTER_LENGTH(word) > 4 AND word ~ '\d{5,}';
163             entry.prefix_key := word;
164
165             entry.keyword_count := 0;
166             entry.title_count := 0;
167             entry.author_count := 0;
168             entry.subject_count := 0;
169             entry.series_count := 0;
170             entry.identifier_count := 0;
171
172             entry.keyword_suggestions := '{}';
173             entry.title_suggestions := '{}';
174             entry.author_suggestions := '{}';
175             entry.subject_suggestions := '{}';
176             entry.series_suggestions := '{}';
177             entry.identifier_suggestions := '{}';
178
179             IF source_class = 'keyword' THEN entry.keyword_count := -1; END IF;
180             IF source_class = 'title' THEN entry.title_count := -1; END IF;
181             IF source_class = 'author' THEN entry.author_count := -1; END IF;
182             IF source_class = 'subject' THEN entry.subject_count := -1; END IF;
183             IF source_class = 'series' THEN entry.series_count := -1; END IF;
184             IF source_class = 'identifier' THEN entry.identifier_count := -1; END IF;
185
186             RETURN NEXT entry;
187         END LOOP;
188     END IF;
189 END;
190 $F$ LANGUAGE PLPGSQL;
191
192 CREATE OR REPLACE FUNCTION search.symspell_build_and_merge_entries (
193     full_input      TEXT,
194     source_class    TEXT,
195     old_input       TEXT DEFAULT NULL,
196     include_phrases BOOL DEFAULT FALSE
197 ) RETURNS SETOF search.symspell_dictionary AS $F$
198 DECLARE
199     new_entry       RECORD;
200     conflict_entry  RECORD;
201 BEGIN
202
203     IF full_input = old_input THEN -- neither NULL, and are the same
204         RETURN;
205     END IF;
206
207     FOR new_entry IN EXECUTE $q$
208         SELECT  count,
209                 prefix_key,
210                 s AS suggestions
211           FROM  (SELECT prefix_key,
212                         ARRAY_AGG(DISTINCT $q$ || source_class || $q$_suggestions[1]) s,
213                         SUM($q$ || source_class || $q$_count) count
214                   FROM  search.symspell_build_entries($1, $2, $3, $4)
215                   GROUP BY 1) x
216         $q$ USING full_input, source_class, old_input, include_phrases
217     LOOP
218         EXECUTE $q$
219             SELECT  prefix_key,
220                     $q$ || source_class || $q$_suggestions suggestions,
221                     $q$ || source_class || $q$_count count
222               FROM  search.symspell_dictionary
223               WHERE prefix_key = $1 $q$
224             INTO conflict_entry
225             USING new_entry.prefix_key;
226
227         IF new_entry.count <> 0 THEN -- Real word, and count changed
228             IF conflict_entry.prefix_key IS NOT NULL THEN -- we'll be updating
229                 IF conflict_entry.count > 0 THEN -- it's a real word
230                     RETURN QUERY EXECUTE $q$
231                         UPDATE  search.symspell_dictionary
232                            SET  $q$ || source_class || $q$_count = $2
233                           WHERE prefix_key = $1
234                           RETURNING * $q$
235                         USING new_entry.prefix_key, GREATEST(0, new_entry.count + conflict_entry.count);
236                 ELSE -- it was a prefix key or delete-emptied word before
237                     IF conflict_entry.suggestions @> new_entry.suggestions THEN -- already have all suggestions here...
238                         RETURN QUERY EXECUTE $q$
239                             UPDATE  search.symspell_dictionary
240                                SET  $q$ || source_class || $q$_count = $2
241                               WHERE prefix_key = $1
242                               RETURNING * $q$
243                             USING new_entry.prefix_key, GREATEST(0, new_entry.count);
244                     ELSE -- new suggestion!
245                         RETURN QUERY EXECUTE $q$
246                             UPDATE  search.symspell_dictionary
247                                SET  $q$ || source_class || $q$_count = $2,
248                                     $q$ || source_class || $q$_suggestions = $3
249                               WHERE prefix_key = $1
250                               RETURNING * $q$
251                             USING new_entry.prefix_key, GREATEST(0, new_entry.count), evergreen.text_array_merge_unique(conflict_entry.suggestions,new_entry.suggestions);
252                     END IF;
253                 END IF;
254             ELSE
255                 -- We keep the on-conflict clause just in case...
256                 RETURN QUERY EXECUTE $q$
257                     INSERT INTO search.symspell_dictionary AS d (
258                         $q$ || source_class || $q$_count,
259                         prefix_key,
260                         $q$ || source_class || $q$_suggestions
261                     ) VALUES ( $1, $2, $3 ) ON CONFLICT (prefix_key) DO
262                         UPDATE SET  $q$ || source_class || $q$_count = d.$q$ || source_class || $q$_count + EXCLUDED.$q$ || source_class || $q$_count,
263                                     $q$ || source_class || $q$_suggestions = evergreen.text_array_merge_unique(d.$q$ || source_class || $q$_suggestions, EXCLUDED.$q$ || source_class || $q$_suggestions)
264                         RETURNING * $q$
265                     USING new_entry.count, new_entry.prefix_key, new_entry.suggestions;
266             END IF;
267         ELSE -- key only, or no change
268             IF conflict_entry.prefix_key IS NOT NULL THEN -- we'll be updating
269                 IF NOT conflict_entry.suggestions @> new_entry.suggestions THEN -- There are new suggestions
270                     RETURN QUERY EXECUTE $q$
271                         UPDATE  search.symspell_dictionary
272                            SET  $q$ || source_class || $q$_suggestions = $2
273                           WHERE prefix_key = $1
274                           RETURNING * $q$
275                         USING new_entry.prefix_key, evergreen.text_array_merge_unique(conflict_entry.suggestions,new_entry.suggestions);
276                 END IF;
277             ELSE
278                 RETURN QUERY EXECUTE $q$
279                     INSERT INTO search.symspell_dictionary AS d (
280                         $q$ || source_class || $q$_count,
281                         prefix_key,
282                         $q$ || source_class || $q$_suggestions
283                     ) VALUES ( $1, $2, $3 ) ON CONFLICT (prefix_key) DO -- key exists, suggestions may be added due to this entry
284                         UPDATE SET  $q$ || source_class || $q$_suggestions = evergreen.text_array_merge_unique(d.$q$ || source_class || $q$_suggestions, EXCLUDED.$q$ || source_class || $q$_suggestions)
285                     RETURNING * $q$
286                     USING new_entry.count, new_entry.prefix_key, new_entry.suggestions;
287             END IF;
288         END IF;
289     END LOOP;
290 END;
291 $F$ LANGUAGE PLPGSQL;
292
293
294 \qecho ''
295 \qecho 'The following should be run at the end of the upgrade before any'
296 \qecho 'reingest occurs.  Because new triggers are installed already,'
297 \qecho 'updates to indexed strings will cause zero-count dictionary entries'
298 \qecho 'to be recorded which will require updating every row again (or'
299 \qecho 'starting from scratch) so best to do this before other batch'
300 \qecho 'changes.  A later reingest that does not significantly change'
301 \qecho 'indexed strings will /not/ cause table bloat here, and will be'
302 \qecho 'as fast as normal.  A copy of the SQL in a ready-to-use, non-escaped'
303 \qecho 'form is available inside a comment at the end of this upgrade sub-'
304 \qecho 'script so you do not need to copy this comment from the psql ouptut.'
305 \qecho ''
306 \qecho '\\a'
307 \qecho '\\t'
308 \qecho ''
309 \qecho '\\o title'
310 \qecho 'select value from metabib.title_field_entry where source in (select id from biblio.record_entry where not deleted);'
311 \qecho '\\o author'
312 \qecho 'select value from metabib.author_field_entry where source in (select id from biblio.record_entry where not deleted);'
313 \qecho '\\o subject'
314 \qecho 'select value from metabib.subject_field_entry where source in (select id from biblio.record_entry where not deleted);'
315 \qecho '\\o series'
316 \qecho 'select value from metabib.series_field_entry where source in (select id from biblio.record_entry where not deleted);'
317 \qecho '\\o identifier'
318 \qecho 'select value from metabib.identifier_field_entry where source in (select id from biblio.record_entry where not deleted);'
319 \qecho '\\o keyword'
320 \qecho 'select value from metabib.keyword_field_entry where source in (select id from biblio.record_entry where not deleted);'
321 \qecho ''
322 \qecho '\\o'
323 \qecho '\\a'
324 \qecho '\\t'
325 \qecho ''
326 \qecho '// Then, at the command line:'
327 \qecho ''
328 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl title > title.sql'
329 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl author > author.sql'
330 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl subject > subject.sql'
331 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl series > series.sql'
332 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl identifier > identifier.sql'
333 \qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl keyword > keyword.sql'
334 \qecho ''
335 \qecho '// And, back in psql'
336 \qecho ''
337 \qecho 'ALTER TABLE search.symspell_dictionary SET UNLOGGED;'
338 \qecho 'TRUNCATE search.symspell_dictionary;'
339 \qecho ''
340 \qecho '\\i identifier.sql'
341 \qecho '\\i author.sql'
342 \qecho '\\i title.sql'
343 \qecho '\\i subject.sql'
344 \qecho '\\i series.sql'
345 \qecho '\\i keyword.sql'
346 \qecho ''
347 \qecho 'CLUSTER search.symspell_dictionary USING symspell_dictionary_pkey;'
348 \qecho 'REINDEX TABLE search.symspell_dictionary;'
349 \qecho 'ALTER TABLE search.symspell_dictionary SET LOGGED;'
350 \qecho 'VACUUM ANALYZE search.symspell_dictionary;'
351 \qecho ''
352 \qecho 'DROP TABLE search.symspell_dictionary_partial_title;'
353 \qecho 'DROP TABLE search.symspell_dictionary_partial_author;'
354 \qecho 'DROP TABLE search.symspell_dictionary_partial_subject;'
355 \qecho 'DROP TABLE search.symspell_dictionary_partial_series;'
356 \qecho 'DROP TABLE search.symspell_dictionary_partial_identifier;'
357 \qecho 'DROP TABLE search.symspell_dictionary_partial_keyword;'
358
359 /* To run by hand:
360
361 \a
362 \t
363
364 \o title
365 select value from metabib.title_field_entry where source in (select id from biblio.record_entry where not deleted);
366
367 \o author
368 select value from metabib.author_field_entry where source in (select id from biblio.record_entry where not deleted);
369
370 \o subject
371 select value from metabib.subject_field_entry where source in (select id from biblio.record_entry where not deleted);
372
373 \o series
374 select value from metabib.series_field_entry where source in (select id from biblio.record_entry where not deleted);
375
376 \o identifier
377 select value from metabib.identifier_field_entry where source in (select id from biblio.record_entry where not deleted);
378
379 \o keyword
380 select value from metabib.keyword_field_entry where source in (select id from biblio.record_entry where not deleted);
381
382 \o
383 \a
384 \t
385
386 // Then, at the command line:
387
388 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl title > title.sql
389 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl author > author.sql
390 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl subject > subject.sql
391 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl series > series.sql
392 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl identifier > identifier.sql
393 $ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl keyword > keyword.sql
394
395 // To the extent your hardware allows, the above commands can be run in 
396 // in parallel, in different shells.  Each will use a full CPU, and RAM
397 // may be a limiting resource, so keep an eye on that with `top`.
398
399
400 // And, back in psql
401
402 ALTER TABLE search.symspell_dictionary SET UNLOGGED;
403 TRUNCATE search.symspell_dictionary;
404
405 \i identifier.sql
406 \i author.sql
407 \i title.sql
408 \i subject.sql
409 \i series.sql
410 \i keyword.sql
411
412 CLUSTER search.symspell_dictionary USING symspell_dictionary_pkey;
413 REINDEX TABLE search.symspell_dictionary;
414 ALTER TABLE search.symspell_dictionary SET LOGGED;
415 VACUUM ANALYZE search.symspell_dictionary;
416
417 DROP TABLE search.symspell_dictionary_partial_title;
418 DROP TABLE search.symspell_dictionary_partial_author;
419 DROP TABLE search.symspell_dictionary_partial_subject;
420 DROP TABLE search.symspell_dictionary_partial_series;
421 DROP TABLE search.symspell_dictionary_partial_identifier;
422 DROP TABLE search.symspell_dictionary_partial_keyword;
423
424 */
425
426
427 SELECT evergreen.upgrade_deps_block_check('1309', :eg_version);
428
429 ALTER TABLE asset.course_module_term
430         DROP CONSTRAINT course_module_term_name_key;
431
432 ALTER TABLE asset.course_module_term
433         ADD CONSTRAINT cmt_once_per_owning_lib UNIQUE (owning_lib, name);
434
435
436 SELECT evergreen.upgrade_deps_block_check('1311', :eg_version);
437
438 CREATE OR REPLACE FUNCTION biblio.extract_located_uris( bib_id BIGINT, marcxml TEXT, editor_id INT ) RETURNS VOID AS $func$
439 DECLARE
440     uris            TEXT[];
441     uri_xml         TEXT;
442     uri_label       TEXT;
443     uri_href        TEXT;
444     uri_use         TEXT;
445     uri_owner_list  TEXT[];
446     uri_owner       TEXT;
447     uri_owner_id    INT;
448     uri_id          INT;
449     uri_cn_id       INT;
450     uri_map_id      INT;
451     current_uri     INT;
452     current_map     INT;
453     uri_map_count   INT;
454     current_uri_map_list    INT[];
455     current_map_owner_list  INT[];
456
457 BEGIN
458
459     uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
460     IF ARRAY_UPPER(uris,1) > 0 THEN
461         FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
462             -- First we pull info out of the 856
463             uri_xml     := uris[i];
464
465             uri_href    := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
466             uri_label   := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
467             uri_use     := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
468
469             IF uri_label IS NULL THEN
470                 uri_label := uri_href;
471             END IF;
472             CONTINUE WHEN uri_href IS NULL;
473
474             -- Get the distinct list of libraries wanting to use 
475             SELECT  ARRAY_AGG(
476                         DISTINCT REGEXP_REPLACE(
477                             x,
478                             $re$^.*?\((\w+)\).*$$re$,
479                             E'\\1'
480                         )
481                     ) INTO uri_owner_list
482               FROM  UNNEST(
483                         oils_xpath(
484                             '//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
485                             uri_xml
486                         )
487                     )x;
488
489             IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
490
491                 -- look for a matching uri
492                 IF uri_use IS NULL THEN
493                     SELECT id INTO uri_id
494                         FROM asset.uri
495                         WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
496                         ORDER BY id LIMIT 1;
497                     IF NOT FOUND THEN -- create one
498                         INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
499                         SELECT id INTO uri_id
500                             FROM asset.uri
501                             WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
502                     END IF;
503                 ELSE
504                     SELECT id INTO uri_id
505                         FROM asset.uri
506                         WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
507                         ORDER BY id LIMIT 1;
508                     IF NOT FOUND THEN -- create one
509                         INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
510                         SELECT id INTO uri_id
511                             FROM asset.uri
512                             WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
513                     END IF;
514                 END IF;
515
516                 FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
517                     uri_owner := uri_owner_list[j];
518
519                     SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = BTRIM(REPLACE(uri_owner,chr(160),''));
520                     CONTINUE WHEN NOT FOUND;
521
522                     -- we need a call number to link through
523                     SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
524                     IF NOT FOUND THEN
525                         INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
526                             VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
527                         SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
528                     END IF;
529
530                     -- now, link them if they're not already
531                     SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
532                     IF NOT FOUND THEN
533                         INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
534                         SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
535                     END IF;
536
537                     current_uri_map_list := current_uri_map_list || uri_map_id;
538                     current_map_owner_list := current_map_owner_list || uri_cn_id;
539
540                 END LOOP;
541
542             END IF;
543
544         END LOOP;
545     END IF;
546
547     -- Clear any orphaned URIs, URI mappings and call
548     -- numbers for this bib that weren't mapped above.
549     FOR current_map IN
550         SELECT  m.id
551           FROM  asset.uri_call_number_map m
552                 LEFT JOIN asset.call_number cn ON (cn.id = m.call_number)
553           WHERE cn.record = bib_id
554                 AND cn.label = '##URI##'
555                 AND (NOT (m.id = ANY (current_uri_map_list))
556                      OR current_uri_map_list is NULL)
557     LOOP
558         SELECT uri INTO current_uri FROM asset.uri_call_number_map WHERE id = current_map;
559         DELETE FROM asset.uri_call_number_map WHERE id = current_map;
560
561         SELECT COUNT(*) INTO uri_map_count FROM asset.uri_call_number_map WHERE uri = current_uri;
562         IF uri_map_count = 0 THEN
563             DELETE FROM asset.uri WHERE id = current_uri;
564         END IF;
565     END LOOP;
566
567     UPDATE asset.call_number
568     SET deleted = TRUE, edit_date = now(), editor = editor_id
569     WHERE id IN (
570         SELECT  id
571           FROM  asset.call_number
572           WHERE record = bib_id
573                 AND label = '##URI##'
574                 AND NOT deleted
575                 AND (NOT (id = ANY (current_map_owner_list))
576                      OR current_map_owner_list is NULL)
577     );
578
579     RETURN;
580 END;
581 $func$ LANGUAGE PLPGSQL;
582
583 -- Remove existing orphaned URIs from the database.
584 DELETE FROM asset.uri
585 WHERE id IN
586 (
587 SELECT uri.id
588 FROM asset.uri
589 LEFT JOIN asset.uri_call_number_map
590 ON uri_call_number_map.uri = uri.id
591 LEFT JOIN serial.item
592 ON item.uri = uri.id
593 WHERE uri_call_number_map IS NULL
594 AND item IS NULL
595 );
596
597
598
599 SELECT evergreen.upgrade_deps_block_check('1325', :eg_version);
600
601 UPDATE config.xml_transform SET xslt=$XSLT$<?xml version="1.0" encoding="UTF-8"?>
602 <xsl:stylesheet version="1.0" xmlns:mads="http://www.loc.gov/mads/v2"
603         xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim"
604         xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
605         <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
606         <xsl:strip-space elements="*"/>
607
608         <xsl:variable name="ascii">
609                 <xsl:text> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
610         </xsl:variable>
611
612         <xsl:variable name="latin1">
613                 <xsl:text> ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
614         </xsl:variable>
615         <!-- Characters that usually don't need to be escaped -->
616         <xsl:variable name="safe">
617                 <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
618         </xsl:variable>
619
620         <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
621
622
623         <xsl:template name="datafield">
624                 <xsl:param name="tag"/>
625                 <xsl:param name="ind1">
626                         <xsl:text> </xsl:text>
627                 </xsl:param>
628                 <xsl:param name="ind2">
629                         <xsl:text> </xsl:text>
630                 </xsl:param>
631                 <xsl:param name="subfields"/>
632                 <xsl:element name="marc:datafield">
633                         <xsl:attribute name="tag">
634                                 <xsl:value-of select="$tag"/>
635                         </xsl:attribute>
636                         <xsl:attribute name="ind1">
637                                 <xsl:value-of select="$ind1"/>
638                         </xsl:attribute>
639                         <xsl:attribute name="ind2">
640                                 <xsl:value-of select="$ind2"/>
641                         </xsl:attribute>
642                         <xsl:copy-of select="$subfields"/>
643                 </xsl:element>
644         </xsl:template>
645
646         <xsl:template name="subfieldSelect">
647                 <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
648                 <xsl:param name="delimeter">
649                         <xsl:text> </xsl:text>
650                 </xsl:param>
651                 <xsl:variable name="str">
652                         <xsl:for-each select="marc:subfield">
653                                 <xsl:if test="contains($codes, @code)">
654                                         <xsl:value-of select="text()"/>
655                                         <xsl:value-of select="$delimeter"/>
656                                 </xsl:if>
657                         </xsl:for-each>
658                 </xsl:variable>
659                 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
660         </xsl:template>
661
662         <xsl:template name="buildSpaces">
663                 <xsl:param name="spaces"/>
664                 <xsl:param name="char">
665                         <xsl:text> </xsl:text>
666                 </xsl:param>
667                 <xsl:if test="$spaces>0">
668                         <xsl:value-of select="$char"/>
669                         <xsl:call-template name="buildSpaces">
670                                 <xsl:with-param name="spaces" select="$spaces - 1"/>
671                                 <xsl:with-param name="char" select="$char"/>
672                         </xsl:call-template>
673                 </xsl:if>
674         </xsl:template>
675
676         <xsl:template name="chopPunctuation">
677                 <xsl:param name="chopString"/>
678                 <xsl:param name="punctuation">
679                         <xsl:text>.:,;/ </xsl:text>
680                 </xsl:param>
681                 <xsl:variable name="length" select="string-length($chopString)"/>
682                 <xsl:choose>
683                         <xsl:when test="$length=0"/>
684                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
685                                 <xsl:call-template name="chopPunctuation">
686                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
687                                         <xsl:with-param name="punctuation" select="$punctuation"/>
688                                 </xsl:call-template>
689                         </xsl:when>
690                         <xsl:when test="not($chopString)"/>
691                         <xsl:otherwise>
692                                 <xsl:value-of select="$chopString"/>
693                         </xsl:otherwise>
694                 </xsl:choose>
695         </xsl:template>
696
697         <xsl:template name="chopPunctuationFront">
698                 <xsl:param name="chopString"/>
699                 <xsl:variable name="length" select="string-length($chopString)"/>
700                 <xsl:choose>
701                         <xsl:when test="$length=0"/>
702                         <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
703                                 <xsl:call-template name="chopPunctuationFront">
704                                         <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
705                                         />
706                                 </xsl:call-template>
707                         </xsl:when>
708                         <xsl:when test="not($chopString)"/>
709                         <xsl:otherwise>
710                                 <xsl:value-of select="$chopString"/>
711                         </xsl:otherwise>
712                 </xsl:choose>
713         </xsl:template>
714
715         <xsl:template name="chopPunctuationBack">
716                 <xsl:param name="chopString"/>
717                 <xsl:param name="punctuation">
718                         <xsl:text>.:,;/] </xsl:text>
719                 </xsl:param>
720                 <xsl:variable name="length" select="string-length($chopString)"/>
721                 <xsl:choose>
722                         <xsl:when test="$length=0"/>
723                         <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
724                                 <xsl:call-template name="chopPunctuation">
725                                         <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
726                                         <xsl:with-param name="punctuation" select="$punctuation"/>
727                                 </xsl:call-template>
728                         </xsl:when>
729                         <xsl:when test="not($chopString)"/>
730                         <xsl:otherwise>
731                                 <xsl:value-of select="$chopString"/>
732                         </xsl:otherwise>
733                 </xsl:choose>
734         </xsl:template>
735
736         <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
737         <xsl:template name="url-encode">
738
739                 <xsl:param name="str"/>
740
741                 <xsl:if test="$str">
742                         <xsl:variable name="first-char" select="substring($str,1,1)"/>
743                         <xsl:choose>
744                                 <xsl:when test="contains($safe,$first-char)">
745                                         <xsl:value-of select="$first-char"/>
746                                 </xsl:when>
747                                 <xsl:otherwise>
748                                         <xsl:variable name="codepoint">
749                                                 <xsl:choose>
750                                                         <xsl:when test="contains($ascii,$first-char)">
751                                                                 <xsl:value-of
752                                                                         select="string-length(substring-before($ascii,$first-char)) + 32"
753                                                                 />
754                                                         </xsl:when>
755                                                         <xsl:when test="contains($latin1,$first-char)">
756                                                                 <xsl:value-of
757                                                                         select="string-length(substring-before($latin1,$first-char)) + 160"/>
758                                                                 <!-- was 160 -->
759                                                         </xsl:when>
760                                                         <xsl:otherwise>
761                                                                 <xsl:message terminate="no">Warning: string contains a character
762                                                                         that is out of range! Substituting "?".</xsl:message>
763                                                                 <xsl:text>63</xsl:text>
764                                                         </xsl:otherwise>
765                                                 </xsl:choose>
766                                         </xsl:variable>
767                                         <xsl:variable name="hex-digit1"
768                                                 select="substring($hex,floor($codepoint div 16) + 1,1)"/>
769                                         <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
770                                         <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
771                                         <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
772                                 </xsl:otherwise>
773                         </xsl:choose>
774                         <xsl:if test="string-length($str) &gt; 1">
775                                 <xsl:call-template name="url-encode">
776                                         <xsl:with-param name="str" select="substring($str,2)"/>
777                                 </xsl:call-template>
778                         </xsl:if>
779                 </xsl:if>
780         </xsl:template>
781
782
783 <!--
784 2.15  reversed genre and setAuthority template order under relatedTypeAttribute                       tmee 11/13/2018
785 2.14    Fixed bug in mads:geographic attributes syntax                                      ws   05/04/2016             
786 2.13    fixed repeating <geographic>                                                                                                            tmee 01/31/2014
787 2.12    added $2 authority for <classification>                                                                                         tmee 09/18/2012
788 2.11    added delimiters between <classification> subfields                                                                     tmee 09/18/2012
789 2.10    fixed type="other" and type="otherType" for mads:related                                                        tmee 09/16/2011
790 2.09    fixed professionTerm and genreTerm empty tag error                                                                      tmee 09/16/2011
791 2.08    fixed marc:subfield @code='i' matching error                                                                            tmee 09/16/2011
792 2.07    fixed 555 duplication error                                                                                                                     tmee 08/10/2011 
793 2.06    fixed topic subfield error                                                                                                                      tmee 08/10/2011 
794 2.05    fixed title subfield error                                                                                                                      tmee 06/20/2011 
795 2.04    fixed geographicSubdivision mapping for authority element                                                       tmee 06/16/2011
796 2.03    added classification for 053, 055, 060, 065, 070, 080, 082, 083, 086, 087                       tmee 06/03/2011         
797 2.02    added descriptionStandard for 008/10                                                                                            tmee 04/27/2011
798 2.01    added extensions for 046, 336, 370, 374, 375, 376                                                                       tmee 04/08/2011
799 2.00    redefined imported MODS elements in version 1.0 to MADS elements in version 2.0         tmee 02/08/2011
800 1.08    added 372 subfields $a $s $t for <fieldOfActivity>                                                                      tmee 06/24/2010
801 1.07    removed role/roleTerm 100, 110, 111, 400, 410, 411, 500, 510, 511, 700, 710, 711        tmee 06/24/2010
802 1.06    added strip-space                                                                                                                                       tmee 06/24/2010
803 1.05    added subfield $a for 130, 430, 530                                                                                                     tmee 06/21/2010
804 1.04    fixed 550 z omission                                                                                                                            ntra 08/11/2008
805 1.03    removed duplication of 550 $a text                                                                                                      tmee 11/01/2006
806 1.02    fixed namespace references between mads and mods                                                                        ntra 10/06/2006
807 1.01    revised                                                                                                                                                         rgue/jrad 11/29/05
808 1.00    adapted from MARC21Slim2MODS3.xsl                                                                                                       ntra 07/06/05
809 -->
810
811         <!-- authority attribute defaults to 'naf' if not set using this authority parameter, for <authority> descriptors: name, titleInfo, geographic -->
812         <xsl:param name="authority"/>
813         <xsl:variable name="auth">
814                 <xsl:choose>
815                         <xsl:when test="$authority">
816                                 <xsl:value-of select="$authority"/>
817                         </xsl:when>
818                         <xsl:otherwise>naf</xsl:otherwise>
819                 </xsl:choose>
820         </xsl:variable>
821         <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
822         <xsl:variable name="controlField008-06"
823                 select="substring(descendant-or-self::marc:controlfield[@tag=008],7,1)"/>
824         <xsl:variable name="controlField008-11"
825                 select="substring(descendant-or-self::marc:controlfield[@tag=008],12,1)"/>
826         <xsl:variable name="controlField008-14"
827                 select="substring(descendant-or-self::marc:controlfield[@tag=008],15,1)"/>
828         <xsl:template match="/">
829                 <xsl:choose>
830                         <xsl:when test="descendant-or-self::marc:collection">
831                                 <mads:madsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
832                                         xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/v2/mads-2-0.xsd">
833                                         <xsl:for-each select="descendant-or-self::marc:collection/marc:record">
834                                                 <mads:mads version="2.0">
835                                                         <xsl:call-template name="marcRecord"/>
836                                                 </mads:mads>
837                                         </xsl:for-each>
838                                 </mads:madsCollection>
839                         </xsl:when>
840                         <xsl:otherwise>
841                                 <mads:mads version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
842                                         xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/mads-2-0.xsd">
843                                         <xsl:for-each select="descendant-or-self::marc:record">
844                                                 <xsl:call-template name="marcRecord"/>
845                                         </xsl:for-each>
846                                 </mads:mads>
847                         </xsl:otherwise>
848                 </xsl:choose>
849         </xsl:template>
850
851         <xsl:template name="marcRecord">
852                 <mads:authority>
853                         <!-- 2.04 -->
854                         <xsl:choose>
855                                 <xsl:when test="$controlField008-06='d'">
856                                         <xsl:attribute name="geographicSubdivision">
857                                                 <xsl:text>direct</xsl:text>
858                                         </xsl:attribute>
859                                 </xsl:when>
860                                 <xsl:when test="$controlField008-06='i'">
861                                         <xsl:attribute name="geographicSubdivision">
862                                                 <xsl:text>indirect</xsl:text>
863                                         </xsl:attribute>
864                                 </xsl:when>
865                                 <xsl:when test="$controlField008-06='n'">
866                                         <xsl:attribute name="geographicSubdivision">
867                                                 <xsl:text>not applicable</xsl:text>
868                                         </xsl:attribute>
869                                 </xsl:when>
870                         </xsl:choose>
871                         
872                         <xsl:apply-templates select="marc:datafield[100 &lt;= @tag  and @tag &lt; 200]"/>               
873                 </mads:authority>
874
875                 <!-- related -->
876                 <xsl:apply-templates
877                         select="marc:datafield[500 &lt;= @tag and @tag &lt;= 585]|marc:datafield[700 &lt;= @tag and @tag &lt;= 785]"/>
878
879                 <!-- variant -->
880                 <xsl:apply-templates select="marc:datafield[400 &lt;= @tag and @tag &lt;= 485]"/>
881
882                 <!-- notes -->
883                 <xsl:apply-templates select="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]"/>
884
885                 <!-- url -->
886                 <xsl:apply-templates select="marc:datafield[@tag=856]"/>
887                 <xsl:apply-templates select="marc:datafield[@tag=010]"/>
888                 <xsl:apply-templates select="marc:datafield[@tag=024]"/>
889                 <xsl:apply-templates select="marc:datafield[@tag=372]"/>
890                 
891                 <!-- classification -->
892                 <xsl:apply-templates select="marc:datafield[@tag=053]"/>
893                 <xsl:apply-templates select="marc:datafield[@tag=055]"/>
894                 <xsl:apply-templates select="marc:datafield[@tag=060]"/>
895                 <xsl:apply-templates select="marc:datafield[@tag=065]"/>
896                 <xsl:apply-templates select="marc:datafield[@tag=070]"/>
897                 <xsl:apply-templates select="marc:datafield[@tag=080]"/>
898                 <xsl:apply-templates select="marc:datafield[@tag=082]"/>
899                 <xsl:apply-templates select="marc:datafield[@tag=083]"/>
900                 <xsl:apply-templates select="marc:datafield[@tag=086]"/>
901                 <xsl:apply-templates select="marc:datafield[@tag=087]"/>
902
903                 <!-- affiliation-->
904                 <xsl:for-each select="marc:datafield[@tag=373]">
905                         <mads:affiliation>
906                                 <mads:position>
907                                         <xsl:value-of select="marc:subfield[@code='a']"/>
908                                 </mads:position>
909                                 <mads:dateValid point="start">
910                                         <xsl:value-of select="marc:subfield[@code='s']"/>
911                                 </mads:dateValid>
912                                 <mads:dateValid point="end">
913                                         <xsl:value-of select="marc:subfield[@code='t']"/>
914                                 </mads:dateValid>
915                         </mads:affiliation>
916                 </xsl:for-each>
917                 <xsl:for-each select="marc:datafield[@tag=371]">
918                         <mads:affiliation>
919                                 <mads:address>
920                                         <mads:street>
921                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
922                                         </mads:street>
923                                         <mads:city>
924                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
925                                         </mads:city>
926                                         <mads:state>
927                                                 <xsl:value-of select="marc:subfield[@code='c']"/>
928                                         </mads:state>
929                                         <mads:country>
930                                                 <xsl:value-of select="marc:subfield[@code='d']"/>
931                                         </mads:country>
932                                         <mads:postcode>
933                                                 <xsl:value-of select="marc:subfield[@code='e']"/>
934                                         </mads:postcode>
935                                 </mads:address>
936                                 <mads:email>
937                                         <xsl:value-of select="marc:subfield[@code='m']"/>
938                                 </mads:email>
939                         </mads:affiliation>
940                 </xsl:for-each>
941
942                 <!-- extension-->
943                 <xsl:for-each select="marc:datafield[@tag=336]">
944                         <mads:extension>
945                                 <mads:contentType>
946                                         <mads:contentType type="text">
947                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
948                                         </mads:contentType>
949                                         <mads:contentType type="code">
950                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
951                                         </mads:contentType>
952                                 </mads:contentType>
953                         </mads:extension>
954                 </xsl:for-each>
955
956                 <xsl:for-each select="marc:datafield[@tag=374]">
957                         <mads:extension>
958                                 <mads:profession>
959                                         <xsl:choose>
960                                                 <xsl:when test="marc:subfield[@code='a']">
961                                                         <mads:professionTerm>
962                                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
963                                                         </mads:professionTerm>
964                                                 </xsl:when>
965                                                 <xsl:when test="marc:subfield[@code='s']">
966                                                         <mads:dateValid point="start">
967                                                                 <xsl:value-of select="marc:subfield[@code='s']"/>
968                                                         </mads:dateValid>
969                                                 </xsl:when>
970                                                 <xsl:when test="marc:subfield[@code='t']">
971                                                         <mads:dateValid point="end">
972                                                                 <xsl:value-of select="marc:subfield[@code='t']"/>
973                                                         </mads:dateValid>
974                                                 </xsl:when>
975                                         </xsl:choose>
976                                 </mads:profession>
977                         </mads:extension>
978                 </xsl:for-each>
979                 
980                 <xsl:for-each select="marc:datafield[@tag=375]">
981                         <mads:extension>
982                                 <mads:gender>
983                                         <xsl:choose>
984                                                 <xsl:when test="marc:subfield[@code='a']">
985                                                         <mads:genderTerm>
986                                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
987                                                         </mads:genderTerm>
988                                                 </xsl:when>
989                                                 <xsl:when test="marc:subfield[@code='s']">
990                                                         <mads:dateValid point="start">
991                                                                 <xsl:value-of select="marc:subfield[@code='s']"/>
992                                                         </mads:dateValid>
993                                                 </xsl:when>
994                                                 <xsl:when test="marc:subfield[@code='t']">
995                                                         <mads:dateValid point="end">
996                                                                 <xsl:value-of select="marc:subfield[@code='t']"/>
997                                                         </mads:dateValid>
998                                                 </xsl:when>
999                                         </xsl:choose>
1000                                 </mads:gender>
1001                         </mads:extension>
1002                 </xsl:for-each>
1003
1004                 <xsl:for-each select="marc:datafield[@tag=376]">
1005                         <mads:extension>
1006                                 <mads:familyInformation>
1007                                         <mads:typeOfFamily>
1008                                                 <xsl:value-of select="marc:subfield[@code='a']"/>
1009                                         </mads:typeOfFamily>
1010                                         <mads:nameOfProminentMember>
1011                                                 <xsl:value-of select="marc:subfield[@code='b']"/>
1012                                         </mads:nameOfProminentMember>
1013                                         <mads:hereditaryTitle>
1014                                                 <xsl:value-of select="marc:subfield[@code='c']"/>
1015                                         </mads:hereditaryTitle>
1016                                         <mads:dateValid point="start">
1017                                                 <xsl:value-of select="marc:subfield[@code='s']"/>
1018                                         </mads:dateValid>
1019                                         <mads:dateValid point="end">
1020                                                 <xsl:value-of select="marc:subfield[@code='t']"/>
1021                                         </mads:dateValid>
1022                                 </mads:familyInformation>
1023                         </mads:extension>
1024                 </xsl:for-each>
1025
1026                 <mads:recordInfo>
1027                         <mads:recordOrigin>Converted from MARCXML to MADS version 2.0 (Revision 2.13)</mads:recordOrigin>
1028                         <!-- <xsl:apply-templates select="marc:datafield[@tag=024]"/> -->
1029
1030                         <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='a']"/>
1031                         <xsl:apply-templates select="marc:controlfield[@tag=005]"/>
1032                         <xsl:apply-templates select="marc:controlfield[@tag=001]"/>
1033                         <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='b']"/>
1034                         <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='e']"/>
1035                         <xsl:for-each select="marc:controlfield[@tag=008]">
1036                                 <xsl:if test="substring(.,11,1)='a'">
1037                                         <mads:descriptionStandard>
1038                                                 <xsl:text>earlier rules</xsl:text>
1039                                         </mads:descriptionStandard>
1040                                 </xsl:if>
1041                                 <xsl:if test="substring(.,11,1)='b'">
1042                                         <mads:descriptionStandard>
1043                                                 <xsl:text>aacr1</xsl:text>
1044                                         </mads:descriptionStandard>
1045                                 </xsl:if>
1046                                 <xsl:if test="substring(.,11,1)='c'">
1047                                         <mads:descriptionStandard>
1048                                                 <xsl:text>aacr2</xsl:text>
1049                                         </mads:descriptionStandard>
1050                                 </xsl:if>
1051                                 <xsl:if test="substring(.,11,1)='d'">
1052                                         <mads:descriptionStandard>
1053                                                 <xsl:text>aacr2 compatible</xsl:text>
1054                                         </mads:descriptionStandard>
1055                                 </xsl:if>
1056                                 <xsl:if test="substring(.,11,1)='z'">
1057                                         <mads:descriptionStandard>
1058                                                 <xsl:text>other rules</xsl:text>
1059                                         </mads:descriptionStandard>
1060                                 </xsl:if>
1061                         </xsl:for-each>
1062                 </mads:recordInfo>
1063         </xsl:template>
1064
1065         <!-- start of secondary templates -->
1066
1067         <!-- ======== xlink ======== -->
1068
1069         <!-- <xsl:template name="uri"> 
1070     <xsl:for-each select="marc:subfield[@code='0']">
1071       <xsl:attribute name="xlink:href">
1072         <xsl:value-of select="."/>
1073       </xsl:attribute>
1074     </xsl:for-each>
1075      </xsl:template> 
1076    -->
1077         <xsl:template match="marc:subfield[@code='i']">
1078                 <xsl:attribute name="otherType">
1079                         <xsl:value-of select="."/>
1080                 </xsl:attribute>
1081         </xsl:template>
1082
1083         <!-- No role/roleTerm mapped in MADS 06/24/2010
1084         <xsl:template name="role">
1085                 <xsl:for-each select="marc:subfield[@code='e']">
1086                         <mads:role>
1087                                 <mads:roleTerm type="text">
1088                                         <xsl:value-of select="."/>
1089                                 </mads:roleTerm>
1090                         </mads:role>
1091                 </xsl:for-each>
1092         </xsl:template>
1093 -->
1094
1095         <xsl:template name="part">
1096                 <xsl:variable name="partNumber">
1097                         <xsl:call-template name="specialSubfieldSelect">
1098                                 <xsl:with-param name="axis">n</xsl:with-param>
1099                                 <xsl:with-param name="anyCodes">n</xsl:with-param>
1100                                 <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
1101                         </xsl:call-template>
1102                 </xsl:variable>
1103                 <xsl:variable name="partName">
1104                         <xsl:call-template name="specialSubfieldSelect">
1105                                 <xsl:with-param name="axis">p</xsl:with-param>
1106                                 <xsl:with-param name="anyCodes">p</xsl:with-param>
1107                                 <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
1108                         </xsl:call-template>
1109                 </xsl:variable>
1110                 <xsl:if test="string-length(normalize-space($partNumber))">
1111                         <mads:partNumber>
1112                                 <xsl:call-template name="chopPunctuation">
1113                                         <xsl:with-param name="chopString" select="$partNumber"/>
1114                                 </xsl:call-template>
1115                         </mads:partNumber>
1116                 </xsl:if>
1117                 <xsl:if test="string-length(normalize-space($partName))">
1118                         <mads:partName>
1119                                 <xsl:call-template name="chopPunctuation">
1120                                         <xsl:with-param name="chopString" select="$partName"/>
1121                                 </xsl:call-template>
1122                         </mads:partName>
1123                 </xsl:if>
1124         </xsl:template>
1125
1126         <xsl:template name="nameABCDN">
1127                 <xsl:for-each select="marc:subfield[@code='a']">
1128                         <mads:namePart>
1129                                 <xsl:call-template name="chopPunctuation">
1130                                         <xsl:with-param name="chopString" select="."/>
1131                                 </xsl:call-template>
1132                         </mads:namePart>
1133                 </xsl:for-each>
1134                 <xsl:for-each select="marc:subfield[@code='b']">
1135                         <mads:namePart>
1136                                 <xsl:value-of select="."/>
1137                         </mads:namePart>
1138                 </xsl:for-each>
1139                 <xsl:if
1140                         test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
1141                         <mads:namePart>
1142                                 <xsl:call-template name="subfieldSelect">
1143                                         <xsl:with-param name="codes">cdn</xsl:with-param>
1144                                 </xsl:call-template>
1145                         </mads:namePart>
1146                 </xsl:if>
1147         </xsl:template>
1148
1149         <xsl:template name="nameABCDQ">
1150                 <mads:namePart>
1151                         <xsl:call-template name="chopPunctuation">
1152                                 <xsl:with-param name="chopString">
1153                                         <xsl:call-template name="subfieldSelect">
1154                                                 <xsl:with-param name="codes">aq</xsl:with-param>
1155                                         </xsl:call-template>
1156                                 </xsl:with-param>
1157                         </xsl:call-template>
1158                 </mads:namePart>
1159                 <xsl:call-template name="termsOfAddress"/>
1160                 <xsl:call-template name="nameDate"/>
1161         </xsl:template>
1162
1163         <xsl:template name="nameACDENQ">
1164                 <mads:namePart>
1165                         <xsl:call-template name="subfieldSelect">
1166                                 <xsl:with-param name="codes">acdenq</xsl:with-param>
1167                         </xsl:call-template>
1168                 </mads:namePart>
1169         </xsl:template>
1170
1171         <xsl:template name="nameDate">
1172                 <xsl:for-each select="marc:subfield[@code='d']">
1173                         <mads:namePart type="date">
1174                                 <xsl:call-template name="chopPunctuation">
1175                                         <xsl:with-param name="chopString" select="."/>
1176                                 </xsl:call-template>
1177                         </mads:namePart>
1178                 </xsl:for-each>
1179         </xsl:template>
1180
1181         <xsl:template name="specialSubfieldSelect">
1182                 <xsl:param name="anyCodes"/>
1183                 <xsl:param name="axis"/>
1184                 <xsl:param name="beforeCodes"/>
1185                 <xsl:param name="afterCodes"/>
1186                 <xsl:variable name="str">
1187                         <xsl:for-each select="marc:subfield">
1188                                 <xsl:if
1189                                         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])">
1190                                         <xsl:value-of select="text()"/>
1191                                         <xsl:text> </xsl:text>
1192                                 </xsl:if>
1193                         </xsl:for-each>
1194                 </xsl:variable>
1195                 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
1196         </xsl:template>
1197
1198         <xsl:template name="termsOfAddress">
1199                 <xsl:if test="marc:subfield[@code='b' or @code='c']">
1200                         <mads:namePart type="termsOfAddress">
1201                                 <xsl:call-template name="chopPunctuation">
1202                                         <xsl:with-param name="chopString">
1203                                                 <xsl:call-template name="subfieldSelect">
1204                                                         <xsl:with-param name="codes">bc</xsl:with-param>
1205                                                 </xsl:call-template>
1206                                         </xsl:with-param>
1207                                 </xsl:call-template>
1208                         </mads:namePart>
1209                 </xsl:if>
1210         </xsl:template>
1211
1212         <xsl:template name="displayLabel">
1213                 <xsl:if test="marc:subfield[@code='z']">
1214                         <xsl:attribute name="displayLabel">
1215                                 <xsl:value-of select="marc:subfield[@code='z']"/>
1216                         </xsl:attribute>
1217                 </xsl:if>
1218                 <xsl:if test="marc:subfield[@code='3']">
1219                         <xsl:attribute name="displayLabel">
1220                                 <xsl:value-of select="marc:subfield[@code='3']"/>
1221                         </xsl:attribute>
1222                 </xsl:if>
1223         </xsl:template>
1224
1225         <xsl:template name="isInvalid">
1226                 <xsl:if test="@code='z'">
1227                         <xsl:attribute name="invalid">yes</xsl:attribute>
1228                 </xsl:if>
1229         </xsl:template>
1230
1231         <xsl:template name="sub2Attribute">
1232                 <!-- 024 -->
1233                 <xsl:if test="../marc:subfield[@code='2']">
1234                         <xsl:attribute name="type">
1235                                 <xsl:value-of select="../marc:subfield[@code='2']"/>
1236                         </xsl:attribute>
1237                 </xsl:if>
1238         </xsl:template>
1239
1240         <xsl:template match="marc:controlfield[@tag=001]">
1241                 <mads:recordIdentifier>
1242                         <xsl:if test="../marc:controlfield[@tag=003]">
1243                                 <xsl:attribute name="source">
1244                                         <xsl:value-of select="../marc:controlfield[@tag=003]"/>
1245                                 </xsl:attribute>
1246                         </xsl:if>
1247                         <xsl:value-of select="."/>
1248                 </mads:recordIdentifier>
1249         </xsl:template>
1250
1251         <xsl:template match="marc:controlfield[@tag=005]">
1252                 <mads:recordChangeDate encoding="iso8601">
1253                         <xsl:value-of select="."/>
1254                 </mads:recordChangeDate>
1255         </xsl:template>
1256
1257         <xsl:template match="marc:controlfield[@tag=008]">
1258                 <mads:recordCreationDate encoding="marc">
1259                         <xsl:value-of select="substring(.,1,6)"/>
1260                 </mads:recordCreationDate>
1261         </xsl:template>
1262
1263         <xsl:template match="marc:datafield[@tag=010]">
1264                 <xsl:for-each select="marc:subfield">
1265                         <mads:identifier type="lccn">
1266                                 <xsl:call-template name="isInvalid"/>
1267                                 <xsl:value-of select="."/>
1268                         </mads:identifier>
1269                 </xsl:for-each>
1270         </xsl:template>
1271
1272         <xsl:template match="marc:datafield[@tag=024]">
1273                 <xsl:for-each select="marc:subfield[not(@code=2)]">
1274                         <mads:identifier>
1275                                 <xsl:call-template name="isInvalid"/>
1276                                 <xsl:call-template name="sub2Attribute"/>
1277                                 <xsl:value-of select="."/>
1278                         </mads:identifier>
1279                 </xsl:for-each>
1280         </xsl:template>
1281
1282         <!-- ========== 372 ========== -->
1283         <xsl:template match="marc:datafield[@tag=372]">
1284                 <mads:fieldOfActivity>
1285                         <xsl:call-template name="subfieldSelect">
1286                                 <xsl:with-param name="codes">a</xsl:with-param>
1287                         </xsl:call-template>
1288                         <xsl:text>-</xsl:text>
1289                         <xsl:call-template name="subfieldSelect">
1290                                 <xsl:with-param name="codes">st</xsl:with-param>
1291                         </xsl:call-template>
1292                 </mads:fieldOfActivity>
1293         </xsl:template>
1294
1295
1296         <!-- ========== 040 ========== -->
1297         <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='a']">
1298                 <mads:recordContentSource authority="marcorg">
1299                         <xsl:value-of select="."/>
1300                 </mads:recordContentSource>
1301         </xsl:template>
1302
1303         <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='b']">
1304                 <mads:languageOfCataloging>
1305                         <mads:languageTerm authority="iso639-2b" type="code">
1306                                 <xsl:value-of select="."/>
1307                         </mads:languageTerm>
1308                 </mads:languageOfCataloging>
1309         </xsl:template>
1310
1311         <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='e']">
1312                 <mads:descriptionStandard>
1313                         <xsl:value-of select="."/>
1314                 </mads:descriptionStandard>
1315         </xsl:template>
1316         
1317         <!-- ========== classification 2.03 ========== -->
1318         
1319         <xsl:template match="marc:datafield[@tag=053]">
1320                 <mads:classification>
1321                         <xsl:call-template name="subfieldSelect">
1322                                 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
1323                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1324                         </xsl:call-template>
1325                 </mads:classification>
1326         </xsl:template>
1327         
1328         <xsl:template match="marc:datafield[@tag=055]">
1329                 <mads:classification>
1330                         <xsl:call-template name="subfieldSelect">
1331                                 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
1332                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1333                         </xsl:call-template>
1334                 </mads:classification>
1335         </xsl:template>
1336         
1337         <xsl:template match="marc:datafield[@tag=060]">
1338                 <mads:classification>
1339                         <xsl:call-template name="subfieldSelect">
1340                                 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
1341                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1342                         </xsl:call-template>
1343                 </mads:classification>
1344         </xsl:template>
1345         <xsl:template match="marc:datafield[@tag=065]">
1346                 <mads:classification>
1347                         <xsl:attribute name="authority">
1348                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1349                         </xsl:attribute>
1350                         <xsl:call-template name="subfieldSelect">
1351                                 <xsl:with-param name="codes">abcdxyz</xsl:with-param>
1352                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1353                         </xsl:call-template>
1354                 </mads:classification>
1355         </xsl:template>
1356         <xsl:template match="marc:datafield[@tag=070]">
1357                 <mads:classification>
1358                         <xsl:call-template name="subfieldSelect">
1359                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1360                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1361                         </xsl:call-template>
1362                 </mads:classification>
1363         </xsl:template>
1364         <xsl:template match="marc:datafield[@tag=080]">
1365                 <mads:classification>
1366                         <xsl:attribute name="authority">
1367                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1368                         </xsl:attribute>
1369                         <xsl:call-template name="subfieldSelect">
1370                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1371                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1372                         </xsl:call-template>
1373                 </mads:classification>
1374         </xsl:template>
1375         <xsl:template match="marc:datafield[@tag=082]">
1376                 <mads:classification>
1377                         <xsl:attribute name="authority">
1378                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1379                         </xsl:attribute>
1380                         <xsl:call-template name="subfieldSelect">
1381                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1382                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1383                         </xsl:call-template>
1384                 </mads:classification>
1385         </xsl:template>
1386         <xsl:template match="marc:datafield[@tag=083]">
1387                 <mads:classification>
1388                         <xsl:attribute name="authority">
1389                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1390                         </xsl:attribute>
1391                         <xsl:call-template name="subfieldSelect">
1392                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1393                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1394                         </xsl:call-template>
1395                 </mads:classification>
1396         </xsl:template>
1397         <xsl:template match="marc:datafield[@tag=086]">
1398                 <mads:classification>
1399                         <xsl:attribute name="authority">
1400                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1401                         </xsl:attribute>
1402                         <xsl:call-template name="subfieldSelect">
1403                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1404                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1405                         </xsl:call-template>
1406                 </mads:classification>
1407         </xsl:template>
1408         <xsl:template match="marc:datafield[@tag=087]">
1409                 <mads:classification>
1410                         <xsl:attribute name="authority">
1411                                 <xsl:value-of select="marc:subfield[@code='2']"/>
1412                         </xsl:attribute>
1413                         <xsl:call-template name="subfieldSelect">
1414                                 <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
1415                                 <xsl:with-param name="delimeter">-</xsl:with-param>
1416                         </xsl:call-template>
1417                 </mads:classification>
1418         </xsl:template>
1419         
1420
1421         <!-- ========== names  ========== -->
1422         <xsl:template match="marc:datafield[@tag=100]">
1423                 <mads:name type="personal">
1424                         <xsl:call-template name="setAuthority"/>
1425                         <xsl:call-template name="nameABCDQ"/>
1426                 </mads:name>
1427                 <xsl:apply-templates select="*[marc:subfield[not(contains('abcdeq',@code))]]"/>
1428                 <xsl:call-template name="title"/>
1429                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1430         </xsl:template>
1431
1432         <xsl:template match="marc:datafield[@tag=110]">
1433                 <mads:name type="corporate">
1434                         <xsl:call-template name="setAuthority"/>
1435                         <xsl:call-template name="nameABCDN"/>
1436                 </mads:name>
1437                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1438         </xsl:template>
1439
1440         <xsl:template match="marc:datafield[@tag=111]">
1441                 <mads:name type="conference">
1442                         <xsl:call-template name="setAuthority"/>
1443                         <xsl:call-template name="nameACDENQ"/>
1444                 </mads:name>
1445                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1446         </xsl:template>
1447
1448         <xsl:template match="marc:datafield[@tag=400]">
1449                 <mads:variant>
1450                         <xsl:call-template name="variantTypeAttribute"/>
1451                         <mads:name type="personal">
1452                                 <xsl:call-template name="nameABCDQ"/>
1453                         </mads:name>
1454                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1455                         <xsl:call-template name="title"/>
1456                 </mads:variant>
1457         </xsl:template>
1458
1459         <xsl:template match="marc:datafield[@tag=410]">
1460                 <mads:variant>
1461                         <xsl:call-template name="variantTypeAttribute"/>
1462                         <mads:name type="corporate">
1463                                 <xsl:call-template name="nameABCDN"/>
1464                         </mads:name>
1465                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1466                 </mads:variant>
1467         </xsl:template>
1468
1469         <xsl:template match="marc:datafield[@tag=411]">
1470                 <mads:variant>
1471                         <xsl:call-template name="variantTypeAttribute"/>
1472                         <mads:name type="conference">
1473                                 <xsl:call-template name="nameACDENQ"/>
1474                         </mads:name>
1475                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1476                 </mads:variant>
1477         </xsl:template>
1478
1479         <xsl:template match="marc:datafield[@tag=500]|marc:datafield[@tag=700]">
1480                 <mads:related>
1481                         <xsl:call-template name="relatedTypeAttribute"/>
1482                         <!-- <xsl:call-template name="uri"/> -->
1483                         <mads:name type="personal">
1484                                 <xsl:call-template name="setAuthority"/>
1485                                 <xsl:call-template name="nameABCDQ"/>
1486                         </mads:name>
1487                         <xsl:call-template name="title"/>
1488                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1489                 </mads:related>
1490         </xsl:template>
1491
1492         <xsl:template match="marc:datafield[@tag=510]|marc:datafield[@tag=710]">
1493                 <mads:related>
1494                         <xsl:call-template name="relatedTypeAttribute"/>
1495                         <!-- <xsl:call-template name="uri"/> -->
1496                         <mads:name type="corporate">
1497                                 <xsl:call-template name="setAuthority"/>
1498                                 <xsl:call-template name="nameABCDN"/>
1499                         </mads:name>
1500                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1501                 </mads:related>
1502         </xsl:template>
1503
1504         <xsl:template match="marc:datafield[@tag=511]|marc:datafield[@tag=711]">
1505                 <mads:related>
1506                         <xsl:call-template name="relatedTypeAttribute"/>
1507                         <!-- <xsl:call-template name="uri"/> -->
1508                         <mads:name type="conference">
1509                                 <xsl:call-template name="setAuthority"/>
1510                                 <xsl:call-template name="nameACDENQ"/>
1511                         </mads:name>
1512                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1513                 </mads:related>
1514         </xsl:template>
1515
1516         <!-- ========== titles  ========== -->
1517         <xsl:template match="marc:datafield[@tag=130]">
1518                 <xsl:call-template name="uniform-title"/>
1519                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1520         </xsl:template>
1521
1522         <xsl:template match="marc:datafield[@tag=430]">
1523                 <mads:variant>
1524                         <xsl:call-template name="variantTypeAttribute"/>
1525                         <xsl:call-template name="uniform-title"/>
1526                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1527                 </mads:variant>
1528         </xsl:template>
1529
1530         <xsl:template match="marc:datafield[@tag=530]|marc:datafield[@tag=730]">
1531                 <mads:related>
1532                         <xsl:call-template name="relatedTypeAttribute"/>
1533                         <xsl:call-template name="uniform-title"/>
1534                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1535                 </mads:related>
1536         </xsl:template>
1537
1538         <xsl:template name="title">
1539                 <xsl:variable name="hasTitle">
1540                         <xsl:for-each select="marc:subfield">
1541                                 <xsl:if test="(contains('tfghklmors',@code) )">
1542                                         <xsl:value-of select="@code"/>
1543                                 </xsl:if>
1544                         </xsl:for-each>
1545                 </xsl:variable>
1546                 <xsl:if test="string-length($hasTitle) &gt; 0 ">
1547                         <mads:titleInfo>
1548                                 <xsl:call-template name="setAuthority"/>
1549                                 <mads:title>
1550                                         <xsl:variable name="str">
1551                                                 <xsl:for-each select="marc:subfield">
1552                                                         <xsl:if test="(contains('atfghklmors',@code) )">
1553                                                                 <xsl:value-of select="text()"/>
1554                                                                 <xsl:text> </xsl:text>
1555                                                         </xsl:if>
1556                                                 </xsl:for-each>
1557                                         </xsl:variable>
1558                                         <xsl:call-template name="chopPunctuation">
1559                                                 <xsl:with-param name="chopString">
1560                                                         <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
1561                                                 </xsl:with-param>
1562                                         </xsl:call-template>
1563                                 </mads:title>
1564                                 <xsl:call-template name="part"/>
1565                                 <!-- <xsl:call-template name="uri"/> -->
1566                         </mads:titleInfo>
1567                 </xsl:if>
1568         </xsl:template>
1569
1570         <xsl:template name="uniform-title">
1571                 <xsl:variable name="hasTitle">
1572                         <xsl:for-each select="marc:subfield">
1573                                 <xsl:if test="(contains('atfghklmors',@code) )">
1574                                         <xsl:value-of select="@code"/>
1575                                 </xsl:if>
1576                         </xsl:for-each>
1577                 </xsl:variable>
1578                 <xsl:if test="string-length($hasTitle) &gt; 0 ">
1579                         <mads:titleInfo>
1580                                 <xsl:call-template name="setAuthority"/>
1581                                 <mads:title>
1582                                         <xsl:variable name="str">
1583                                                 <xsl:for-each select="marc:subfield">
1584                                                         <xsl:if test="(contains('adfghklmors',@code) )">
1585                                                                 <xsl:value-of select="text()"/>
1586                                                                 <xsl:text> </xsl:text>
1587                                                         </xsl:if>
1588                                                 </xsl:for-each>
1589                                         </xsl:variable>
1590                                         <xsl:call-template name="chopPunctuation">
1591                                                 <xsl:with-param name="chopString">
1592                                                         <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
1593                                                 </xsl:with-param>
1594                                         </xsl:call-template>
1595                                 </mads:title>
1596                                 <xsl:call-template name="part"/>
1597                                 <!-- <xsl:call-template name="uri"/> -->
1598                         </mads:titleInfo>
1599                 </xsl:if>
1600         </xsl:template>
1601
1602
1603         <!-- ========== topics  ========== -->
1604         <xsl:template match="marc:subfield[@code='x']">
1605                 <mads:topic>
1606                         <xsl:call-template name="chopPunctuation">
1607                                 <xsl:with-param name="chopString">
1608                                         <xsl:value-of select="."/>
1609                                 </xsl:with-param>
1610                         </xsl:call-template>
1611                 </mads:topic>
1612         </xsl:template>
1613         
1614         <!-- 2.06 fix -->
1615         <xsl:template
1616                 match="marc:datafield[@tag=150][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=180][marc:subfield[@code='x']]">
1617                 <xsl:call-template name="topic"/>
1618                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1619         </xsl:template>
1620         <xsl:template
1621                 match="marc:datafield[@tag=450][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=480][marc:subfield[@code='x']]">
1622                 <mads:variant>
1623                         <xsl:call-template name="variantTypeAttribute"/>
1624                         <xsl:call-template name="topic"/>
1625                 </mads:variant>
1626         </xsl:template>
1627         <xsl:template
1628                 match="marc:datafield[@tag=550 or @tag=750][marc:subfield[@code='a' or @code='b']]">
1629                 <mads:related>
1630                         <xsl:call-template name="relatedTypeAttribute"/>
1631                         <!-- <xsl:call-template name="uri"/> -->
1632                         <xsl:call-template name="topic"/>
1633                         <xsl:apply-templates select="marc:subfield[@code='z']"/>
1634                 </mads:related>
1635         </xsl:template>
1636         <xsl:template name="topic">
1637                 <mads:topic>
1638                         <xsl:call-template name="setAuthority"/>
1639                         <!-- tmee2006 dedupe 550a
1640                         <xsl:if test="@tag=550 or @tag=750">
1641                                 <xsl:call-template name="subfieldSelect">
1642                                         <xsl:with-param name="codes">ab</xsl:with-param>
1643                                 </xsl:call-template>
1644                         </xsl:if>       
1645                         -->
1646                         <xsl:choose>
1647                                 <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
1648                                         <xsl:call-template name="chopPunctuation">
1649                                                 <xsl:with-param name="chopString">
1650                                                         <xsl:apply-templates select="marc:subfield[@code='x']"/>
1651                                                 </xsl:with-param>
1652                                         </xsl:call-template>
1653                                 </xsl:when>
1654                         </xsl:choose>
1655                         <xsl:call-template name="chopPunctuation">
1656                                 <xsl:with-param name="chopString">
1657                                         <xsl:choose>
1658                                                 <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
1659                                                         <xsl:apply-templates select="marc:subfield[@code='x']"/>
1660                                                 </xsl:when>
1661                                                 <xsl:otherwise>
1662                                                         <xsl:call-template name="subfieldSelect">
1663                                                                 <xsl:with-param name="codes">ab</xsl:with-param>
1664                                                         </xsl:call-template>
1665                                                 </xsl:otherwise>
1666                                         </xsl:choose>
1667                                 </xsl:with-param>
1668                         </xsl:call-template>
1669                 </mads:topic>
1670         </xsl:template>
1671
1672         <!-- ========= temporals  ========== -->
1673         <xsl:template match="marc:subfield[@code='y']">
1674                 <mads:temporal>
1675                         <xsl:call-template name="chopPunctuation">
1676                                 <xsl:with-param name="chopString">
1677                                         <xsl:value-of select="."/>
1678                                 </xsl:with-param>
1679                         </xsl:call-template>
1680                 </mads:temporal>
1681         </xsl:template>
1682         <xsl:template
1683                 match="marc:datafield[@tag=148][marc:subfield[@code='a']]|marc:datafield[@tag=182 ][marc:subfield[@code='y']]">
1684                 <xsl:call-template name="temporal"/>
1685         </xsl:template>
1686         <xsl:template
1687                 match="marc:datafield[@tag=448][marc:subfield[@code='a']]|marc:datafield[@tag=482][marc:subfield[@code='y']]">
1688                 <mads:variant>
1689                         <xsl:call-template name="variantTypeAttribute"/>
1690                         <xsl:call-template name="temporal"/>
1691                 </mads:variant>
1692         </xsl:template>
1693         <xsl:template
1694                 match="marc:datafield[@tag=548 or @tag=748][marc:subfield[@code='a']]|marc:datafield[@tag=582 or @tag=782][marc:subfield[@code='y']]">
1695                 <mads:related>
1696                         <xsl:call-template name="relatedTypeAttribute"/>
1697                         <!-- <xsl:call-template name="uri"/> -->
1698                         <xsl:call-template name="temporal"/>
1699                 </mads:related>
1700         </xsl:template>
1701         <xsl:template name="temporal">
1702                 <mads:temporal>
1703                         <xsl:call-template name="setAuthority"/>
1704                         <xsl:if test="@tag=548 or @tag=748">
1705                                 <xsl:value-of select="marc:subfield[@code='a']"/>
1706                         </xsl:if>
1707                         <xsl:call-template name="chopPunctuation">
1708                                 <xsl:with-param name="chopString">
1709                                         <xsl:choose>
1710                                                 <xsl:when test="@tag=182 or @tag=482 or @tag=582 or @tag=782">
1711                                                         <xsl:apply-templates select="marc:subfield[@code='y']"/>
1712                                                 </xsl:when>
1713                                                 <xsl:otherwise>
1714                                                         <xsl:value-of select="marc:subfield[@code='a']"/>
1715                                                 </xsl:otherwise>
1716                                         </xsl:choose>
1717                                 </xsl:with-param>
1718                         </xsl:call-template>
1719                 </mads:temporal>
1720                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1721         </xsl:template>
1722
1723         <!-- ========== genre  ========== -->
1724         <xsl:template match="marc:subfield[@code='v']">
1725                 <mads:genre>
1726                         <xsl:call-template name="chopPunctuation">
1727                                 <xsl:with-param name="chopString">
1728                                         <xsl:value-of select="."/>
1729                                 </xsl:with-param>
1730                         </xsl:call-template>
1731                 </mads:genre>
1732         </xsl:template>
1733         <xsl:template
1734                 match="marc:datafield[@tag=155][marc:subfield[@code='a']]|marc:datafield[@tag=185][marc:subfield[@code='v']]">
1735                 <xsl:call-template name="genre"/>
1736         </xsl:template>
1737         <xsl:template
1738                 match="marc:datafield[@tag=455][marc:subfield[@code='a']]|marc:datafield[@tag=485 ][marc:subfield[@code='v']]">
1739                 <mads:variant>
1740                         <xsl:call-template name="variantTypeAttribute"/>
1741                         <xsl:call-template name="genre"/>
1742                 </mads:variant>
1743         </xsl:template>
1744         <!--
1745         <xsl:template match="marc:datafield[@tag=555]">
1746                 <mads:related>
1747                         <xsl:call-template name="relatedTypeAttribute"/>
1748                         <xsl:call-template name="uri"/>
1749                         <xsl:call-template name="genre"/>
1750                 </mads:related>
1751         </xsl:template>
1752         -->
1753         <xsl:template
1754                 match="marc:datafield[@tag=555 or @tag=755][marc:subfield[@code='a']]|marc:datafield[@tag=585][marc:subfield[@code='v']]">
1755                 <mads:related>
1756                         <xsl:call-template name="relatedTypeAttribute"/>
1757                         <xsl:call-template name="genre"/>
1758                 </mads:related>
1759         </xsl:template>
1760         <xsl:template name="genre">
1761                 <mads:genre>
1762                         <xsl:if test="@tag=555">
1763                                 <xsl:value-of select="marc:subfield[@code='a']"/>
1764                         </xsl:if>
1765                         <xsl:call-template name="setAuthority"/>
1766                         <xsl:call-template name="chopPunctuation">
1767                                 <xsl:with-param name="chopString">
1768                                         <xsl:choose>
1769                                                 <!-- 2.07 fix -->
1770                                                 <xsl:when test="@tag='555'"/>
1771                                                 <xsl:when test="@tag=185 or @tag=485 or @tag=585">
1772                                                         <xsl:apply-templates select="marc:subfield[@code='v']"/>
1773                                                 </xsl:when>
1774                                                 <xsl:otherwise>
1775                                                         <xsl:value-of select="marc:subfield[@code='a']"/>
1776                                                 </xsl:otherwise>
1777                                         </xsl:choose>
1778                                 </xsl:with-param>
1779                         </xsl:call-template>
1780                 </mads:genre>
1781                 <xsl:apply-templates/>
1782         </xsl:template>
1783
1784         <!-- ========= geographic  ========== -->
1785         <xsl:template match="marc:subfield[@code='z']">
1786                 <mads:geographic>
1787                         <xsl:call-template name="chopPunctuation">
1788                                 <xsl:with-param name="chopString">
1789                                         <xsl:value-of select="."/>
1790                                 </xsl:with-param>
1791                         </xsl:call-template>
1792                 </mads:geographic>
1793         </xsl:template>
1794         <xsl:template name="geographic">
1795                 <mads:geographic>
1796                         <!-- 2.14 -->
1797                         <xsl:call-template name="setAuthority"/>
1798                         <!-- 2.13 -->
1799                         <xsl:if test="@tag=151 or @tag=551">
1800                                 <xsl:value-of select="marc:subfield[@code='a']"/>
1801                         </xsl:if>
1802                         <xsl:call-template name="chopPunctuation">
1803                                 <xsl:with-param name="chopString">
1804                                                 <xsl:if test="@tag=181 or @tag=481 or @tag=581">
1805                                                                 <xsl:apply-templates select="marc:subfield[@code='z']"/>
1806                                                 </xsl:if>
1807                                                 <!-- 2.13
1808                                                         <xsl:choose>
1809                                                 <xsl:when test="@tag=181 or @tag=481 or @tag=581">
1810                                                         <xsl:apply-templates select="marc:subfield[@code='z']"/>
1811                                                 </xsl:when>
1812                                         
1813                                                 <xsl:otherwise>
1814                                                         <xsl:value-of select="marc:subfield[@code='a']"/>
1815                                                 </xsl:otherwise>
1816                                                 </xsl:choose>
1817                                                 -->
1818                                 </xsl:with-param>
1819                         </xsl:call-template>
1820                 </mads:geographic>
1821                 <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1822         </xsl:template>
1823         <xsl:template
1824                 match="marc:datafield[@tag=151][marc:subfield[@code='a']]|marc:datafield[@tag=181][marc:subfield[@code='z']]">
1825                 <xsl:call-template name="geographic"/>
1826         </xsl:template>
1827         <xsl:template
1828                 match="marc:datafield[@tag=451][marc:subfield[@code='a']]|marc:datafield[@tag=481][marc:subfield[@code='z']]">
1829                 <mads:variant>
1830                         <xsl:call-template name="variantTypeAttribute"/>
1831                         <xsl:call-template name="geographic"/>
1832                 </mads:variant>
1833         </xsl:template>
1834         <xsl:template
1835                 match="marc:datafield[@tag=551]|marc:datafield[@tag=581][marc:subfield[@code='z']]">
1836                 <mads:related>
1837                         <xsl:call-template name="relatedTypeAttribute"/>
1838                         <!-- <xsl:call-template name="uri"/> -->
1839                         <xsl:call-template name="geographic"/>
1840                 </mads:related>
1841         </xsl:template>
1842         <xsl:template match="marc:datafield[@tag=580]">
1843                 <mads:related>
1844                         <xsl:call-template name="relatedTypeAttribute"/>
1845                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1846                 </mads:related>
1847         </xsl:template>
1848         <xsl:template
1849                 match="marc:datafield[@tag=751][marc:subfield[@code='z']]|marc:datafield[@tag=781][marc:subfield[@code='z']]">
1850                 <mads:related>
1851                         <xsl:call-template name="relatedTypeAttribute"/>
1852                         <xsl:call-template name="geographic"/>
1853                 </mads:related>
1854         </xsl:template>
1855         <xsl:template match="marc:datafield[@tag=755]">
1856                 <mads:related>
1857                         <xsl:call-template name="relatedTypeAttribute"/>
1858                         <xsl:call-template name="setAuthority"/>
1859                         <xsl:call-template name="genre"/>
1860                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1861                 </mads:related>
1862         </xsl:template>
1863         <xsl:template match="marc:datafield[@tag=780]">
1864                 <mads:related>
1865                         <xsl:call-template name="relatedTypeAttribute"/>
1866                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1867                 </mads:related>
1868         </xsl:template>
1869         <xsl:template match="marc:datafield[@tag=785]">
1870                 <mads:related>
1871                         <xsl:call-template name="relatedTypeAttribute"/>
1872                         <xsl:apply-templates select="marc:subfield[@code!='i']"/>
1873                 </mads:related>
1874         </xsl:template>
1875
1876         <!-- ========== notes  ========== -->
1877         <xsl:template match="marc:datafield[667 &lt;= @tag and @tag &lt;= 688]">
1878                 <mads:note>
1879                         <xsl:choose>
1880                                 <xsl:when test="@tag=667">
1881                                         <xsl:attribute name="type">nonpublic</xsl:attribute>
1882                                 </xsl:when>
1883                                 <xsl:when test="@tag=670">
1884                                         <xsl:attribute name="type">source</xsl:attribute>
1885                                 </xsl:when>
1886                                 <xsl:when test="@tag=675">
1887                                         <xsl:attribute name="type">notFound</xsl:attribute>
1888                                 </xsl:when>
1889                                 <xsl:when test="@tag=678">
1890                                         <xsl:attribute name="type">history</xsl:attribute>
1891                                 </xsl:when>
1892                                 <xsl:when test="@tag=681">
1893                                         <xsl:attribute name="type">subject example</xsl:attribute>
1894                                 </xsl:when>
1895                                 <xsl:when test="@tag=682">
1896                                         <xsl:attribute name="type">deleted heading information</xsl:attribute>
1897                                 </xsl:when>
1898                                 <xsl:when test="@tag=688">
1899                                         <xsl:attribute name="type">application history</xsl:attribute>
1900                                 </xsl:when>
1901                         </xsl:choose>
1902                         <xsl:call-template name="chopPunctuation">
1903                                 <xsl:with-param name="chopString">
1904                                         <xsl:choose>
1905                                                 <xsl:when test="@tag=667 or @tag=675">
1906                                                         <xsl:value-of select="marc:subfield[@code='a']"/>
1907                                                 </xsl:when>
1908                                                 <xsl:when test="@tag=670 or @tag=678">
1909                                                         <xsl:call-template name="subfieldSelect">
1910                                                                 <xsl:with-param name="codes">ab</xsl:with-param>
1911                                                         </xsl:call-template>
1912                                                 </xsl:when>
1913                                                 <xsl:when test="680 &lt;= @tag and @tag &lt;=688">
1914                                                         <xsl:call-template name="subfieldSelect">
1915                                                                 <xsl:with-param name="codes">ai</xsl:with-param>
1916                                                         </xsl:call-template>
1917                                                 </xsl:when>
1918                                         </xsl:choose>
1919                                 </xsl:with-param>
1920                         </xsl:call-template>
1921                 </mads:note>
1922         </xsl:template>
1923
1924         <!-- ========== url  ========== -->
1925         <xsl:template match="marc:datafield[@tag=856][marc:subfield[@code='u']]">
1926                 <mads:url>
1927                         <xsl:if test="marc:subfield[@code='z' or @code='3']">
1928                                 <xsl:attribute name="displayLabel">
1929                                         <xsl:call-template name="subfieldSelect">
1930                                                 <xsl:with-param name="codes">z3</xsl:with-param>
1931                                         </xsl:call-template>
1932                                 </xsl:attribute>
1933                         </xsl:if>
1934                         <xsl:value-of select="marc:subfield[@code='u']"/>
1935                 </mads:url>
1936         </xsl:template>
1937
1938         <xsl:template name="relatedTypeAttribute">
1939                 <xsl:choose>
1940                         <xsl:when
1941                                 test="@tag=500 or @tag=510 or @tag=511 or @tag=548 or @tag=550 or @tag=551 or @tag=555 or @tag=580 or @tag=581 or @tag=582 or @tag=585">
1942                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='a'">
1943                                         <xsl:attribute name="type">earlier</xsl:attribute>
1944                                 </xsl:if>
1945                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='b'">
1946                                         <xsl:attribute name="type">later</xsl:attribute>
1947                                 </xsl:if>
1948                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='t'">
1949                                         <xsl:attribute name="type">parentOrg</xsl:attribute>
1950                                 </xsl:if>
1951                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='g'">
1952                                         <xsl:attribute name="type">broader</xsl:attribute>
1953                                 </xsl:if>
1954                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='h'">
1955                                         <xsl:attribute name="type">narrower</xsl:attribute>
1956                                 </xsl:if>
1957                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='r'">
1958                                         <xsl:attribute name="type">other</xsl:attribute>
1959                                 </xsl:if>
1960                                 <xsl:if test="contains('fin|', substring(marc:subfield[@code='w'],1,1))">
1961                                         <xsl:attribute name="type">other</xsl:attribute>
1962                                 </xsl:if>
1963                         </xsl:when>
1964                         <xsl:when test="@tag=530 or @tag=730">
1965                                 <xsl:attribute name="type">other</xsl:attribute>
1966                         </xsl:when>
1967                         <xsl:otherwise>
1968                                 <!-- 7xx -->
1969                                 <xsl:attribute name="type">equivalent</xsl:attribute>
1970                         </xsl:otherwise>
1971                 </xsl:choose>
1972                 <xsl:apply-templates select="marc:subfield[@code='i']"/>
1973         </xsl:template>
1974         
1975
1976
1977         <xsl:template name="variantTypeAttribute">
1978                 <xsl:choose>
1979                         <xsl:when
1980                                 test="@tag=400 or @tag=410 or @tag=411 or @tag=451 or @tag=455 or @tag=480 or @tag=481 or @tag=482 or @tag=485">
1981                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='d'">
1982                                         <xsl:attribute name="type">acronym</xsl:attribute>
1983                                 </xsl:if>
1984                                 <xsl:if test="substring(marc:subfield[@code='w'],1,1)='n'">
1985                                         <xsl:attribute name="type">other</xsl:attribute>
1986                                 </xsl:if>
1987                                 <xsl:if test="contains('fit', substring(marc:subfield[@code='w'],1,1))">
1988                                         <xsl:attribute name="type">other</xsl:attribute>
1989                                 </xsl:if>
1990                         </xsl:when>
1991                         <xsl:otherwise>
1992                                 <!-- 430  -->
1993                                 <xsl:attribute name="type">other</xsl:attribute>
1994                         </xsl:otherwise>
1995                 </xsl:choose>
1996                 <xsl:apply-templates select="marc:subfield[@code='i']"/>
1997         </xsl:template>
1998
1999         <xsl:template name="setAuthority">
2000                 <xsl:choose>
2001                         <!-- can be called from the datafield or subfield level, so "..//@tag" means
2002                         the tag can be at the subfield's parent level or at the datafields own level -->
2003
2004                         <xsl:when
2005                                 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='a'">
2006                                 <xsl:attribute name="authority">
2007                                         <xsl:text>naf</xsl:text>
2008                                 </xsl:attribute>
2009                         </xsl:when>
2010                         <xsl:when
2011                                 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='b'">
2012                                 <xsl:attribute name="authority">
2013                                         <xsl:text>lcsh</xsl:text>
2014                                 </xsl:attribute>
2015                         </xsl:when>
2016                         <xsl:when
2017                                 test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='k'">
2018                                 <xsl:attribute name="authority">
2019                                         <xsl:text>lacnaf</xsl:text>
2020                                 </xsl:attribute>
2021                         </xsl:when>
2022                         <xsl:when
2023                                 test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='a' and $controlField008-14='b'">
2024                                 <xsl:attribute name="authority">
2025                                         <xsl:text>lcsh</xsl:text>
2026                                 </xsl:attribute>
2027                         </xsl:when>
2028                         <xsl:when
2029                                 test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='k' and $controlField008-14='b'">
2030                                 <xsl:attribute name="authority">cash</xsl:attribute>
2031                         </xsl:when>
2032                         <xsl:when
2033                                 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='a'">
2034                                 <xsl:attribute name="authority">naf</xsl:attribute>
2035                         </xsl:when>
2036                         <xsl:when
2037                                 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='b'">
2038                                 <xsl:attribute name="authority">lcsh</xsl:attribute>
2039                         </xsl:when>
2040                         <xsl:when
2041                                 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='a'">
2042                                 <xsl:attribute name="authority">
2043                                         <xsl:text>lacnaf</xsl:text>
2044                                 </xsl:attribute>
2045                         </xsl:when>
2046                         <xsl:when
2047                                 test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='b'">
2048                                 <xsl:attribute name="authority">
2049                                         <xsl:text>cash</xsl:text>
2050                                 </xsl:attribute>
2051                         </xsl:when>
2052                         <xsl:when
2053                                 test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='b'">
2054                                 <xsl:attribute name="authority">
2055                                         <xsl:text>lcshcl</xsl:text>
2056                                 </xsl:attribute>
2057                         </xsl:when>
2058                         <xsl:when
2059                                 test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='c'">
2060                                 <xsl:attribute name="authority">
2061                                         <xsl:text>nlmnaf</xsl:text>
2062                                 </xsl:attribute>
2063                         </xsl:when>
2064                         <xsl:when
2065                                 test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='d'">
2066                                 <xsl:attribute name="authority">
2067                                         <xsl:text>nalnaf</xsl:text>
2068                                 </xsl:attribute>
2069                         </xsl:when>
2070                         <xsl:when
2071                                 test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='r'">
2072                                 <xsl:attribute name="authority">
2073                                         <xsl:text>aat</xsl:text>
2074                                 </xsl:attribute>
2075                         </xsl:when>
2076                         <xsl:when
2077                                 test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='s'">
2078                                 <xsl:attribute name="authority">sears</xsl:attribute>
2079                         </xsl:when>
2080                         <xsl:when
2081                                 test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='v'">
2082                                 <xsl:attribute name="authority">rvm</xsl:attribute>
2083                         </xsl:when>
2084                         <xsl:when
2085                                 test="100 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 155 and $controlField008-11='z'">
2086                                 <xsl:attribute name="authority">
2087                                         <xsl:value-of
2088                                                 select="../marc:datafield[ancestor-or-self::marc:datafield/@tag=040]/marc:subfield[@code='f']"
2089                                         />
2090                                 </xsl:attribute>
2091                         </xsl:when>
2092                         <xsl:when
2093                                 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='a'">
2094                                 <xsl:attribute name="authority">
2095                                         <xsl:text>naf</xsl:text>
2096                                 </xsl:attribute>
2097                         </xsl:when>
2098                         <xsl:when
2099                                 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='b'">
2100                                 <xsl:attribute name="authority">
2101                                         <xsl:text>lcsh</xsl:text>
2102                                 </xsl:attribute>
2103                         </xsl:when>
2104                         <xsl:when
2105                                 test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='k' ">
2106                                 <xsl:attribute name="authority">
2107                                         <xsl:text>lacnaf</xsl:text>
2108                                 </xsl:attribute>
2109                         </xsl:when>
2110                         <xsl:when
2111                                 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
2112                                 <xsl:attribute name="authority">
2113                                         <xsl:text>lcsh</xsl:text>
2114                                 </xsl:attribute>
2115                         </xsl:when>
2116                         <xsl:when
2117                                 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
2118                                 <xsl:attribute name="authority">
2119                                         <xsl:text>lcsh</xsl:text>
2120                                 </xsl:attribute>
2121                         </xsl:when>
2122                         <xsl:when
2123                                 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='c' ">
2124                                 <xsl:attribute name="authority">
2125                                         <xsl:text>mesh</xsl:text>
2126                                 </xsl:attribute>
2127                         </xsl:when>
2128                         <xsl:when
2129                                 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='d' ">
2130                                 <xsl:attribute name="authority">
2131                                         <xsl:text>nal</xsl:text>
2132                                 </xsl:attribute>
2133                         </xsl:when>
2134                         <xsl:when
2135                                 test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150  or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='k' ">
2136                                 <xsl:attribute name="authority">
2137                                         <xsl:text>cash</xsl:text>
2138                                 </xsl:attribute>
2139                         </xsl:when>
2140                         <xsl:when
2141                                 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='a'">
2142                                 <xsl:attribute name="authority">
2143                                         <xsl:text>naf</xsl:text>
2144                                 </xsl:attribute>
2145                         </xsl:when>
2146                         <xsl:when
2147                                 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='b'">
2148                                 <xsl:attribute name="authority">lcsh</xsl:attribute>
2149                         </xsl:when>
2150                         <xsl:when
2151                                 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='a'">
2152                                 <xsl:attribute name="authority">lacnaf</xsl:attribute>
2153                         </xsl:when>
2154                         <xsl:when
2155                                 test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='b'">
2156                                 <xsl:attribute name="authority">cash</xsl:attribute>
2157                         </xsl:when>
2158                         <xsl:when
2159                                 test="(..//ancestor-or-self::marc:datafield/@tag=180 or ..//ancestor-or-self::marc:datafield/@tag=181 or ..//ancestor-or-self::marc:datafield/@tag=182 or ..//ancestor-or-self::marc:datafield/@tag=185) and $controlField008-11='a'">
2160                                 <xsl:attribute name="authority">lcsh</xsl:attribute>
2161                         </xsl:when>
2162                         <xsl:when
2163                                 test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='0'">
2164                                 <xsl:attribute name="authority">naf</xsl:attribute>
2165                         </xsl:when>
2166                         <xsl:when
2167                                 test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='5'">
2168                                 <xsl:attribute name="authority">lacnaf</xsl:attribute>
2169                         </xsl:when>
2170                         <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='0'">
2171                                 <xsl:attribute name="authority">lcsh</xsl:attribute>
2172                         </xsl:when>
2173                         <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='5'">
2174                                 <xsl:attribute name="authority">cash</xsl:attribute>
2175                         </xsl:when>
2176                         <xsl:when
2177                                 test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='1'">
2178                                 <xsl:attribute name="authority">lcshcl</xsl:attribute>
2179                         </xsl:when>
2180                         <xsl:when
2181                                 test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='2'">
2182                                 <xsl:attribute name="authority">nlmnaf</xsl:attribute>
2183                         </xsl:when>
2184                         <xsl:when
2185                                 test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='3'">
2186                                 <xsl:attribute name="authority">nalnaf</xsl:attribute>
2187                         </xsl:when>
2188                         <xsl:when
2189                                 test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='6'">
2190                                 <xsl:attribute name="authority">rvm</xsl:attribute>
2191                         </xsl:when>
2192                         <xsl:when
2193                                 test="(700 &lt;= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag &lt;= 755 ) and @ind2='7'">
2194                                 <xsl:attribute name="authority">
2195                                         <xsl:value-of select="marc:subfield[@code='2']"/>
2196                                 </xsl:attribute>
2197                         </xsl:when>
2198                         <xsl:when
2199                                 test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='5'">
2200                                 <xsl:attribute name="authority">lacnaf</xsl:attribute>
2201                         </xsl:when>
2202                         <xsl:when
2203                                 test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751)  and @ind2='0'">
2204                                 <xsl:attribute name="authority">naf</xsl:attribute>
2205                         </xsl:when>
2206                         <xsl:when
2207                                 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='0'">
2208                                 <xsl:attribute name="authority">lcsh</xsl:attribute>
2209                         </xsl:when>
2210                         <xsl:when
2211                                 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='2'">
2212                                 <xsl:attribute name="authority">mesh</xsl:attribute>
2213                         </xsl:when>
2214                         <xsl:when
2215                                 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='3'">
2216                                 <xsl:attribute name="authority">nal</xsl:attribute>
2217                         </xsl:when>
2218                         <xsl:when
2219                                 test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755)  and @ind2='5'">
2220                                 <xsl:attribute name="authority">cash</xsl:attribute>
2221                         </xsl:when>
2222                 </xsl:choose>
2223         </xsl:template>
2224         <xsl:template match="*"/>
2225 </xsl:stylesheet>$XSLT$ WHERE name = 'mads21';
2226
2227 COMMIT;
2228
2229 -- Update auditor tables to catch changes to source tables.
2230 --   Can be removed/skipped if there were no schema changes.
2231 SELECT auditor.update_auditors();