1 --Upgrade Script for 2.4.3 to 2.5.0
3 \qecho **** Libraries that upgraded or installed 2.0 before May 2011 never
4 \qecho **** got this schema, so add it first.
5 \qecho **** If this fails, don't worry, it probably won't be an issue.
10 CREATE SCHEMA staging;
12 CREATE TABLE staging.user_stage (
13 row_id BIGSERIAL PRIMARY KEY,
14 row_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
15 usrname TEXT NOT NULL,
19 ident_type INT DEFAULT 3,
20 first_given_name TEXT,
21 second_given_name TEXT,
25 home_ou INT DEFAULT 2,
27 complete BOOL DEFAULT FALSE
30 CREATE TABLE staging.card_stage ( -- for new library barcodes
31 row_id BIGSERIAL PRIMARY KEY,
32 row_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
33 usrname TEXT NOT NULL,
34 barcode TEXT NOT NULL,
35 complete BOOL DEFAULT FALSE
38 CREATE TABLE staging.mailing_address_stage (
39 row_id BIGSERIAL PRIMARY KEY,
40 row_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
41 usrname TEXT NOT NULL, -- user's SIS barcode, for linking
44 city TEXT NOT NULL DEFAULT '',
45 state TEXT NOT NULL DEFAULT 'OK',
46 country TEXT NOT NULL DEFAULT 'US',
47 post_code TEXT NOT NULL,
48 complete BOOL DEFAULT FALSE
51 CREATE TABLE staging.billing_address_stage (
52 LIKE staging.mailing_address_stage INCLUDING DEFAULTS
55 ALTER TABLE staging.billing_address_stage ADD PRIMARY KEY (row_id);
57 CREATE TABLE staging.statcat_stage (
58 row_id BIGSERIAL PRIMARY KEY,
59 row_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
60 usrname TEXT NOT NULL,
61 statcat TEXT NOT NULL, -- for things like 'Year of study'
62 value TEXT NOT NULL, -- and the value, such as 'Freshman'
63 complete BOOL DEFAULT FALSE
69 \qecho **** REAL 2.5 upgrade starting now...
71 \set eg_version '''2.5.0'''
73 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.5.0', :eg_version);
75 SELECT evergreen.upgrade_deps_block_check('0794', :eg_version);
77 INSERT INTO config.standing_penalty (id,name,label,block_list,staff_alert)
78 VALUES (5,'PATRON_EXCEEDS_LOST_COUNT',oils_i18n_gettext(5, 'Patron exceeds max lost item threshold', 'csp', 'label'),'CIRC|FULFILL|HOLD|CAPTURE|RENEW', TRUE);
80 INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (
81 'circ.tally_lost', 'circ',
84 'Include Lost circulations in lump sum tallies in Patron Display.',
89 'In the Patron Display interface, the number of total active circulations for a given patron is presented in the Summary sidebar and underneath the Items Out navigation button. This setting will include Lost circulations as counting toward these tallies.',
95 -- Function: actor.calculate_system_penalties(integer, integer)
96 -- DROP FUNCTION actor.calculate_system_penalties(integer, integer);
98 CREATE OR REPLACE FUNCTION actor.calculate_system_penalties(match_user integer, context_org integer)
99 RETURNS SETOF actor.usr_standing_penalty AS
102 user_object actor.usr%ROWTYPE;
103 new_sp_row actor.usr_standing_penalty%ROWTYPE;
104 existing_sp_row actor.usr_standing_penalty%ROWTYPE;
105 collections_fines permission.grp_penalty_threshold%ROWTYPE;
106 max_fines permission.grp_penalty_threshold%ROWTYPE;
107 max_overdue permission.grp_penalty_threshold%ROWTYPE;
108 max_items_out permission.grp_penalty_threshold%ROWTYPE;
109 max_lost permission.grp_penalty_threshold%ROWTYPE;
114 context_org_list INT[];
115 current_fines NUMERIC(8,2) := 0.0;
116 tmp_fines NUMERIC(8,2);
119 tmp_org actor.org_unit%ROWTYPE;
120 tmp_penalty config.standing_penalty%ROWTYPE;
123 SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
126 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
128 -- Fail if the user has a high fine balance
130 tmp_grp := user_object.profile;
132 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 1 AND org_unit = tmp_org.id;
134 IF max_fines.threshold IS NULL THEN
135 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
140 IF tmp_grp IS NULL THEN
145 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
149 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
153 IF max_fines.threshold IS NOT NULL THEN
157 FROM actor.usr_standing_penalty
158 WHERE usr = match_user
159 AND org_unit = max_fines.org_unit
160 AND (stop_date IS NULL or stop_date > NOW())
161 AND standing_penalty = 1;
163 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
165 SELECT SUM(f.balance_owed) INTO current_fines
166 FROM money.materialized_billable_xact_summary f
169 FROM booking.reservation r
170 WHERE r.usr = match_user
171 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
172 AND xact_finish IS NULL
176 WHERE g.usr = match_user
177 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
178 AND xact_finish IS NULL
181 FROM action.circulation circ
182 WHERE circ.usr = match_user
183 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
184 AND xact_finish IS NULL ) l USING (id);
186 IF current_fines >= max_fines.threshold THEN
187 new_sp_row.usr := match_user;
188 new_sp_row.org_unit := max_fines.org_unit;
189 new_sp_row.standing_penalty := 1;
190 RETURN NEXT new_sp_row;
194 -- Start over for max overdue
195 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
197 -- Fail if the user has too many overdue items
199 tmp_grp := user_object.profile;
202 SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 2 AND org_unit = tmp_org.id;
204 IF max_overdue.threshold IS NULL THEN
205 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
210 IF tmp_grp IS NULL THEN
215 IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
219 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
223 IF max_overdue.threshold IS NOT NULL THEN
227 FROM actor.usr_standing_penalty
228 WHERE usr = match_user
229 AND org_unit = max_overdue.org_unit
230 AND (stop_date IS NULL or stop_date > NOW())
231 AND standing_penalty = 2;
233 SELECT INTO items_overdue COUNT(*)
234 FROM action.circulation circ
235 JOIN actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
236 WHERE circ.usr = match_user
237 AND circ.checkin_time IS NULL
238 AND circ.due_date < NOW()
239 AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);
241 IF items_overdue >= max_overdue.threshold::INT THEN
242 new_sp_row.usr := match_user;
243 new_sp_row.org_unit := max_overdue.org_unit;
244 new_sp_row.standing_penalty := 2;
245 RETURN NEXT new_sp_row;
249 -- Start over for max out
250 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
252 -- Fail if the user has too many checked out items
254 tmp_grp := user_object.profile;
256 SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 3 AND org_unit = tmp_org.id;
258 IF max_items_out.threshold IS NULL THEN
259 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
264 IF tmp_grp IS NULL THEN
269 IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
273 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
277 -- Fail if the user has too many items checked out
278 IF max_items_out.threshold IS NOT NULL THEN
281 FROM actor.usr_standing_penalty
282 WHERE usr = match_user
283 AND org_unit = max_items_out.org_unit
284 AND (stop_date IS NULL or stop_date > NOW())
285 AND standing_penalty = 3;
286 SELECT INTO items_out COUNT(*)
287 FROM action.circulation circ
288 JOIN actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
289 WHERE circ.usr = match_user
290 AND circ.checkin_time IS NULL
291 AND (circ.stop_fines IN (
292 SELECT 'MAXFINES'::TEXT
294 SELECT 'LONGOVERDUE'::TEXT
300 WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.tally_lost', circ.circ_lib)) ILIKE 'true' THEN 'true'
305 SELECT 'CLAIMSRETURNED'::TEXT
309 WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.do_not_tally_claims_returned', circ.circ_lib)) ILIKE 'true' THEN 'true'
313 ) OR circ.stop_fines IS NULL)
314 AND xact_finish IS NULL;
316 IF items_out >= max_items_out.threshold::INT THEN
317 new_sp_row.usr := match_user;
318 new_sp_row.org_unit := max_items_out.org_unit;
319 new_sp_row.standing_penalty := 3;
320 RETURN NEXT new_sp_row;
324 -- Start over for max lost
325 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
327 -- Fail if the user has too many lost items
329 tmp_grp := user_object.profile;
331 SELECT * INTO max_lost FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 5 AND org_unit = tmp_org.id;
332 IF max_lost.threshold IS NULL THEN
333 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
338 IF tmp_grp IS NULL THEN
343 IF max_lost.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
347 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
351 IF max_lost.threshold IS NOT NULL THEN
354 FROM actor.usr_standing_penalty
355 WHERE usr = match_user
356 AND org_unit = max_lost.org_unit
357 AND (stop_date IS NULL or stop_date > NOW())
358 AND standing_penalty = 5;
360 SELECT INTO items_lost COUNT(*)
361 FROM action.circulation circ
362 JOIN actor.org_unit_full_path( max_lost.org_unit ) fp ON (circ.circ_lib = fp.id)
363 WHERE circ.usr = match_user
364 AND circ.checkin_time IS NULL
365 AND (circ.stop_fines = 'LOST')
366 AND xact_finish IS NULL;
368 IF items_lost >= max_lost.threshold::INT AND 0 < max_lost.threshold::INT THEN
369 new_sp_row.usr := match_user;
370 new_sp_row.org_unit := max_lost.org_unit;
371 new_sp_row.standing_penalty := 5;
372 RETURN NEXT new_sp_row;
376 -- Start over for collections warning
377 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
379 -- Fail if the user has a collections-level fine balance
381 tmp_grp := user_object.profile;
383 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id;
384 IF max_fines.threshold IS NULL THEN
385 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
390 IF tmp_grp IS NULL THEN
395 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
399 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
403 IF max_fines.threshold IS NOT NULL THEN
407 FROM actor.usr_standing_penalty
408 WHERE usr = match_user
409 AND org_unit = max_fines.org_unit
410 AND (stop_date IS NULL or stop_date > NOW())
411 AND standing_penalty = 4;
413 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
415 SELECT SUM(f.balance_owed) INTO current_fines
416 FROM money.materialized_billable_xact_summary f
419 FROM booking.reservation r
420 WHERE r.usr = match_user
421 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
422 AND r.xact_finish IS NULL
426 WHERE g.usr = match_user
427 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
428 AND g.xact_finish IS NULL
431 FROM action.circulation circ
432 WHERE circ.usr = match_user
433 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
434 AND circ.xact_finish IS NULL ) l USING (id);
436 IF current_fines >= max_fines.threshold THEN
437 new_sp_row.usr := match_user;
438 new_sp_row.org_unit := max_fines.org_unit;
439 new_sp_row.standing_penalty := 4;
440 RETURN NEXT new_sp_row;
444 -- Start over for in collections
445 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
447 -- Remove the in-collections penalty if the user has paid down enough
448 -- This penalty is different, because this code is not responsible for creating
449 -- new in-collections penalties, only for removing them
451 tmp_grp := user_object.profile;
453 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 30 AND org_unit = tmp_org.id;
455 IF max_fines.threshold IS NULL THEN
456 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
461 IF tmp_grp IS NULL THEN
466 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
470 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
474 IF max_fines.threshold IS NOT NULL THEN
476 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
478 -- first, see if the user had paid down to the threshold
479 SELECT SUM(f.balance_owed) INTO current_fines
480 FROM money.materialized_billable_xact_summary f
483 FROM booking.reservation r
484 WHERE r.usr = match_user
485 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
486 AND r.xact_finish IS NULL
490 WHERE g.usr = match_user
491 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
492 AND g.xact_finish IS NULL
495 FROM action.circulation circ
496 WHERE circ.usr = match_user
497 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
498 AND circ.xact_finish IS NULL ) l USING (id);
500 IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
501 -- patron has paid down enough
503 SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = 30;
505 IF tmp_penalty.org_depth IS NOT NULL THEN
507 -- since this code is not responsible for applying the penalty, it can't
508 -- guarantee the current context org will match the org at which the penalty
509 --- was applied. search up the org tree until we hit the configured penalty depth
510 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
511 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
513 WHILE tmp_depth >= tmp_penalty.org_depth LOOP
517 FROM actor.usr_standing_penalty
518 WHERE usr = match_user
519 AND org_unit = tmp_org.id
520 AND (stop_date IS NULL or stop_date > NOW())
521 AND standing_penalty = 30;
523 IF tmp_org.parent_ou IS NULL THEN
527 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
528 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
533 -- no penalty depth is defined, look for exact matches
537 FROM actor.usr_standing_penalty
538 WHERE usr = match_user
539 AND org_unit = max_fines.org_unit
540 AND (stop_date IS NULL or stop_date > NOW())
541 AND standing_penalty = 30;
551 LANGUAGE plpgsql VOLATILE
556 SELECT evergreen.upgrade_deps_block_check('0795', :eg_version);
558 CREATE OR REPLACE FUNCTION
559 evergreen.z3950_attr_name_is_valid(TEXT) RETURNS BOOLEAN AS $func$
560 SELECT EXISTS (SELECT 1 FROM config.z3950_attr WHERE name = $1);
561 $func$ LANGUAGE SQL STRICT IMMUTABLE;
563 COMMENT ON FUNCTION evergreen.z3950_attr_name_is_valid(TEXT) IS $$
564 Results in TRUE if there exists at least one config.z3950_attr
565 with the provided name. Used by config.z3950_index_field_map
566 to verify z3950_attr_type maps.
569 CREATE TABLE config.z3950_index_field_map (
570 id SERIAL PRIMARY KEY,
571 label TEXT NOT NULL, -- i18n
572 metabib_field INTEGER REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
573 record_attr TEXT REFERENCES config.record_attr_definition(name),
574 z3950_attr INTEGER REFERENCES config.z3950_attr(id),
575 z3950_attr_type TEXT,-- REFERENCES config.z3950_attr(name)
576 CONSTRAINT metabib_field_or_record_attr CHECK (
577 metabib_field IS NOT NULL OR
578 record_attr IS NOT NULL
580 CONSTRAINT attr_or_attr_type CHECK (
581 z3950_attr IS NOT NULL OR
582 z3950_attr_type IS NOT NULL
584 -- ensure the selected z3950_attr_type refers to a valid attr name
585 CONSTRAINT valid_z3950_attr_type CHECK (
586 z3950_attr_type IS NULL OR
587 evergreen.z3950_attr_name_is_valid(z3950_attr_type)
591 -- check whether patch can be applied
592 SELECT evergreen.upgrade_deps_block_check('0841', :eg_version);
593 SELECT evergreen.upgrade_deps_block_check('0842', :eg_version);
594 SELECT evergreen.upgrade_deps_block_check('0843', :eg_version);
596 ALTER TABLE config.metabib_field_ts_map DROP CONSTRAINT metabib_field_ts_map_metabib_field_fkey;
597 ALTER TABLE config.metabib_search_alias DROP CONSTRAINT metabib_search_alias_field_fkey;
598 ALTER TABLE metabib.browse_entry_def_map DROP CONSTRAINT browse_entry_def_map_def_fkey;
600 ALTER TABLE config.metabib_field_ts_map ADD CONSTRAINT metabib_field_ts_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
601 ALTER TABLE config.metabib_search_alias ADD CONSTRAINT metabib_search_alias_field_fkey FOREIGN KEY (field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
602 ALTER TABLE metabib.browse_entry_def_map ADD CONSTRAINT browse_entry_def_map_def_fkey FOREIGN KEY (def) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
606 DROP FUNCTION IF EXISTS config.modify_metabib_field(source INT, target INT);
607 CREATE FUNCTION config.modify_metabib_field(v_source INT, target INT) RETURNS INT AS $func$
613 SELECT field_class INTO f_class FROM config.metabib_field WHERE id = v_source;
617 IF target IS NULL THEN
618 target_id = v_source + 1000;
622 SELECT id FROM config.metabib_field INTO check_id WHERE id = target_id;
624 RAISE NOTICE 'Cannot bump config.metabib_field.id from % to %; the target ID already exists.', v_source, target_id;
627 UPDATE config.metabib_field SET id = target_id WHERE id = v_source;
628 EXECUTE ' UPDATE metabib.' || f_class || '_field_entry SET field = ' || target_id || ' WHERE field = ' || v_source;
629 UPDATE config.metabib_field_ts_map SET metabib_field = target_id WHERE metabib_field = v_source;
630 UPDATE config.metabib_field_index_norm_map SET field = target_id WHERE field = v_source;
631 UPDATE search.relevance_adjustment SET field = target_id WHERE field = v_source;
632 UPDATE config.metabib_search_alias SET field = target_id WHERE field = v_source;
633 UPDATE config.z3950_index_field_map SET metabib_field = target_id WHERE metabib_field = v_source;
634 UPDATE metabib.browse_entry_def_map SET def = target_id WHERE def = v_source;
637 $func$ LANGUAGE PLPGSQL;
639 SELECT config.modify_metabib_field(id, NULL)
640 FROM config.metabib_field
643 SELECT SETVAL('config.metabib_field_id_seq', GREATEST(1000, (SELECT MAX(id) FROM config.metabib_field)));
649 INSERT INTO config.z3950_index_field_map
650 (id, label, metabib_field, z3950_attr_type) VALUES
651 (1, oils_i18n_gettext(1, 'Title', 'czifm', 'label'), 5, 'title'),
652 (2, oils_i18n_gettext(2, 'Author', 'czifm', 'label'), 8, 'author'),
653 (3, oils_i18n_gettext(3, 'ISBN', 'czifm', 'label'), 18, 'isbn'),
654 (4, oils_i18n_gettext(4, 'ISSN', 'czifm', 'label'), 19, 'issn'),
655 (5, oils_i18n_gettext(5, 'LCCN', 'czifm', 'label'), 30, 'lccn');
657 INSERT INTO config.z3950_index_field_map
658 (id, label, record_attr, z3950_attr_type) VALUES
659 (6, oils_i18n_gettext(6, 'Pubdate', 'czifm', 'label'),'pubdate', 'pubdate'),
660 (7, oils_i18n_gettext(7, 'Item Type', 'czifm', 'label'),'item_type', 'item_type');
663 -- let's leave room for more stock mappings
664 SELECT SETVAL('config.z3950_index_field_map_id_seq'::TEXT, 1000);
666 INSERT INTO config.org_unit_setting_type
667 (name, grp, label, description, datatype)
669 'cat.z3950.batch.max_parallel',
672 'cat.z3950.batch.max_parallel',
673 'Maximum Parallel Z39.50 Batch Searches',
678 'cat.z3950.batch.max_parallel',
679 'The maximum number of Z39.50 searches that can be in-flight at any given time when performing batch Z39.50 searches',
686 INSERT INTO config.org_unit_setting_type
687 (name, grp, label, description, datatype)
689 'cat.z3950.batch.max_results',
692 'cat.z3950.batch.max_results',
693 'Maximum Z39.50 Batch Search Results',
698 'cat.z3950.batch.max_results',
699 'The maximum number of search results to retrieve and queue for each record + Z39 source during batch Z39.50 searches',
706 INSERT INTO vandelay.bib_attr_definition (id, code, description, xpath)
710 oils_i18n_gettext(16, 'Z39.50 Source', 'vqbrad', 'description'),
711 '//*[@tag="901"]/*[@code="z"]'
717 SELECT evergreen.upgrade_deps_block_check('0796', :eg_version);
719 ALTER TABLE vandelay.bib_queue ADD COLUMN match_bucket
720 INTEGER REFERENCES container.biblio_record_entry_bucket(id)
721 ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
723 CREATE OR REPLACE FUNCTION vandelay.match_bib_record() RETURNS TRIGGER AS $func$
725 incoming_existing_id TEXT;
726 test_result vandelay.match_set_test_result%ROWTYPE;
731 IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
735 DELETE FROM vandelay.bib_match WHERE queued_record = NEW.id;
737 SELECT q.match_set INTO match_set FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
739 IF match_set IS NOT NULL THEN
740 NEW.quality := vandelay.measure_record_quality( NEW.marc, match_set );
743 -- Perfect matches on 901$c exit early with a match with high quality.
744 incoming_existing_id :=
745 oils_xpath_string('//*[@tag="901"]/*[@code="c"][1]', NEW.marc);
747 IF incoming_existing_id IS NOT NULL AND incoming_existing_id != '' THEN
748 SELECT id INTO tmp_rec FROM biblio.record_entry WHERE id = incoming_existing_id::bigint;
749 IF tmp_rec IS NOT NULL THEN
750 INSERT INTO vandelay.bib_match (queued_record, eg_record, match_score, quality)
755 -- note: no match_set means quality==0
756 vandelay.measure_record_quality( b.marc, match_set )
757 FROM biblio.record_entry b
758 WHERE id = incoming_existing_id::bigint;
762 IF match_set IS NULL THEN
766 SELECT q.match_bucket INTO match_bucket FROM vandelay.bib_queue q WHERE q.id = NEW.queue;
768 FOR test_result IN SELECT * FROM
769 vandelay.match_set_test_marcxml(match_set, NEW.marc, match_bucket) LOOP
771 INSERT INTO vandelay.bib_match ( queued_record, eg_record, match_score, quality )
776 vandelay.measure_record_quality( b.marc, match_set )
777 FROM biblio.record_entry b
778 WHERE id = test_result.record;
784 $func$ LANGUAGE PLPGSQL;
787 DROP FUNCTION IF EXISTS vandelay.match_set_test_marcxml(INTEGER, TEXT);
789 CREATE OR REPLACE FUNCTION vandelay.match_set_test_marcxml(
790 match_set_id INTEGER, record_xml TEXT, bucket_id INTEGER
791 ) RETURNS SETOF vandelay.match_set_test_result AS $$
802 tags_rstore := vandelay.flatten_marc_hstore(record_xml);
803 svf_rstore := vandelay.extract_rec_attrs(record_xml);
805 CREATE TEMPORARY TABLE _vandelay_tmp_qrows (q INTEGER);
806 CREATE TEMPORARY TABLE _vandelay_tmp_jrows (j TEXT);
808 -- generate the where clause and return that directly (into wq), and as
809 -- a side-effect, populate the _vandelay_tmp_[qj]rows tables.
810 wq := vandelay.get_expr_from_match_set(match_set_id, tags_rstore);
812 query_ := 'SELECT DISTINCT(record), ';
814 -- qrows table is for the quality bits we add to the SELECT clause
815 SELECT ARRAY_TO_STRING(
816 ARRAY_ACCUM('COALESCE(n' || q::TEXT || '.quality, 0)'), ' + '
817 ) INTO coal FROM _vandelay_tmp_qrows;
819 -- our query string so far is the SELECT clause and the inital FROM.
820 -- no JOINs yet nor the WHERE clause
821 query_ := query_ || coal || ' AS quality ' || E'\n';
823 -- jrows table is for the joins we must make (and the real text conditions)
824 SELECT ARRAY_TO_STRING(ARRAY_ACCUM(j), E'\n') INTO joins
825 FROM _vandelay_tmp_jrows;
827 -- add those joins and the where clause to our query.
828 query_ := query_ || joins || E'\n';
830 -- join the record bucket
831 IF bucket_id IS NOT NULL THEN
832 query_ := query_ || 'JOIN container.biblio_record_entry_bucket_item ' ||
833 'brebi ON (brebi.target_biblio_record_entry = record ' ||
834 'AND brebi.bucket = ' || bucket_id || E')\n';
837 query_ := query_ || 'JOIN biblio.record_entry bre ON (bre.id = record) ' || 'WHERE ' || wq || ' AND not bre.deleted';
839 -- this will return rows of record,quality
840 FOR rec IN EXECUTE query_ USING tags_rstore, svf_rstore LOOP
844 DROP TABLE _vandelay_tmp_qrows;
845 DROP TABLE _vandelay_tmp_jrows;
851 SELECT evergreen.upgrade_deps_block_check('0797', :eg_version);
853 -- New global flags for the purge function
854 INSERT INTO config.global_flag (name, label, enabled)
856 'history.hold.retention_age',
857 oils_i18n_gettext('history.hold.retention_age', 'Historical Hold Retention Age', 'cgf', 'label'),
860 'history.hold.retention_age_fulfilled',
861 oils_i18n_gettext('history.hold.retention_age_fulfilled', 'Historical Hold Retention Age - Fulfilled', 'cgf', 'label'),
864 'history.hold.retention_age_canceled',
865 oils_i18n_gettext('history.hold.retention_age_canceled', 'Historical Hold Retention Age - Canceled (Default)', 'cgf', 'label'),
868 'history.hold.retention_age_canceled_1',
869 oils_i18n_gettext('history.hold.retention_age_canceled_1', 'Historical Hold Retention Age - Canceled (Untarged expiration)', 'cgf', 'label'),
872 'history.hold.retention_age_canceled_2',
873 oils_i18n_gettext('history.hold.retention_age_canceled_2', 'Historical Hold Retention Age - Canceled (Hold Shelf expiration)', 'cgf', 'label'),
876 'history.hold.retention_age_canceled_3',
877 oils_i18n_gettext('history.hold.retention_age_canceled_3', 'Historical Hold Retention Age - Canceled (Patron via phone)', 'cgf', 'label'),
880 'history.hold.retention_age_canceled_4',
881 oils_i18n_gettext('history.hold.retention_age_canceled_4', 'Historical Hold Retention Age - Canceled (Patron in person)', 'cgf', 'label'),
884 'history.hold.retention_age_canceled_5',
885 oils_i18n_gettext('history.hold.retention_age_canceled_5', 'Historical Hold Retention Age - Canceled (Staff forced)', 'cgf', 'label'),
888 'history.hold.retention_age_canceled_6',
889 oils_i18n_gettext('history.hold.retention_age_canceled_6', 'Historical Hold Retention Age - Canceled (Patron via OPAC)', 'cgf', 'label'),
893 CREATE OR REPLACE FUNCTION action.purge_holds() RETURNS INT AS $func$
901 user_start TIMESTAMPTZ;
906 SELECT INTO cgf_d value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age' AND enabled;
907 SELECT INTO cgf_f value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age_fulfilled' AND enabled;
908 SELECT INTO cgf_c value::INTERVAL FROM config.global_flag WHERE name = 'history.hold.retention_age_canceled' AND enabled;
911 rank() OVER (PARTITION BY usr ORDER BY COALESCE(fulfillment_time, cancel_time) DESC),
912 cgf_cs.value::INTERVAL as cgf_cs,
915 action.hold_request ahr
916 LEFT JOIN config.global_flag cgf_cs ON (ahr.cancel_cause IS NOT NULL AND cgf_cs.name = 'history.hold.retention_age_canceled_' || ahr.cancel_cause AND cgf_cs.enabled)
918 (fulfillment_time IS NOT NULL OR cancel_time IS NOT NULL)
920 IF prev_usr IS NULL OR prev_usr != current_hold.usr THEN
921 prev_usr := current_hold.usr;
922 SELECT INTO user_start oils_json_to_text(value)::TIMESTAMPTZ FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_start';
923 SELECT INTO user_age oils_json_to_text(value)::INTERVAL FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_age';
924 SELECT INTO user_count oils_json_to_text(value)::INT FROM actor.usr_setting WHERE usr = prev_usr AND name = 'history.hold.retention_count';
925 IF user_start IS NOT NULL THEN
926 user_age := LEAST(user_age, AGE(NOW(), user_start));
928 IF user_count IS NULL THEN
929 user_count := 1000; -- Assumption based on the user visible holds routine
932 -- Library keep age trumps user keep anything, for purposes of being able to hold on to things when staff canceled and such.
933 IF current_hold.fulfillment_time IS NOT NULL AND current_hold.fulfillment_time > NOW() - COALESCE(cgf_f, cgf_d) THEN
936 IF current_hold.cancel_time IS NOT NULL AND current_hold.cancel_time > NOW() - COALESCE(current_hold.cgf_cs, cgf_c, cgf_d) THEN
940 -- User keep age needs combining with count. If too old AND within the count, keep!
941 IF user_start IS NOT NULL AND COALESCE(current_hold.fulfillment_time, current_hold.cancel_time) > NOW() - user_age AND current_hold.rank <= user_count THEN
945 -- All checks should have passed, delete!
946 DELETE FROM action.hold_request WHERE id = current_hold.id;
947 purged_holds := purged_holds + 1;
951 $func$ LANGUAGE plpgsql;
953 CREATE OR REPLACE FUNCTION action.usr_visible_holds (usr_id INT) RETURNS SETOF action.hold_request AS $func$
955 h action.hold_request%ROWTYPE;
958 usr_view_count actor.usr_setting%ROWTYPE;
959 usr_view_age actor.usr_setting%ROWTYPE;
960 usr_view_start actor.usr_setting%ROWTYPE;
962 SELECT * INTO usr_view_count FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_count';
963 SELECT * INTO usr_view_age FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_age';
964 SELECT * INTO usr_view_start FROM actor.usr_setting WHERE usr = usr_id AND name = 'history.hold.retention_start';
968 FROM action.hold_request
970 AND fulfillment_time IS NULL
971 AND cancel_time IS NULL
972 ORDER BY request_time DESC
977 IF usr_view_start.value IS NULL THEN
981 IF usr_view_age.value IS NOT NULL THEN
982 -- User opted in and supplied a retention age
983 IF oils_json_to_text(usr_view_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ) THEN
984 view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
986 view_age := oils_json_to_text(usr_view_age.value)::INTERVAL;
990 view_age := AGE(NOW(), oils_json_to_text(usr_view_start.value)::TIMESTAMPTZ);
993 IF usr_view_count.value IS NOT NULL THEN
994 view_count := oils_json_to_text(usr_view_count.value)::INT;
999 -- show some fulfilled/canceled holds
1002 FROM action.hold_request
1004 AND ( fulfillment_time IS NOT NULL OR cancel_time IS NOT NULL )
1005 AND COALESCE(fulfillment_time, cancel_time) > NOW() - view_age
1006 ORDER BY COALESCE(fulfillment_time, cancel_time) DESC
1014 $func$ LANGUAGE PLPGSQL;
1016 CREATE TABLE action.aged_hold_request (
1018 usr_home_ou INT NOT NULL,
1019 usr_profile INT NOT NULL,
1021 staff_placed BOOLEAN NOT NULL,
1022 LIKE action.hold_request
1024 ALTER TABLE action.aged_hold_request
1025 ADD PRIMARY KEY (id),
1027 DROP COLUMN requestor,
1028 DROP COLUMN sms_carrier,
1029 ALTER COLUMN phone_notify TYPE BOOLEAN
1030 USING CASE WHEN phone_notify IS NULL OR phone_notify = '' THEN FALSE ELSE TRUE END,
1031 ALTER COLUMN sms_notify TYPE BOOLEAN
1032 USING CASE WHEN sms_notify IS NULL OR sms_notify = '' THEN FALSE ELSE TRUE END,
1033 ALTER COLUMN phone_notify SET NOT NULL,
1034 ALTER COLUMN sms_notify SET NOT NULL;
1035 CREATE INDEX aged_hold_request_target_idx ON action.aged_hold_request (target);
1036 CREATE INDEX aged_hold_request_pickup_lib_idx ON action.aged_hold_request (pickup_lib);
1037 CREATE INDEX aged_hold_request_current_copy_idx ON action.aged_hold_request (current_copy);
1038 CREATE INDEX aged_hold_request_fulfillment_staff_idx ON action.aged_hold_request ( fulfillment_staff );
1040 CREATE OR REPLACE VIEW action.all_hold_request AS
1042 COALESCE(a.post_code, b.post_code) AS usr_post_code,
1043 p.home_ou AS usr_home_ou,
1044 p.profile AS usr_profile,
1045 EXTRACT(YEAR FROM p.dob)::INT AS usr_birth_year,
1046 CAST(ahr.requestor <> ahr.usr AS BOOLEAN) AS staff_placed,
1050 ahr.fulfillment_time,
1053 ahr.prev_check_time,
1060 ahr.fulfillment_staff,
1061 ahr.fulfillment_lib,
1064 ahr.selection_depth,
1067 ahr.holdable_formats,
1069 WHEN ahr.phone_notify IS NULL THEN FALSE
1070 WHEN ahr.phone_notify = '' THEN FALSE
1072 END AS phone_notify,
1075 WHEN ahr.sms_notify IS NULL THEN FALSE
1076 WHEN ahr.sms_notify = '' THEN FALSE
1084 ahr.shelf_expire_time,
1085 ahr.current_shelf_lib
1086 FROM action.hold_request ahr
1087 JOIN actor.usr p ON (ahr.usr = p.id)
1088 LEFT JOIN actor.usr_address a ON (p.mailing_address = a.id)
1089 LEFT JOIN actor.usr_address b ON (p.billing_address = b.id)
1128 FROM action.aged_hold_request;
1130 CREATE OR REPLACE FUNCTION action.age_hold_on_delete () RETURNS TRIGGER AS $$
1133 -- Archive a copy of the old row to action.aged_hold_request
1135 INSERT INTO action.aged_hold_request
1209 FROM action.all_hold_request WHERE id = OLD.id;
1213 $$ LANGUAGE 'plpgsql';
1215 CREATE TRIGGER action_hold_request_aging_tgr
1216 BEFORE DELETE ON action.hold_request
1218 EXECUTE PROCEDURE action.age_hold_on_delete ();
1221 SELECT evergreen.upgrade_deps_block_check('0798', :eg_version);
1223 INSERT INTO config.global_flag (name, label)
1225 'history.circ.retention_uses_last_finished',
1227 'history.circ.retention_uses_last_finished',
1228 'Historical Circulations use most recent xact_finish date instead of last circ''s.',
1233 'history.circ.retention_age_is_min',
1235 'history.circ.retention_age_is_min',
1236 'Historical Circulations are kept for global retention age at a minimum, regardless of user preferences.',
1243 -- Drop old variants
1244 DROP FUNCTION IF EXISTS action.circ_chain(INTEGER);
1245 DROP FUNCTION IF EXISTS action.summarize_circ_chain(INTEGER);
1247 CREATE OR REPLACE FUNCTION action.circ_chain ( ctx_circ_id BIGINT ) RETURNS SETOF action.circulation AS $$
1249 tmp_circ action.circulation%ROWTYPE;
1250 circ_0 action.circulation%ROWTYPE;
1253 SELECT INTO tmp_circ * FROM action.circulation WHERE id = ctx_circ_id;
1255 IF tmp_circ IS NULL THEN
1256 RETURN NEXT tmp_circ;
1260 -- find the front of the chain
1262 SELECT INTO tmp_circ * FROM action.circulation WHERE id = tmp_circ.parent_circ;
1263 IF tmp_circ IS NULL THEN
1269 -- now send the circs to the caller, oldest to newest
1272 IF tmp_circ IS NULL THEN
1275 RETURN NEXT tmp_circ;
1276 SELECT INTO tmp_circ * FROM action.circulation WHERE parent_circ = tmp_circ.id;
1280 $$ LANGUAGE 'plpgsql';
1282 CREATE OR REPLACE FUNCTION action.summarize_circ_chain ( ctx_circ_id BIGINT ) RETURNS action.circ_chain_summary AS $$
1286 -- first circ in the chain
1287 circ_0 action.circulation%ROWTYPE;
1289 -- last circ in the chain
1290 circ_n action.circulation%ROWTYPE;
1292 -- circ chain under construction
1293 chain action.circ_chain_summary;
1294 tmp_circ action.circulation%ROWTYPE;
1298 chain.num_circs := 0;
1299 FOR tmp_circ IN SELECT * FROM action.circ_chain(ctx_circ_id) LOOP
1301 IF chain.num_circs = 0 THEN
1305 chain.num_circs := chain.num_circs + 1;
1309 chain.start_time := circ_0.xact_start;
1310 chain.last_stop_fines := circ_n.stop_fines;
1311 chain.last_stop_fines_time := circ_n.stop_fines_time;
1312 chain.last_checkin_time := circ_n.checkin_time;
1313 chain.last_checkin_scan_time := circ_n.checkin_scan_time;
1314 SELECT INTO chain.checkout_workstation name FROM actor.workstation WHERE id = circ_0.workstation;
1315 SELECT INTO chain.last_checkin_workstation name FROM actor.workstation WHERE id = circ_n.checkin_workstation;
1317 IF chain.num_circs > 1 THEN
1318 chain.last_renewal_time := circ_n.xact_start;
1319 SELECT INTO chain.last_renewal_workstation name FROM actor.workstation WHERE id = circ_n.workstation;
1325 $$ LANGUAGE 'plpgsql';
1327 CREATE OR REPLACE FUNCTION action.purge_circulations () RETURNS INT AS $func$
1329 usr_keep_age actor.usr_setting%ROWTYPE;
1330 usr_keep_start actor.usr_setting%ROWTYPE;
1331 org_keep_age INTERVAL;
1332 org_use_last BOOL = false;
1333 org_age_is_min BOOL = false;
1339 circ_chain_head action.circulation%ROWTYPE;
1340 circ_chain_tail action.circulation%ROWTYPE;
1345 last_finished TIMESTAMP WITH TIME ZONE;
1350 SELECT value::INTERVAL INTO org_keep_age FROM config.global_flag WHERE name = 'history.circ.retention_age' AND enabled;
1352 SELECT value::INT INTO org_keep_count FROM config.global_flag WHERE name = 'history.circ.retention_count' AND enabled;
1353 IF org_keep_count IS NULL THEN
1354 RETURN count_purged; -- Gimme a count to keep, or I keep them all, forever
1357 SELECT enabled INTO org_use_last FROM config.global_flag WHERE name = 'history.circ.retention_uses_last_finished';
1358 SELECT enabled INTO org_age_is_min FROM config.global_flag WHERE name = 'history.circ.retention_age_is_min';
1360 -- First, find copies with more than keep_count non-renewal circs
1363 COUNT(*) AS total_real_circs
1364 FROM action.circulation
1365 WHERE parent_circ IS NULL
1366 AND xact_finish IS NOT NULL
1367 GROUP BY target_copy
1368 HAVING COUNT(*) > org_keep_count
1370 -- And, for those, select circs that are finished and older than keep_age
1371 FOR circ_chain_head IN
1372 -- For reference, the subquery uses a window function to order the circs newest to oldest and number them
1373 -- The outer query then uses that information to skip the most recent set the library wants to keep
1374 -- End result is we don't care what order they come out in, as they are all potentials for deletion.
1375 SELECT ac.* FROM action.circulation ac JOIN (
1376 SELECT rank() OVER (ORDER BY xact_start DESC), ac.id
1377 FROM action.circulation ac
1378 WHERE ac.target_copy = target_acp.target_copy
1379 AND ac.parent_circ IS NULL
1380 ORDER BY ac.xact_start ) ranked USING (id)
1381 WHERE ranked.rank > org_keep_count
1384 SELECT * INTO circ_chain_tail FROM action.circ_chain(circ_chain_head.id) ORDER BY xact_start DESC LIMIT 1;
1385 SELECT COUNT(CASE WHEN xact_finish IS NULL THEN 1 ELSE NULL END), MAX(xact_finish) INTO num_incomplete, last_finished FROM action.circ_chain(circ_chain_head.id);
1386 CONTINUE WHEN circ_chain_tail.xact_finish IS NULL OR num_incomplete > 0;
1388 IF NOT org_use_last THEN
1389 last_finished := circ_chain_tail.xact_finish;
1392 -- Now get the user settings, if any, to block purging if the user wants to keep more circs
1393 usr_keep_age.value := NULL;
1394 SELECT * INTO usr_keep_age FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_age';
1396 usr_keep_start.value := NULL;
1397 SELECT * INTO usr_keep_start FROM actor.usr_setting WHERE usr = circ_chain_head.usr AND name = 'history.circ.retention_start';
1399 IF usr_keep_age.value IS NOT NULL AND usr_keep_start.value IS NOT NULL THEN
1400 IF oils_json_to_text(usr_keep_age.value)::INTERVAL > AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ) THEN
1401 keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
1403 keep_age := oils_json_to_text(usr_keep_age.value)::INTERVAL;
1405 ELSIF usr_keep_start.value IS NOT NULL THEN
1406 keep_age := AGE(NOW(), oils_json_to_text(usr_keep_start.value)::TIMESTAMPTZ);
1408 keep_age := COALESCE( org_keep_age, '2000 years'::INTERVAL );
1411 IF org_age_is_min THEN
1412 keep_age := GREATEST( keep_age, org_keep_age );
1415 CONTINUE WHEN AGE(NOW(), last_finished) < keep_age;
1417 -- We've passed the purging tests, purge the circ chain starting at the end
1418 -- A trigger should auto-purge the rest of the chain.
1419 DELETE FROM action.circulation WHERE id = circ_chain_tail.id;
1421 count_purged := count_purged + 1;
1426 return count_purged;
1428 $func$ LANGUAGE PLPGSQL;
1431 SELECT evergreen.upgrade_deps_block_check('0799', :eg_version);
1433 -- allow state to be null
1434 ALTER TABLE actor.usr_address ALTER COLUMN state DROP NOT NULL;
1437 INSERT into config.org_unit_setting_type
1438 (name, grp, label, description, datatype)
1440 'ui.patron.edit.au.state.require',
1443 'ui.patron.edit.au.state.require',
1444 'Require State field on patron registration',
1449 'ui.patron.edit.au.state.require',
1450 'The State field will be required on the patron registration screen.',
1457 INSERT into config.org_unit_setting_type
1458 (name, grp, label, description, datatype)
1460 'ui.patron.edit.au.state.show',
1463 'ui.patron.edit.au.state.show',
1464 'Show State field on patron registration',
1469 'ui.patron.edit.au.state.show',
1470 'The State field will be shown on the patron registration screen. Showing a field makes it appear with required fields even when not required. If the field is required this setting is ignored.',
1477 INSERT into config.org_unit_setting_type
1478 (name, grp, label, description, datatype)
1480 'ui.patron.edit.au.state.suggest',
1483 'ui.patron.edit.au.state.suggest',
1484 'Suggest State field on patron registration',
1489 'ui.patron.edit.au.state.suggest',
1490 'The State field will be suggested on the patron registration screen. Suggesting a field makes it appear when suggested fields are shown. If the field is shown or required this setting is ignored.',
1498 SELECT evergreen.upgrade_deps_block_check('0801', :eg_version);
1500 INSERT into config.org_unit_setting_type
1501 ( name, grp, label, description, datatype, fm_class ) VALUES
1502 ( 'ui.patron.edit.ac.barcode.regex', 'gui',
1503 oils_i18n_gettext('ui.patron.edit.ac.barcode.regex',
1504 'Regex for barcodes on patron registration',
1506 oils_i18n_gettext('ui.patron.edit.ac.barcode.regex',
1507 'The Regular Expression for validation on barcodes in patron registration.',
1508 'coust', 'description'),
1512 SELECT evergreen.upgrade_deps_block_check('0802', :eg_version);
1514 CREATE OR REPLACE FUNCTION authority.normalize_heading( marcxml TEXT, no_thesaurus BOOL ) RETURNS TEXT AS $func$
1516 acsaf authority.control_set_authority_field%ROWTYPE;
1527 auth_id INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
1529 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
1531 IF cset IS NULL THEN
1532 SELECT control_set INTO cset
1533 FROM authority.control_set_authority_field
1534 WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
1538 thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
1539 IF thes_code IS NULL THEN
1541 ELSIF thes_code = 'z' THEN
1542 thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), '' );
1546 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
1547 tag_used := acsaf.tag;
1548 nfi_used := acsaf.nfi;
1551 FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml)) LOOP
1552 FOR sf_node IN SELECT unnest(oils_xpath('//*[contains("'||acsaf.sf_list||'",@code)]',tag_node)) LOOP
1554 tmp_text := oils_xpath_string('.', sf_node);
1555 sf := oils_xpath_string('./@code', sf_node);
1557 IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
1559 tmp_text := SUBSTRING(
1564 oils_xpath_string('./@ind'||nfi_used, tag_node),
1579 IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
1580 heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
1584 EXIT WHEN heading_text <> '';
1587 EXIT WHEN heading_text <> '';
1590 IF heading_text <> '' THEN
1591 IF no_thesaurus IS TRUE THEN
1592 heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
1594 heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
1597 heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
1600 RETURN heading_text;
1602 $func$ LANGUAGE PLPGSQL IMMUTABLE;
1604 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
1606 res authority.simple_heading%ROWTYPE;
1607 acsaf authority.control_set_authority_field%ROWTYPE;
1617 auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml)::INT;
1620 res.record := auth_id;
1622 SELECT control_set INTO cset
1623 FROM authority.control_set_authority_field
1624 WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]) )
1627 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
1629 res.atag := acsaf.id;
1630 tag_used := acsaf.tag;
1631 nfi_used := acsaf.nfi;
1633 FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)) LOOP
1635 heading_text := public.naco_normalize(
1637 oils_xpath_string('//*[contains("'||acsaf.sf_list||'",@code)]',tmp_xml::TEXT, ' '),
1642 IF nfi_used IS NOT NULL THEN
1644 sort_text := SUBSTRING(
1649 oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
1661 sort_text := heading_text;
1664 IF heading_text IS NOT NULL AND heading_text <> '' THEN
1665 res.value := heading_text;
1666 res.sort_value := sort_text;
1676 $func$ LANGUAGE PLPGSQL IMMUTABLE;
1680 -- check whether patch can be applied
1681 SELECT evergreen.upgrade_deps_block_check('0805', :eg_version);
1683 INSERT INTO config.global_flag (name, label, enabled)
1685 'circ.desk_renewal.use_original_circ_lib',
1687 'circ.desk_renewal.use_original_circ_lib',
1688 'Circ: Use original circulation library on desk renewal instead of user home library',
1696 -- check whether patch can be applied
1697 SELECT evergreen.upgrade_deps_block_check('0806', :eg_version);
1699 INSERT INTO action.hold_request_cancel_cause (id,label)
1700 VALUES (7,'Patron via SIP');
1703 -- check whether patch can be applied
1704 SELECT evergreen.upgrade_deps_block_check('0807', :eg_version);
1706 ALTER TABLE config.usr_setting_type
1707 ADD COLUMN reg_default TEXT;
1710 SELECT evergreen.upgrade_deps_block_check('0809', :eg_version);
1712 ALTER TABLE actor.org_address ALTER COLUMN state DROP NOT NULL;
1715 -- Evergreen DB patch 0812.data.add_library_info_url_OUS.sql
1717 -- Adds YAOUS for enabling information links from the TPAC to a library URL
1720 -- check whether patch can be applied
1721 SELECT evergreen.upgrade_deps_block_check('0812', :eg_version);
1723 -- FIXME: add/check SQL statements to perform the upgrade
1724 INSERT into config.org_unit_setting_type
1725 ( name, grp, label, description, datatype, fm_class ) VALUES
1726 ( 'lib.info_url', 'lib',
1727 oils_i18n_gettext('lib.info_url',
1728 'Library information URL (such as "http://example.com/about.html")',
1730 oils_i18n_gettext('lib.info_url',
1731 'URL for information on this library, such as contact information, hours of operation, and directions. If set, the library name in the copy details section links to that URL. Use a complete URL, such as "http://example.com/hours.html".',
1732 'coust', 'description'),
1737 SELECT evergreen.upgrade_deps_block_check('0813', :eg_version);
1739 -- Don't require state in the auditor tracking for user addresses
1741 ALTER TABLE auditor.actor_usr_address_history ALTER COLUMN state DROP NOT NULL;
1743 -- Change constraint on actor.org_unit_setting_log to be deferrable initially
1745 ALTER TABLE config.org_unit_setting_type_log
1746 DROP CONSTRAINT org_unit_setting_type_log_field_name_fkey,
1747 ADD CONSTRAINT org_unit_setting_type_log_field_name_fkey FOREIGN KEY (field_name)
1748 REFERENCES config.org_unit_setting_type (name) MATCH SIMPLE
1749 ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;
1751 -- Fix names in the org unit setting configuration
1753 UPDATE config.org_unit_setting_type SET name = overlay(name placing 'aua' from 16 for 2) where name like 'ui.patron.edit.au.state.%';
1755 -- Fix names if they have already been set in the editor
1757 UPDATE actor.org_unit_setting SET name = overlay(name placing 'aua' from 16 for 2) where name like 'ui.patron.edit.au.state.%';
1761 UPDATE config.org_unit_setting_type_log SET field_name = overlay(field_name placing 'aua' from 16 for 2) where field_name like 'ui.patron.edit.au.state.%';
1764 SELECT evergreen.upgrade_deps_block_check('0814', :eg_version);
1766 UPDATE permission.perm_list
1767 SET description = 'Allow a user to delete a provider'
1768 WHERE code = 'DELETE_PROVIDER';
1771 -- check whether patch can be applied
1772 SELECT evergreen.upgrade_deps_block_check('0815', :eg_version);
1774 ALTER TABLE authority.control_set_authority_field
1775 ADD COLUMN linking_subfield CHAR(1);
1777 UPDATE authority.control_set_authority_field
1778 SET linking_subfield = '0' WHERE main_entry IS NOT NULL;
1780 CREATE TABLE authority.authority_linking (
1781 id BIGSERIAL PRIMARY KEY,
1782 source BIGINT REFERENCES authority.record_entry (id) NOT NULL,
1783 target BIGINT REFERENCES authority.record_entry (id) NOT NULL,
1784 field INT REFERENCES authority.control_set_authority_field (id) NOT NULL
1787 -- Given an authority record's ID, control set ID (if known), and marc::XML,
1788 -- return all links to other authority records in the form of rows that
1789 -- can be inserted into authority.authority_linking.
1790 CREATE OR REPLACE FUNCTION authority.calculate_authority_linking(
1791 rec_id BIGINT, rec_control_set INT, rec_marc_xml XML
1792 ) RETURNS SETOF authority.authority_linking AS $func$
1794 acsaf authority.control_set_authority_field%ROWTYPE;
1796 aal authority.authority_linking%ROWTYPE;
1798 IF rec_control_set IS NULL THEN
1799 -- No control_set on record? Guess at one
1800 SELECT control_set INTO rec_control_set
1801 FROM authority.control_set_authority_field
1804 XPATH('//*[starts-with(@tag,"1")]/@tag',rec_marc_xml::XML)::TEXT[]
1809 RAISE WARNING 'Could not even guess at control set for authority record %', rec_id;
1814 aal.source := rec_id;
1817 SELECT * FROM authority.control_set_authority_field
1818 WHERE control_set = rec_control_set
1819 AND linking_subfield IS NOT NULL
1820 AND main_entry IS NOT NULL
1823 (XPATH('//*[@tag="' || acsaf.tag || '"]/*[@code="' ||
1824 acsaf.linking_subfield || '"]/text()', rec_marc_xml))[1]::TEXT,
1828 -- Ignore links that are null, malformed, circular, or point to
1829 -- non-existent authority records.
1830 IF link IS NOT NULL AND link::BIGINT <> rec_id THEN
1831 PERFORM * FROM authority.record_entry WHERE id = link::BIGINT;
1833 aal.target := link::BIGINT;
1834 aal.field := acsaf.id;
1840 $func$ LANGUAGE PLPGSQL;
1843 -- AFTER UPDATE OR INSERT trigger for authority.record_entry
1844 CREATE OR REPLACE FUNCTION authority.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
1847 IF NEW.deleted IS TRUE THEN -- If this authority is deleted
1848 DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
1849 DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
1850 DELETE FROM authority.simple_heading WHERE record = NEW.id;
1851 -- Should remove matching $0 from controlled fields at the same time?
1853 -- XXX What do we about the actual linking subfields present in
1854 -- authority records that target this one when this happens?
1855 DELETE FROM authority.authority_linking
1856 WHERE source = NEW.id OR target = NEW.id;
1858 RETURN NEW; -- and we're done
1861 IF TG_OP = 'UPDATE' THEN -- re-ingest?
1862 PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
1864 IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
1868 -- Propagate these updates to any linked bib records
1869 PERFORM authority.propagate_changes(NEW.id) FROM authority.record_entry WHERE id = NEW.id;
1871 DELETE FROM authority.simple_heading WHERE record = NEW.id;
1872 DELETE FROM authority.authority_linking WHERE source = NEW.id;
1875 INSERT INTO authority.authority_linking (source, target, field)
1876 SELECT source, target, field FROM authority.calculate_authority_linking(
1877 NEW.id, NEW.control_set, NEW.marc::XML
1880 INSERT INTO authority.simple_heading (record,atag,value,sort_value)
1881 SELECT record, atag, value, sort_value FROM authority.simple_heading_set(NEW.marc);
1883 -- Flatten and insert the afr data
1884 PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
1886 PERFORM authority.reingest_authority_full_rec(NEW.id);
1887 PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
1889 PERFORM authority.reingest_authority_rec_descriptor(NEW.id);
1895 $func$ LANGUAGE PLPGSQL;
1898 -- check whether patch can be applied
1899 SELECT evergreen.upgrade_deps_block_check('0816', :eg_version);
1901 -- To avoid problems with altering a table column after doing an
1903 ALTER TABLE authority.control_set_authority_field
1904 DISABLE TRIGGER ALL;
1906 ALTER TABLE authority.control_set_authority_field
1907 ADD COLUMN display_sf_list TEXT;
1909 UPDATE authority.control_set_authority_field
1910 SET display_sf_list = REGEXP_REPLACE(sf_list, '[w254]', '', 'g');
1912 ALTER TABLE authority.control_set_authority_field
1913 ALTER COLUMN display_sf_list SET NOT NULL;
1915 ALTER TABLE authority.control_set_authority_field
1918 ALTER TABLE metabib.browse_entry_def_map
1919 ADD COLUMN authority BIGINT REFERENCES authority.record_entry (id)
1922 ALTER TABLE config.metabib_field ADD COLUMN authority_xpath TEXT;
1923 ALTER TABLE config.metabib_field ADD COLUMN browse_sort_xpath TEXT;
1925 UPDATE config.metabib_field
1926 SET authority_xpath = '//@xlink:href'
1928 format = 'mods32' AND
1929 field_class IN ('subject','series','title','author') AND
1930 browse_field IS TRUE;
1932 ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE authority BIGINT;
1933 ALTER TYPE metabib.field_entry_template ADD ATTRIBUTE sort_value TEXT;
1935 CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( bib_id BIGINT, skip_facet BOOL DEFAULT FALSE, skip_browse BOOL DEFAULT FALSE, skip_search BOOL DEFAULT FALSE ) RETURNS VOID AS $func$
1938 ind_data metabib.field_entry_template%ROWTYPE;
1939 mbe_row metabib.browse_entry%ROWTYPE;
1947 SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
1948 SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
1949 SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
1951 PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
1953 IF NOT b_skip_search THEN
1954 FOR fclass IN SELECT * FROM config.metabib_class LOOP
1955 -- RAISE NOTICE 'Emptying out %', fclass.name;
1956 EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
1959 IF NOT b_skip_facet THEN
1960 DELETE FROM metabib.facet_entry WHERE source = bib_id;
1962 IF NOT b_skip_browse THEN
1963 DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
1967 FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id ) LOOP
1968 IF ind_data.field < 0 THEN
1969 ind_data.field = -1 * ind_data.field;
1972 IF ind_data.facet_field AND NOT b_skip_facet THEN
1973 INSERT INTO metabib.facet_entry (field, source, value)
1974 VALUES (ind_data.field, ind_data.source, ind_data.value);
1977 IF ind_data.browse_field AND NOT b_skip_browse THEN
1978 -- A caveat about this SELECT: this should take care of replacing
1979 -- old mbe rows when data changes, but not if normalization (by
1980 -- which I mean specifically the output of
1981 -- evergreen.oils_tsearch2()) changes. It may or may not be
1982 -- expensive to add a comparison of index_vector to index_vector
1983 -- to the WHERE clause below.
1985 value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
1986 SELECT INTO mbe_row * FROM metabib.browse_entry
1987 WHERE value = value_prepped AND sort_value = ind_data.sort_value;
1990 mbe_id := mbe_row.id;
1992 INSERT INTO metabib.browse_entry
1993 ( value, sort_value ) VALUES
1994 ( value_prepped, ind_data.sort_value );
1996 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
1999 INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
2000 VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
2003 IF ind_data.search_field AND NOT b_skip_search THEN
2005 INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
2007 quote_literal(ind_data.field) || $$, $$ ||
2008 quote_literal(ind_data.source) || $$, $$ ||
2009 quote_literal(ind_data.value) ||
2015 IF NOT b_skip_search THEN
2016 PERFORM metabib.update_combined_index_vectors(bib_id);
2021 $func$ LANGUAGE PLPGSQL;
2024 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
2026 bib biblio.record_entry%ROWTYPE;
2027 idx config.metabib_field%ROWTYPE;
2028 xfrm config.xml_transform%ROWTYPE;
2030 transformed_xml TEXT;
2032 xml_node_list TEXT[];
2038 joiner TEXT := default_joiner; -- XXX will index defs supply a joiner?
2039 authority_text TEXT;
2040 authority_link BIGINT;
2041 output_row metabib.field_entry_template%ROWTYPE;
2045 SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
2047 -- Loop over the indexing entries
2048 FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
2050 SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
2052 -- See if we can skip the XSLT ... it's expensive
2053 IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
2054 -- Can't skip the transform
2055 IF xfrm.xslt <> '---' THEN
2056 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
2058 transformed_xml := bib.marc;
2061 prev_xfrm := xfrm.name;
2064 xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2067 FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
2068 CONTINUE WHEN xml_node !~ E'^\\s*<';
2070 curr_text := ARRAY_TO_STRING(
2071 oils_xpath( '//text()',
2072 REGEXP_REPLACE( -- This escapes all &s not followed by "amp;". Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
2073 REGEXP_REPLACE( -- This escapes embeded <s
2075 $re$(>[^<]+)(<)([^>]+<)$re$,
2087 CONTINUE WHEN curr_text IS NULL OR curr_text = '';
2089 IF raw_text IS NOT NULL THEN
2090 raw_text := raw_text || joiner;
2093 raw_text := COALESCE(raw_text,'') || curr_text;
2095 -- autosuggest/metabib.browse_entry
2096 IF idx.browse_field THEN
2098 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
2099 browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2101 browse_text := curr_text;
2104 IF idx.browse_sort_xpath IS NOT NULL AND
2105 idx.browse_sort_xpath <> '' THEN
2107 sort_value := oils_xpath_string(
2108 idx.browse_sort_xpath, xml_node, joiner,
2109 ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
2112 sort_value := browse_text;
2115 output_row.field_class = idx.field_class;
2116 output_row.field = idx.id;
2117 output_row.source = rid;
2118 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
2119 output_row.sort_value :=
2120 public.search_normalize(sort_value);
2122 output_row.authority := NULL;
2124 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
2125 authority_text := oils_xpath_string(
2126 idx.authority_xpath, xml_node, joiner,
2128 ARRAY[xfrm.prefix, xfrm.namespace_uri],
2129 ARRAY['xlink','http://www.w3.org/1999/xlink']
2133 IF authority_text ~ '^\d+$' THEN
2134 authority_link := authority_text::BIGINT;
2135 PERFORM * FROM authority.record_entry WHERE id = authority_link;
2137 output_row.authority := authority_link;
2143 output_row.browse_field = TRUE;
2144 RETURN NEXT output_row;
2145 output_row.browse_field = FALSE;
2146 output_row.sort_value := NULL;
2149 -- insert raw node text for faceting
2150 IF idx.facet_field THEN
2152 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
2153 facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
2155 facet_text := curr_text;
2158 output_row.field_class = idx.field_class;
2159 output_row.field = -1 * idx.id;
2160 output_row.source = rid;
2161 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
2163 output_row.facet_field = TRUE;
2164 RETURN NEXT output_row;
2165 output_row.facet_field = FALSE;
2170 CONTINUE WHEN raw_text IS NULL OR raw_text = '';
2172 -- insert combined node text for searching
2173 IF idx.search_field THEN
2174 output_row.field_class = idx.field_class;
2175 output_row.field = idx.id;
2176 output_row.source = rid;
2177 output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
2179 output_row.search_field = TRUE;
2180 RETURN NEXT output_row;
2181 output_row.search_field = FALSE;
2188 $func$ LANGUAGE PLPGSQL;
2191 -- 953.data.MODS32-xsl.sql
2192 UPDATE config.xml_transform SET xslt=$$<?xml version="1.0" encoding="UTF-8"?>
2193 <xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
2194 <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
2196 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements
2197 with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
2199 Revision 1.13 - Changed order of output under cartographics to reflect schema 2006/11/28 tmee
2201 Revision 1.12 - Updated to reflect MODS 3.2 Mapping 2006/10/11 tmee
2203 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
2206 Revision 1.10 MODS 3.1 revisions to language and classification elements
2207 (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
2210 Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
2212 Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
2214 Revision 1.7 2004/03/25 08:29 jrad
2216 Revision 1.6 various validation fixes 2004/02/20 ntra
2218 Revision 1.5 2003/10/02 16:18:58 ntra
2219 MODS2 to MODS3 updates, language unstacking and
2220 de-duping, chopPunctuation expanded
2222 Revision 1.3 2003/04/03 00:07:19 ntra
2223 Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
2225 Revision 1.2 2003/03/24 19:37:42 ckeith
2229 <xsl:template match="/">
2231 <xsl:when test="//marc:collection">
2232 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
2233 <xsl:for-each select="//marc:collection/marc:record">
2234 <mods version="3.2">
2235 <xsl:call-template name="marcRecord"/>
2241 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
2242 <xsl:for-each select="//marc:record">
2243 <xsl:call-template name="marcRecord"/>
2249 <xsl:template name="marcRecord">
2250 <xsl:variable name="leader" select="marc:leader"/>
2251 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
2252 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
2253 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
2254 <xsl:variable name="typeOf008">
2256 <xsl:when test="$leader6='a'">
2258 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
2259 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
2262 <xsl:when test="$leader6='t'">BK</xsl:when>
2263 <xsl:when test="$leader6='p'">MM</xsl:when>
2264 <xsl:when test="$leader6='m'">CF</xsl:when>
2265 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
2266 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
2267 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
2270 <xsl:for-each select="marc:datafield[@tag='245']">
2272 <xsl:variable name="title">
2274 <xsl:when test="marc:subfield[@code='b']">
2275 <xsl:call-template name="specialSubfieldSelect">
2276 <xsl:with-param name="axis">b</xsl:with-param>
2277 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
2278 </xsl:call-template>
2281 <xsl:call-template name="subfieldSelect">
2282 <xsl:with-param name="codes">abfgk</xsl:with-param>
2283 </xsl:call-template>
2287 <xsl:variable name="titleChop">
2288 <xsl:call-template name="chopPunctuation">
2289 <xsl:with-param name="chopString">
2290 <xsl:value-of select="$title"/>
2292 </xsl:call-template>
2295 <xsl:when test="@ind2>0">
2297 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
2300 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
2305 <xsl:value-of select="$titleChop"/>
2309 <xsl:if test="marc:subfield[@code='b']">
2311 <xsl:call-template name="chopPunctuation">
2312 <xsl:with-param name="chopString">
2313 <xsl:call-template name="specialSubfieldSelect">
2314 <xsl:with-param name="axis">b</xsl:with-param>
2315 <xsl:with-param name="anyCodes">b</xsl:with-param>
2316 <xsl:with-param name="afterCodes">afgk</xsl:with-param>
2317 </xsl:call-template>
2319 </xsl:call-template>
2322 <xsl:call-template name="part"></xsl:call-template>
2324 <!-- A form of title that ignores non-filing characters; useful
2325 for not converting "L'Oreal" into "L' Oreal" at index time -->
2327 <xsl:variable name="title">
2329 <xsl:when test="marc:subfield[@code='b']">
2330 <xsl:call-template name="specialSubfieldSelect">
2331 <xsl:with-param name="axis">b</xsl:with-param>
2332 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
2333 </xsl:call-template>
2336 <xsl:call-template name="subfieldSelect">
2337 <xsl:with-param name="codes">abfgk</xsl:with-param>
2338 </xsl:call-template>
2343 <xsl:value-of select="$title"/>
2345 <xsl:if test="marc:subfield[@code='b']">
2347 <xsl:call-template name="chopPunctuation">
2348 <xsl:with-param name="chopString">
2349 <xsl:call-template name="specialSubfieldSelect">
2350 <xsl:with-param name="axis">b</xsl:with-param>
2351 <xsl:with-param name="anyCodes">b</xsl:with-param>
2352 <xsl:with-param name="afterCodes">afgk</xsl:with-param>
2353 </xsl:call-template>
2355 </xsl:call-template>
2358 <xsl:call-template name="part"></xsl:call-template>
2361 <xsl:for-each select="marc:datafield[@tag='210']">
2362 <titleInfo type="abbreviated">
2364 <xsl:call-template name="chopPunctuation">
2365 <xsl:with-param name="chopString">
2366 <xsl:call-template name="subfieldSelect">
2367 <xsl:with-param name="codes">a</xsl:with-param>
2368 </xsl:call-template>
2370 </xsl:call-template>
2372 <xsl:call-template name="subtitle"/>
2375 <xsl:for-each select="marc:datafield[@tag='242']">
2376 <xsl:variable name="titleChop">
2377 <xsl:call-template name="chopPunctuation">
2378 <xsl:with-param name="chopString">
2379 <xsl:call-template name="subfieldSelect">
2380 <!-- 1/04 removed $h, b -->
2381 <xsl:with-param name="codes">a</xsl:with-param>
2382 </xsl:call-template>
2384 </xsl:call-template>
2386 <titleInfo type="translated">
2387 <!--09/01/04 Added subfield $y-->
2388 <xsl:for-each select="marc:subfield[@code='y']">
2389 <xsl:attribute name="lang">
2390 <xsl:value-of select="text()"/>
2394 <xsl:value-of select="$titleChop" />
2397 <xsl:call-template name="subtitle"/>
2398 <xsl:call-template name="part"/>
2400 <titleInfo type="translated-nfi">
2401 <xsl:for-each select="marc:subfield[@code='y']">
2402 <xsl:attribute name="lang">
2403 <xsl:value-of select="text()"/>
2407 <xsl:when test="@ind2>0">
2409 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
2412 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
2417 <xsl:value-of select="$titleChop" />
2421 <xsl:call-template name="subtitle"/>
2422 <xsl:call-template name="part"/>
2425 <xsl:for-each select="marc:datafield[@tag='246']">
2426 <titleInfo type="alternative">
2427 <xsl:for-each select="marc:subfield[@code='i']">
2428 <xsl:attribute name="displayLabel">
2429 <xsl:value-of select="text()"/>
2433 <xsl:call-template name="chopPunctuation">
2434 <xsl:with-param name="chopString">
2435 <xsl:call-template name="subfieldSelect">
2436 <!-- 1/04 removed $h, $b -->
2437 <xsl:with-param name="codes">af</xsl:with-param>
2438 </xsl:call-template>
2440 </xsl:call-template>
2442 <xsl:call-template name="subtitle"/>
2443 <xsl:call-template name="part"/>
2446 <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
2447 <xsl:variable name="nfi">
2449 <xsl:when test="@tag='240'">
2450 <xsl:value-of select="@ind2"/>
2453 <xsl:value-of select="@ind1"/>
2457 <xsl:variable name="titleChop">
2458 <xsl:call-template name="uri" />
2459 <xsl:variable name="str">
2460 <xsl:for-each select="marc:subfield">
2461 <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
2462 <xsl:value-of select="text()"/>
2463 <xsl:text> </xsl:text>
2467 <xsl:call-template name="chopPunctuation">
2468 <xsl:with-param name="chopString">
2469 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
2471 </xsl:call-template>
2473 <titleInfo type="uniform">
2475 <xsl:value-of select="$titleChop"/>
2477 <xsl:call-template name="part"/>
2479 <titleInfo type="uniform-nfi">
2481 <xsl:when test="$nfi>0">
2483 <xsl:value-of select="substring($titleChop,1,$nfi)"/>
2486 <xsl:value-of select="substring($titleChop,$nfi+1)"/>
2491 <xsl:value-of select="$titleChop"/>
2495 <xsl:call-template name="part"/>
2498 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
2499 <xsl:variable name="titleChop">
2500 <xsl:call-template name="chopPunctuation">
2501 <xsl:with-param name="chopString">
2502 <xsl:call-template name="subfieldSelect">
2503 <xsl:with-param name="codes">ah</xsl:with-param>
2504 </xsl:call-template>
2506 </xsl:call-template>
2508 <titleInfo type="alternative">
2510 <xsl:value-of select="$titleChop" />
2512 <xsl:call-template name="part"/>
2514 <titleInfo type="alternative-nfi">
2516 <xsl:when test="@ind1>0">
2518 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
2521 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
2526 <xsl:value-of select="$titleChop" />
2530 <xsl:call-template name="part"/>
2533 <xsl:for-each select="marc:datafield[@tag='100']">
2534 <name type="personal">
2535 <xsl:call-template name="uri" />
2536 <xsl:call-template name="nameABCDQ"/>
2537 <xsl:call-template name="affiliation"/>
2539 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2541 <xsl:call-template name="role"/>
2544 <xsl:for-each select="marc:datafield[@tag='110']">
2545 <name type="corporate">
2546 <xsl:call-template name="uri" />
2547 <xsl:call-template name="nameABCDN"/>
2549 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2551 <xsl:call-template name="role"/>
2554 <xsl:for-each select="marc:datafield[@tag='111']">
2555 <name type="conference">
2556 <xsl:call-template name="uri" />
2557 <xsl:call-template name="nameACDEQ"/>
2559 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
2561 <xsl:call-template name="role"/>
2564 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
2565 <name type="personal">
2566 <xsl:call-template name="uri" />
2567 <xsl:call-template name="nameABCDQ"/>
2568 <xsl:call-template name="affiliation"/>
2569 <xsl:call-template name="role"/>
2572 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
2573 <name type="corporate">
2574 <xsl:call-template name="uri" />
2575 <xsl:call-template name="nameABCDN"/>
2576 <xsl:call-template name="role"/>
2579 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
2580 <name type="conference">
2581 <xsl:call-template name="uri" />
2582 <xsl:call-template name="nameACDEQ"/>
2583 <xsl:call-template name="role"/>
2586 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
2588 <xsl:if test="@ind1=1">
2589 <xsl:attribute name="type">
2590 <xsl:text>personal</xsl:text>
2594 <xsl:value-of select="marc:subfield[@code='a']"/>
2596 <xsl:call-template name="role"/>
2600 <xsl:if test="$leader7='c'">
2601 <xsl:attribute name="collection">yes</xsl:attribute>
2603 <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
2604 <xsl:attribute name="manuscript">yes</xsl:attribute>
2607 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
2608 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
2609 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
2610 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
2611 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
2612 <xsl:when test="$leader6='k'">still image</xsl:when>
2613 <xsl:when test="$leader6='g'">moving image</xsl:when>
2614 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
2615 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
2616 <xsl:when test="$leader6='p'">mixed material</xsl:when>
2619 <xsl:if test="substring($controlField008,26,1)='d'">
2620 <genre authority="marc">globe</genre>
2622 <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
2623 <genre authority="marc">remote sensing image</genre>
2625 <xsl:if test="$typeOf008='MP'">
2626 <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
2628 <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
2629 <genre authority="marc">map</genre>
2631 <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
2632 <genre authority="marc">atlas</genre>
2636 <xsl:if test="$typeOf008='SE'">
2637 <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
2639 <xsl:when test="$controlField008-21='d'">
2640 <genre authority="marc">database</genre>
2642 <xsl:when test="$controlField008-21='l'">
2643 <genre authority="marc">loose-leaf</genre>
2645 <xsl:when test="$controlField008-21='m'">
2646 <genre authority="marc">series</genre>
2648 <xsl:when test="$controlField008-21='n'">
2649 <genre authority="marc">newspaper</genre>
2651 <xsl:when test="$controlField008-21='p'">
2652 <genre authority="marc">periodical</genre>
2654 <xsl:when test="$controlField008-21='w'">
2655 <genre authority="marc">web site</genre>
2659 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
2660 <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
2662 <xsl:when test="contains($controlField008-24,'a')">
2663 <genre authority="marc">abstract or summary</genre>
2665 <xsl:when test="contains($controlField008-24,'b')">
2666 <genre authority="marc">bibliography</genre>
2668 <xsl:when test="contains($controlField008-24,'c')">
2669 <genre authority="marc">catalog</genre>
2671 <xsl:when test="contains($controlField008-24,'d')">
2672 <genre authority="marc">dictionary</genre>
2674 <xsl:when test="contains($controlField008-24,'e')">
2675 <genre authority="marc">encyclopedia</genre>
2677 <xsl:when test="contains($controlField008-24,'f')">
2678 <genre authority="marc">handbook</genre>
2680 <xsl:when test="contains($controlField008-24,'g')">
2681 <genre authority="marc">legal article</genre>
2683 <xsl:when test="contains($controlField008-24,'i')">
2684 <genre authority="marc">index</genre>
2686 <xsl:when test="contains($controlField008-24,'k')">
2687 <genre authority="marc">discography</genre>
2689 <xsl:when test="contains($controlField008-24,'l')">
2690 <genre authority="marc">legislation</genre>
2692 <xsl:when test="contains($controlField008-24,'m')">
2693 <genre authority="marc">theses</genre>
2695 <xsl:when test="contains($controlField008-24,'n')">
2696 <genre authority="marc">survey of literature</genre>
2698 <xsl:when test="contains($controlField008-24,'o')">
2699 <genre authority="marc">review</genre>
2701 <xsl:when test="contains($controlField008-24,'p')">
2702 <genre authority="marc">programmed text</genre>
2704 <xsl:when test="contains($controlField008-24,'q')">
2705 <genre authority="marc">filmography</genre>
2707 <xsl:when test="contains($controlField008-24,'r')">
2708 <genre authority="marc">directory</genre>
2710 <xsl:when test="contains($controlField008-24,'s')">
2711 <genre authority="marc">statistics</genre>
2713 <xsl:when test="contains($controlField008-24,'t')">
2714 <genre authority="marc">technical report</genre>
2716 <xsl:when test="contains($controlField008-24,'v')">
2717 <genre authority="marc">legal case and case notes</genre>
2719 <xsl:when test="contains($controlField008-24,'w')">
2720 <genre authority="marc">law report or digest</genre>
2722 <xsl:when test="contains($controlField008-24,'z')">
2723 <genre authority="marc">treaty</genre>
2726 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
2728 <xsl:when test="$controlField008-29='1'">
2729 <genre authority="marc">conference publication</genre>
2733 <xsl:if test="$typeOf008='CF'">
2734 <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
2736 <xsl:when test="$controlField008-26='a'">
2737 <genre authority="marc">numeric data</genre>
2739 <xsl:when test="$controlField008-26='e'">
2740 <genre authority="marc">database</genre>
2742 <xsl:when test="$controlField008-26='f'">
2743 <genre authority="marc">font</genre>
2745 <xsl:when test="$controlField008-26='g'">
2746 <genre authority="marc">game</genre>
2750 <xsl:if test="$typeOf008='BK'">
2751 <xsl:if test="substring($controlField008,25,1)='j'">
2752 <genre authority="marc">patent</genre>
2754 <xsl:if test="substring($controlField008,31,1)='1'">
2755 <genre authority="marc">festschrift</genre>
2757 <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
2758 <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
2759 <genre authority="marc">biography</genre>
2761 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
2763 <xsl:when test="$controlField008-33='e'">
2764 <genre authority="marc">essay</genre>
2766 <xsl:when test="$controlField008-33='d'">
2767 <genre authority="marc">drama</genre>
2769 <xsl:when test="$controlField008-33='c'">
2770 <genre authority="marc">comic strip</genre>
2772 <xsl:when test="$controlField008-33='l'">
2773 <genre authority="marc">fiction</genre>
2775 <xsl:when test="$controlField008-33='h'">
2776 <genre authority="marc">humor, satire</genre>
2778 <xsl:when test="$controlField008-33='i'">
2779 <genre authority="marc">letter</genre>
2781 <xsl:when test="$controlField008-33='f'">
2782 <genre authority="marc">novel</genre>
2784 <xsl:when test="$controlField008-33='j'">
2785 <genre authority="marc">short story</genre>
2787 <xsl:when test="$controlField008-33='s'">
2788 <genre authority="marc">speech</genre>
2792 <xsl:if test="$typeOf008='MU'">
2793 <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
2794 <xsl:if test="contains($controlField008-30-31,'b')">
2795 <genre authority="marc">biography</genre>
2797 <xsl:if test="contains($controlField008-30-31,'c')">
2798 <genre authority="marc">conference publication</genre>
2800 <xsl:if test="contains($controlField008-30-31,'d')">
2801 <genre authority="marc">drama</genre>
2803 <xsl:if test="contains($controlField008-30-31,'e')">
2804 <genre authority="marc">essay</genre>
2806 <xsl:if test="contains($controlField008-30-31,'f')">
2807 <genre authority="marc">fiction</genre>
2809 <xsl:if test="contains($controlField008-30-31,'o')">
2810 <genre authority="marc">folktale</genre>
2812 <xsl:if test="contains($controlField008-30-31,'h')">
2813 <genre authority="marc">history</genre>
2815 <xsl:if test="contains($controlField008-30-31,'k')">
2816 <genre authority="marc">humor, satire</genre>
2818 <xsl:if test="contains($controlField008-30-31,'m')">
2819 <genre authority="marc">memoir</genre>
2821 <xsl:if test="contains($controlField008-30-31,'p')">
2822 <genre authority="marc">poetry</genre>
2824 <xsl:if test="contains($controlField008-30-31,'r')">
2825 <genre authority="marc">rehearsal</genre>
2827 <xsl:if test="contains($controlField008-30-31,'g')">
2828 <genre authority="marc">reporting</genre>
2830 <xsl:if test="contains($controlField008-30-31,'s')">
2831 <genre authority="marc">sound</genre>
2833 <xsl:if test="contains($controlField008-30-31,'l')">
2834 <genre authority="marc">speech</genre>
2837 <xsl:if test="$typeOf008='VM'">
2838 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
2840 <xsl:when test="$controlField008-33='a'">
2841 <genre authority="marc">art original</genre>
2843 <xsl:when test="$controlField008-33='b'">
2844 <genre authority="marc">kit</genre>
2846 <xsl:when test="$controlField008-33='c'">
2847 <genre authority="marc">art reproduction</genre>
2849 <xsl:when test="$controlField008-33='d'">
2850 <genre authority="marc">diorama</genre>
2852 <xsl:when test="$controlField008-33='f'">
2853 <genre authority="marc">filmstrip</genre>
2855 <xsl:when test="$controlField008-33='g'">
2856 <genre authority="marc">legal article</genre>
2858 <xsl:when test="$controlField008-33='i'">
2859 <genre authority="marc">picture</genre>
2861 <xsl:when test="$controlField008-33='k'">
2862 <genre authority="marc">graphic</genre>
2864 <xsl:when test="$controlField008-33='l'">
2865 <genre authority="marc">technical drawing</genre>
2867 <xsl:when test="$controlField008-33='m'">
2868 <genre authority="marc">motion picture</genre>
2870 <xsl:when test="$controlField008-33='n'">
2871 <genre authority="marc">chart</genre>
2873 <xsl:when test="$controlField008-33='o'">
2874 <genre authority="marc">flash card</genre>
2876 <xsl:when test="$controlField008-33='p'">
2877 <genre authority="marc">microscope slide</genre>
2879 <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
2880 <genre authority="marc">model</genre>
2882 <xsl:when test="$controlField008-33='r'">
2883 <genre authority="marc">realia</genre>
2885 <xsl:when test="$controlField008-33='s'">
2886 <genre authority="marc">slide</genre>
2888 <xsl:when test="$controlField008-33='t'">
2889 <genre authority="marc">transparency</genre>
2891 <xsl:when test="$controlField008-33='v'">
2892 <genre authority="marc">videorecording</genre>
2894 <xsl:when test="$controlField008-33='w'">
2895 <genre authority="marc">toy</genre>
2899 <xsl:for-each select="marc:datafield[@tag=655]">
2900 <genre authority="marc">
2901 <xsl:attribute name="authority">
2902 <xsl:value-of select="marc:subfield[@code='2']"/>
2904 <xsl:call-template name="subfieldSelect">
2905 <xsl:with-param name="codes">abvxyz</xsl:with-param>
2906 <xsl:with-param name="delimeter">-</xsl:with-param>
2907 </xsl:call-template>
2911 <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
2912 <xsl:if test="translate($MARCpublicationCode,'|','')">
2915 <xsl:attribute name="type">code</xsl:attribute>
2916 <xsl:attribute name="authority">marccountry</xsl:attribute>
2917 <xsl:value-of select="$MARCpublicationCode"/>
2921 <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
2924 <xsl:attribute name="type">code</xsl:attribute>
2925 <xsl:attribute name="authority">iso3166</xsl:attribute>
2926 <xsl:value-of select="."/>
2930 <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
2933 <xsl:attribute name="type">text</xsl:attribute>
2934 <xsl:call-template name="chopPunctuationFront">
2935 <xsl:with-param name="chopString">
2936 <xsl:call-template name="chopPunctuation">
2937 <xsl:with-param name="chopString" select="."/>
2938 </xsl:call-template>
2940 </xsl:call-template>
2944 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
2945 <dateValid point="start">
2946 <xsl:value-of select="."/>
2949 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
2950 <dateValid point="end">
2951 <xsl:value-of select="."/>
2954 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
2956 <xsl:value-of select="."/>
2959 <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
2961 <xsl:when test="@code='b'">
2963 <xsl:call-template name="chopPunctuation">
2964 <xsl:with-param name="chopString" select="."/>
2965 <xsl:with-param name="punctuation">
2966 <xsl:text>:,;/ </xsl:text>
2968 </xsl:call-template>
2971 <xsl:when test="@code='c'">
2973 <xsl:call-template name="chopPunctuation">
2974 <xsl:with-param name="chopString" select="."/>
2975 </xsl:call-template>
2978 <xsl:when test="@code='g'">
2980 <xsl:value-of select="."/>
2985 <xsl:variable name="dataField260c">
2986 <xsl:call-template name="chopPunctuation">
2987 <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
2988 </xsl:call-template>
2990 <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
2991 <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
2992 <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
2993 <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
2994 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
2995 <dateIssued encoding="marc">
2996 <xsl:value-of select="$controlField008-7-10"/>
3000 <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
3001 <xsl:if test="$controlField008-7-10">
3002 <dateIssued encoding="marc" point="start">
3003 <xsl:value-of select="$controlField008-7-10"/>
3007 <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
3008 <xsl:if test="$controlField008-11-14">
3009 <dateIssued encoding="marc" point="end">
3010 <xsl:value-of select="$controlField008-11-14"/>
3014 <xsl:if test="$controlField008-6='q'">
3015 <xsl:if test="$controlField008-7-10">
3016 <dateIssued encoding="marc" point="start" qualifier="questionable">
3017 <xsl:value-of select="$controlField008-7-10"/>
3021 <xsl:if test="$controlField008-6='q'">
3022 <xsl:if test="$controlField008-11-14">
3023 <dateIssued encoding="marc" point="end" qualifier="questionable">
3024 <xsl:value-of select="$controlField008-11-14"/>
3028 <xsl:if test="$controlField008-6='t'">
3029 <xsl:if test="$controlField008-11-14">
3030 <copyrightDate encoding="marc">
3031 <xsl:value-of select="$controlField008-11-14"/>
3035 <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
3036 <dateCaptured encoding="iso8601">
3037 <xsl:value-of select="."/>
3040 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
3041 <dateCaptured encoding="iso8601" point="start">
3042 <xsl:value-of select="."/>
3045 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
3046 <dateCaptured encoding="iso8601" point="end">
3047 <xsl:value-of select="."/>
3050 <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
3052 <xsl:value-of select="."/>
3055 <xsl:for-each select="marc:leader">
3058 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
3059 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
3063 <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
3065 <xsl:call-template name="subfieldSelect">
3066 <xsl:with-param name="codes">ab</xsl:with-param>
3067 </xsl:call-template>
3071 <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
3072 <xsl:if test="$controlField008-35-37">
3074 <languageTerm authority="iso639-2b" type="code">
3075 <xsl:value-of select="substring($controlField008,36,3)"/>
3079 <xsl:for-each select="marc:datafield[@tag=041]">
3080 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
3081 <xsl:variable name="langCodes" select="."/>
3083 <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
3084 <!-- not stacked but could be repeated -->
3085 <xsl:call-template name="rfcLanguages">
3086 <xsl:with-param name="nodeNum">
3087 <xsl:value-of select="1"/>
3089 <xsl:with-param name="usedLanguages">
3090 <xsl:text></xsl:text>
3092 <xsl:with-param name="controlField008-35-37">
3093 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
3095 </xsl:call-template>
3099 <xsl:variable name="allLanguages">
3100 <xsl:copy-of select="$langCodes"></xsl:copy-of>
3102 <xsl:variable name="currentLanguage">
3103 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
3105 <xsl:call-template name="isoLanguage">
3106 <xsl:with-param name="currentLanguage">
3107 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
3109 <xsl:with-param name="remainingLanguages">
3110 <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
3112 <xsl:with-param name="usedLanguages">
3113 <xsl:if test="$controlField008-35-37">
3114 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
3117 </xsl:call-template>
3122 <xsl:variable name="physicalDescription">
3123 <!--3.2 change tmee 007/11 -->
3124 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
3125 <digitalOrigin>reformatted digital</digitalOrigin>
3127 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
3128 <digitalOrigin>digitized microfilm</digitalOrigin>
3130 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
3131 <digitalOrigin>digitized other analog</digitalOrigin>
3133 <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
3134 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
3135 <xsl:variable name="check008-23">
3136 <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
3137 <xsl:value-of select="true()"></xsl:value-of>
3140 <xsl:variable name="check008-29">
3141 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
3142 <xsl:value-of select="true()"></xsl:value-of>
3146 <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
3147 <form authority="marcform">braille</form>
3149 <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
3150 <form authority="marcform">print</form>
3152 <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
3153 <form authority="marcform">electronic</form>
3155 <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
3156 <form authority="marcform">microfiche</form>
3158 <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
3159 <form authority="marcform">microfilm</form>
3163 <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
3164 <form authority="gmd">
3165 <xsl:call-template name="chopBrackets">
3166 <xsl:with-param name="chopString">
3167 <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
3169 </xsl:call-template>
3172 <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
3173 <form authority="gmd">
3174 <xsl:call-template name="chopBrackets">
3175 <xsl:with-param name="chopString">
3176 <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
3178 </xsl:call-template>
3181 <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
3182 <form authority="gmd">
3183 <xsl:call-template name="chopBrackets">
3184 <xsl:with-param name="chopString">
3185 <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
3187 </xsl:call-template>
3190 <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
3191 <form authority="gmd">
3192 <xsl:call-template name="chopBrackets">
3193 <xsl:with-param name="chopString">
3194 <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
3196 </xsl:call-template>
3199 <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
3200 <form authority="gmd">
3201 <xsl:call-template name="chopBrackets">
3202 <xsl:with-param name="chopString">
3203 <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
3205 </xsl:call-template>
3208 <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
3209 <form authority="gmd">
3210 <xsl:call-template name="chopBrackets">
3211 <xsl:with-param name="chopString">
3212 <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
3214 </xsl:call-template>
3217 <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
3219 <xsl:value-of select="."></xsl:value-of>
3222 <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
3224 <xsl:when test="substring(text(),14,1)='a'">
3225 <reformattingQuality>access</reformattingQuality>
3227 <xsl:when test="substring(text(),14,1)='p'">
3228 <reformattingQuality>preservation</reformattingQuality>
3230 <xsl:when test="substring(text(),14,1)='r'">
3231 <reformattingQuality>replacement</reformattingQuality>
3235 <!--3.2 change tmee 007/01 -->
3236 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
3237 <form authority="smd">chip cartridge</form>
3239 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
3240 <form authority="smd">computer optical disc cartridge</form>
3242 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
3243 <form authority="smd">magnetic disc</form>
3245 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
3246 <form authority="smd">magneto-optical disc</form>
3248 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
3249 <form authority="smd">optical disc</form>
3251 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
3252 <form authority="smd">remote</form>
3254 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
3255 <form authority="smd">tape cartridge</form>
3257 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
3258 <form authority="smd">tape cassette</form>
3260 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
3261 <form authority="smd">tape reel</form>
3264 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
3265 <form authority="smd">celestial globe</form>
3267 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
3268 <form authority="smd">earth moon globe</form>
3270 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
3271 <form authority="smd">planetary or lunar globe</form>
3273 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
3274 <form authority="smd">terrestrial globe</form>
3277 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
3278 <form authority="smd">kit</form>
3281 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
3282 <form authority="smd">atlas</form>
3284 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
3285 <form authority="smd">diagram</form>
3287 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
3288 <form authority="smd">map</form>
3290 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
3291 <form authority="smd">model</form>
3293 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
3294 <form authority="smd">profile</form>
3296 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
3297 <form authority="smd">remote-sensing image</form>
3299 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
3300 <form authority="smd">section</form>
3302 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
3303 <form authority="smd">view</form>
3306 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
3307 <form authority="smd">aperture card</form>
3309 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
3310 <form authority="smd">microfiche</form>
3312 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
3313 <form authority="smd">microfiche cassette</form>
3315 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
3316 <form authority="smd">microfilm cartridge</form>
3318 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
3319 <form authority="smd">microfilm cassette</form>
3321 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
3322 <form authority="smd">microfilm reel</form>
3324 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
3325 <form authority="smd">microopaque</form>
3328 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
3329 <form authority="smd">film cartridge</form>
3331 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
3332 <form authority="smd">film cassette</form>
3334 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
3335 <form authority="smd">film reel</form>
3338 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
3339 <form authority="smd">chart</form>
3341 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
3342 <form authority="smd">collage</form>
3344 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
3345 <form authority="smd">drawing</form>
3347 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
3348 <form authority="smd">flash card</form>
3350 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
3351 <form authority="smd">painting</form>
3353 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
3354 <form authority="smd">photomechanical print</form>
3356 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
3357 <form authority="smd">photonegative</form>
3359 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
3360 <form authority="smd">photoprint</form>
3362 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
3363 <form authority="smd">picture</form>
3365 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
3366 <form authority="smd">print</form>
3368 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
3369 <form authority="smd">technical drawing</form>
3372 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
3373 <form authority="smd">notated music</form>
3376 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
3377 <form authority="smd">filmslip</form>
3379 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
3380 <form authority="smd">filmstrip cartridge</form>
3382 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
3383 <form authority="smd">filmstrip roll</form>
3385 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
3386 <form authority="smd">other filmstrip type</form>
3388 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
3389 <form authority="smd">slide</form>
3391 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
3392 <form authority="smd">transparency</form>
3394 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
3395 <form authority="smd">remote-sensing image</form>
3397 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
3398 <form authority="smd">cylinder</form>
3400 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
3401 <form authority="smd">roll</form>
3403 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
3404 <form authority="smd">sound cartridge</form>
3406 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
3407 <form authority="smd">sound cassette</form>
3409 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
3410 <form authority="smd">sound disc</form>
3412 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
3413 <form authority="smd">sound-tape reel</form>
3415 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
3416 <form authority="smd">sound-track film</form>
3418 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
3419 <form authority="smd">wire recording</form>
3422 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
3423 <form authority="smd">braille</form>
3425 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
3426 <form authority="smd">combination</form>
3428 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
3429 <form authority="smd">moon</form>
3431 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
3432 <form authority="smd">tactile, with no writing system</form>
3435 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
3436 <form authority="smd">braille</form>
3438 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
3439 <form authority="smd">large print</form>
3441 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
3442 <form authority="smd">regular print</form>
3444 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
3445 <form authority="smd">text in looseleaf binder</form>
3448 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
3449 <form authority="smd">videocartridge</form>
3451 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
3452 <form authority="smd">videocassette</form>
3454 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
3455 <form authority="smd">videodisc</form>
3457 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
3458 <form authority="smd">videoreel</form>
3461 <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
3463 <xsl:value-of select="."></xsl:value-of>
3464 </internetMediaType>
3466 <xsl:for-each select="marc:datafield[@tag=300]">
3468 <xsl:call-template name="subfieldSelect">
3469 <xsl:with-param name="codes">abce</xsl:with-param>
3470 </xsl:call-template>
3474 <xsl:if test="string-length(normalize-space($physicalDescription))">
3475 <physicalDescription>
3476 <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
3477 </physicalDescription>
3479 <xsl:for-each select="marc:datafield[@tag=520]">
3481 <xsl:call-template name="uri"></xsl:call-template>
3482 <xsl:call-template name="subfieldSelect">
3483 <xsl:with-param name="codes">ab</xsl:with-param>
3484 </xsl:call-template>
3487 <xsl:for-each select="marc:datafield[@tag=505]">
3489 <xsl:call-template name="uri"></xsl:call-template>
3490 <xsl:call-template name="subfieldSelect">
3491 <xsl:with-param name="codes">agrt</xsl:with-param>
3492 </xsl:call-template>
3495 <xsl:for-each select="marc:datafield[@tag=521]">
3497 <xsl:call-template name="subfieldSelect">
3498 <xsl:with-param name="codes">ab</xsl:with-param>
3499 </xsl:call-template>
3502 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
3503 <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
3506 <xsl:when test="$controlField008-22='d'">
3507 <targetAudience authority="marctarget">adolescent</targetAudience>
3509 <xsl:when test="$controlField008-22='e'">
3510 <targetAudience authority="marctarget">adult</targetAudience>
3512 <xsl:when test="$controlField008-22='g'">
3513 <targetAudience authority="marctarget">general</targetAudience>
3515 <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
3516 <targetAudience authority="marctarget">juvenile</targetAudience>
3518 <xsl:when test="$controlField008-22='a'">
3519 <targetAudience authority="marctarget">preschool</targetAudience>
3521 <xsl:when test="$controlField008-22='f'">
3522 <targetAudience authority="marctarget">specialized</targetAudience>
3526 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
3527 <note type="statement of responsibility">
3528 <xsl:value-of select="."></xsl:value-of>
3531 <xsl:for-each select="marc:datafield[@tag=500]">
3533 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3534 <xsl:call-template name="uri"></xsl:call-template>
3538 <!--3.2 change tmee additional note fields-->
3540 <xsl:for-each select="marc:datafield[@tag=506]">
3541 <note type="restrictions">
3542 <xsl:call-template name="uri"></xsl:call-template>
3543 <xsl:variable name="str">
3544 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3545 <xsl:value-of select="."></xsl:value-of>
3546 <xsl:text> </xsl:text>
3549 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3553 <xsl:for-each select="marc:datafield[@tag=510]">
3554 <note type="citation/reference">
3555 <xsl:call-template name="uri"></xsl:call-template>
3556 <xsl:variable name="str">
3557 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3558 <xsl:value-of select="."></xsl:value-of>
3559 <xsl:text> </xsl:text>
3562 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3567 <xsl:for-each select="marc:datafield[@tag=511]">
3568 <note type="performers">
3569 <xsl:call-template name="uri"></xsl:call-template>
3570 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3573 <xsl:for-each select="marc:datafield[@tag=518]">
3575 <xsl:call-template name="uri"></xsl:call-template>
3576 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3580 <xsl:for-each select="marc:datafield[@tag=530]">
3581 <note type="additional physical form">
3582 <xsl:call-template name="uri"></xsl:call-template>
3583 <xsl:variable name="str">
3584 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3585 <xsl:value-of select="."></xsl:value-of>
3586 <xsl:text> </xsl:text>
3589 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3593 <xsl:for-each select="marc:datafield[@tag=533]">
3594 <note type="reproduction">
3595 <xsl:call-template name="uri"></xsl:call-template>
3596 <xsl:variable name="str">
3597 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3598 <xsl:value-of select="."></xsl:value-of>
3599 <xsl:text> </xsl:text>
3602 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3606 <xsl:for-each select="marc:datafield[@tag=534]">
3607 <note type="original version">
3608 <xsl:call-template name="uri"></xsl:call-template>
3609 <xsl:variable name="str">
3610 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3611 <xsl:value-of select="."></xsl:value-of>
3612 <xsl:text> </xsl:text>
3615 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3619 <xsl:for-each select="marc:datafield[@tag=538]">
3620 <note type="system details">
3621 <xsl:call-template name="uri"></xsl:call-template>
3622 <xsl:variable name="str">
3623 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3624 <xsl:value-of select="."></xsl:value-of>
3625 <xsl:text> </xsl:text>
3628 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3632 <xsl:for-each select="marc:datafield[@tag=583]">
3633 <note type="action">
3634 <xsl:call-template name="uri"></xsl:call-template>
3635 <xsl:variable name="str">
3636 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3637 <xsl:value-of select="."></xsl:value-of>
3638 <xsl:text> </xsl:text>
3641 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3649 <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
3651 <xsl:call-template name="uri"></xsl:call-template>
3652 <xsl:variable name="str">
3653 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
3654 <xsl:value-of select="."></xsl:value-of>
3655 <xsl:text> </xsl:text>
3658 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
3661 <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
3665 <xsl:call-template name="subfieldSelect">
3666 <xsl:with-param name="codes">defg</xsl:with-param>
3667 </xsl:call-template>
3672 <xsl:for-each select="marc:datafield[@tag=043]">
3674 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
3676 <xsl:attribute name="authority">
3677 <xsl:if test="@code='a'">
3678 <xsl:text>marcgac</xsl:text>
3680 <xsl:if test="@code='b'">
3681 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
3683 <xsl:if test="@code='c'">
3684 <xsl:text>iso3166</xsl:text>
3687 <xsl:value-of select="self::marc:subfield"></xsl:value-of>
3692 <!-- tmee 2006/11/27 -->
3693 <xsl:for-each select="marc:datafield[@tag=255]">
3695 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
3697 <xsl:if test="@code='a'">
3699 <xsl:value-of select="."></xsl:value-of>
3702 <xsl:if test="@code='b'">
3704 <xsl:value-of select="."></xsl:value-of>
3707 <xsl:if test="@code='c'">
3709 <xsl:value-of select="."></xsl:value-of>
3717 <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
3718 <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
3719 <xsl:for-each select="marc:datafield[@tag=752]">
3721 <hierarchicalGeographic>
3722 <xsl:for-each select="marc:subfield[@code='a']">
3724 <xsl:call-template name="chopPunctuation">
3725 <xsl:with-param name="chopString" select="."></xsl:with-param>
3726 </xsl:call-template>
3729 <xsl:for-each select="marc:subfield[@code='b']">
3731 <xsl:call-template name="chopPunctuation">
3732 <xsl:with-param name="chopString" select="."></xsl:with-param>
3733 </xsl:call-template>
3736 <xsl:for-each select="marc:subfield[@code='c']">
3738 <xsl:call-template name="chopPunctuation">
3739 <xsl:with-param name="chopString" select="."></xsl:with-param>
3740 </xsl:call-template>
3743 <xsl:for-each select="marc:subfield[@code='d']">
3745 <xsl:call-template name="chopPunctuation">
3746 <xsl:with-param name="chopString" select="."></xsl:with-param>
3747 </xsl:call-template>
3750 </hierarchicalGeographic>
3753 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
3756 <xsl:when test="@ind1=2">
3757 <temporal encoding="iso8601" point="start">
3758 <xsl:call-template name="chopPunctuation">
3759 <xsl:with-param name="chopString">
3760 <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
3762 </xsl:call-template>
3764 <temporal encoding="iso8601" point="end">
3765 <xsl:call-template name="chopPunctuation">
3766 <xsl:with-param name="chopString">
3767 <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
3769 </xsl:call-template>
3773 <xsl:for-each select="marc:subfield[@code='b']">
3774 <temporal encoding="iso8601">
3775 <xsl:call-template name="chopPunctuation">
3776 <xsl:with-param name="chopString" select="."></xsl:with-param>
3777 </xsl:call-template>
3784 <xsl:for-each select="marc:datafield[@tag=050]">
3785 <xsl:for-each select="marc:subfield[@code='b']">
3786 <classification authority="lcc">
3787 <xsl:if test="../marc:subfield[@code='3']">
3788 <xsl:attribute name="displayLabel">
3789 <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
3792 <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
3793 <xsl:text> </xsl:text>
3794 <xsl:value-of select="text()"></xsl:value-of>
3797 <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
3798 <classification authority="lcc">
3799 <xsl:if test="../marc:subfield[@code='3']">
3800 <xsl:attribute name="displayLabel">
3801 <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
3804 <xsl:value-of select="text()"></xsl:value-of>
3808 <xsl:for-each select="marc:datafield[@tag=082]">
3809 <classification authority="ddc">
3810 <xsl:if test="marc:subfield[@code='2']">
3811 <xsl:attribute name="edition">
3812 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3815 <xsl:call-template name="subfieldSelect">
3816 <xsl:with-param name="codes">ab</xsl:with-param>
3817 </xsl:call-template>
3820 <xsl:for-each select="marc:datafield[@tag=080]">
3821 <classification authority="udc">
3822 <xsl:call-template name="subfieldSelect">
3823 <xsl:with-param name="codes">abx</xsl:with-param>
3824 </xsl:call-template>
3827 <xsl:for-each select="marc:datafield[@tag=060]">
3828 <classification authority="nlm">
3829 <xsl:call-template name="subfieldSelect">
3830 <xsl:with-param name="codes">ab</xsl:with-param>
3831 </xsl:call-template>
3834 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
3835 <classification authority="sudocs">
3836 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3839 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
3840 <classification authority="candoc">
3841 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3844 <xsl:for-each select="marc:datafield[@tag=086]">
3846 <xsl:attribute name="authority">
3847 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3849 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
3852 <xsl:for-each select="marc:datafield[@tag=084]">
3854 <xsl:attribute name="authority">
3855 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
3857 <xsl:call-template name="subfieldSelect">
3858 <xsl:with-param name="codes">ab</xsl:with-param>
3859 </xsl:call-template>
3862 <xsl:for-each select="marc:datafield[@tag=440]">
3863 <relatedItem type="series">
3864 <xsl:variable name="titleChop">
3865 <xsl:call-template name="chopPunctuation">
3866 <xsl:with-param name="chopString">
3867 <xsl:call-template name="subfieldSelect">
3868 <xsl:with-param name="codes">av</xsl:with-param>
3869 </xsl:call-template>
3871 </xsl:call-template>
3875 <xsl:value-of select="$titleChop" />
3877 <xsl:call-template name="part"></xsl:call-template>
3879 <titleInfo type="nfi">
3881 <xsl:when test="@ind2>0">
3883 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
3886 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
3888 <xsl:call-template name="part"/>
3892 <xsl:value-of select="$titleChop" />
3896 <xsl:call-template name="part"></xsl:call-template>
3900 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
3901 <relatedItem type="series">
3904 <xsl:call-template name="chopPunctuation">
3905 <xsl:with-param name="chopString">
3906 <xsl:call-template name="subfieldSelect">
3907 <xsl:with-param name="codes">av</xsl:with-param>
3908 </xsl:call-template>
3910 </xsl:call-template>
3912 <xsl:call-template name="part"></xsl:call-template>
3916 <xsl:for-each select="marc:datafield[@tag=510]">
3917 <relatedItem type="isReferencedBy">
3919 <xsl:call-template name="subfieldSelect">
3920 <xsl:with-param name="codes">abcx3</xsl:with-param>
3921 </xsl:call-template>
3925 <xsl:for-each select="marc:datafield[@tag=534]">
3926 <relatedItem type="original">
3927 <xsl:call-template name="relatedTitle"></xsl:call-template>
3928 <xsl:call-template name="relatedName"></xsl:call-template>
3929 <xsl:if test="marc:subfield[@code='b' or @code='c']">
3931 <xsl:for-each select="marc:subfield[@code='c']">
3933 <xsl:value-of select="."></xsl:value-of>
3936 <xsl:for-each select="marc:subfield[@code='b']">
3938 <xsl:value-of select="."></xsl:value-of>
3943 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
3944 <xsl:for-each select="marc:subfield[@code='z']">
3945 <identifier type="isbn">
3946 <xsl:value-of select="."></xsl:value-of>
3949 <xsl:call-template name="relatedNote"></xsl:call-template>
3952 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
3954 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
3957 <xsl:call-template name="chopPunctuation">
3958 <xsl:with-param name="chopString">
3959 <xsl:call-template name="specialSubfieldSelect">
3960 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
3961 <xsl:with-param name="axis">t</xsl:with-param>
3962 <xsl:with-param name="afterCodes">g</xsl:with-param>
3963 </xsl:call-template>
3965 </xsl:call-template>
3967 <xsl:call-template name="part"></xsl:call-template>
3969 <name type="personal">
3971 <xsl:call-template name="specialSubfieldSelect">
3972 <xsl:with-param name="anyCodes">aq</xsl:with-param>
3973 <xsl:with-param name="axis">t</xsl:with-param>
3974 <xsl:with-param name="beforeCodes">g</xsl:with-param>
3975 </xsl:call-template>
3977 <xsl:call-template name="termsOfAddress"></xsl:call-template>
3978 <xsl:call-template name="nameDate"></xsl:call-template>
3979 <xsl:call-template name="role"></xsl:call-template>
3981 <xsl:call-template name="relatedForm"></xsl:call-template>
3982 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
3985 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
3987 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
3990 <xsl:call-template name="chopPunctuation">
3991 <xsl:with-param name="chopString">
3992 <xsl:call-template name="specialSubfieldSelect">
3993 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
3994 <xsl:with-param name="axis">t</xsl:with-param>
3995 <xsl:with-param name="afterCodes">dg</xsl:with-param>
3996 </xsl:call-template>
3998 </xsl:call-template>
4000 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4002 <name type="corporate">
4003 <xsl:for-each select="marc:subfield[@code='a']">
4005 <xsl:value-of select="."></xsl:value-of>
4008 <xsl:for-each select="marc:subfield[@code='b']">
4010 <xsl:value-of select="."></xsl:value-of>
4013 <xsl:variable name="tempNamePart">
4014 <xsl:call-template name="specialSubfieldSelect">
4015 <xsl:with-param name="anyCodes">c</xsl:with-param>
4016 <xsl:with-param name="axis">t</xsl:with-param>
4017 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
4018 </xsl:call-template>
4020 <xsl:if test="normalize-space($tempNamePart)">
4022 <xsl:value-of select="$tempNamePart"></xsl:value-of>
4025 <xsl:call-template name="role"></xsl:call-template>
4027 <xsl:call-template name="relatedForm"></xsl:call-template>
4028 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4031 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
4033 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
4036 <xsl:call-template name="chopPunctuation">
4037 <xsl:with-param name="chopString">
4038 <xsl:call-template name="specialSubfieldSelect">
4039 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
4040 <xsl:with-param name="axis">t</xsl:with-param>
4041 <xsl:with-param name="afterCodes">g</xsl:with-param>
4042 </xsl:call-template>
4044 </xsl:call-template>
4046 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4048 <name type="conference">
4050 <xsl:call-template name="specialSubfieldSelect">
4051 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
4052 <xsl:with-param name="axis">t</xsl:with-param>
4053 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
4054 </xsl:call-template>
4057 <xsl:call-template name="relatedForm"></xsl:call-template>
4058 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4061 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
4063 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
4066 <xsl:call-template name="chopPunctuation">
4067 <xsl:with-param name="chopString">
4068 <xsl:call-template name="subfieldSelect">
4069 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
4070 </xsl:call-template>
4072 </xsl:call-template>
4074 <xsl:call-template name="part"></xsl:call-template>
4076 <xsl:call-template name="relatedForm"></xsl:call-template>
4077 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4080 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
4082 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
4083 <xsl:variable name="titleChop">
4084 <xsl:call-template name="chopPunctuation">
4085 <xsl:with-param name="chopString">
4086 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
4088 </xsl:call-template>
4092 <xsl:value-of select="$titleChop" />
4094 <xsl:call-template name="part"></xsl:call-template>
4096 <titleInfo type="nfi">
4098 <xsl:when test="@ind1>0">
4100 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
4103 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
4108 <xsl:value-of select="$titleChop" />
4112 <xsl:call-template name="part"></xsl:call-template>
4114 <xsl:call-template name="relatedForm"></xsl:call-template>
4117 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
4118 <relatedItem type="series">
4119 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4122 <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
4124 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4127 <xsl:for-each select="marc:datafield[@tag=775]">
4128 <relatedItem type="otherVersion">
4129 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4132 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
4133 <relatedItem type="constituent">
4134 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4137 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
4138 <relatedItem type="host">
4139 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4142 <xsl:for-each select="marc:datafield[@tag=776]">
4143 <relatedItem type="otherFormat">
4144 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4147 <xsl:for-each select="marc:datafield[@tag=780]">
4148 <relatedItem type="preceding">
4149 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4152 <xsl:for-each select="marc:datafield[@tag=785]">
4153 <relatedItem type="succeeding">
4154 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4157 <xsl:for-each select="marc:datafield[@tag=786]">
4158 <relatedItem type="original">
4159 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
4162 <xsl:for-each select="marc:datafield[@tag=800]">
4163 <relatedItem type="series">
4166 <xsl:call-template name="chopPunctuation">
4167 <xsl:with-param name="chopString">
4168 <xsl:call-template name="specialSubfieldSelect">
4169 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
4170 <xsl:with-param name="axis">t</xsl:with-param>
4171 <xsl:with-param name="afterCodes">g</xsl:with-param>
4172 </xsl:call-template>
4174 </xsl:call-template>
4176 <xsl:call-template name="part"></xsl:call-template>
4178 <name type="personal">
4180 <xsl:call-template name="chopPunctuation">
4181 <xsl:with-param name="chopString">
4182 <xsl:call-template name="specialSubfieldSelect">
4183 <xsl:with-param name="anyCodes">aq</xsl:with-param>
4184 <xsl:with-param name="axis">t</xsl:with-param>
4185 <xsl:with-param name="beforeCodes">g</xsl:with-param>
4186 </xsl:call-template>
4188 </xsl:call-template>
4190 <xsl:call-template name="termsOfAddress"></xsl:call-template>
4191 <xsl:call-template name="nameDate"></xsl:call-template>
4192 <xsl:call-template name="role"></xsl:call-template>
4194 <xsl:call-template name="relatedForm"></xsl:call-template>
4197 <xsl:for-each select="marc:datafield[@tag=810]">
4198 <relatedItem type="series">
4201 <xsl:call-template name="chopPunctuation">
4202 <xsl:with-param name="chopString">
4203 <xsl:call-template name="specialSubfieldSelect">
4204 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
4205 <xsl:with-param name="axis">t</xsl:with-param>
4206 <xsl:with-param name="afterCodes">dg</xsl:with-param>
4207 </xsl:call-template>
4209 </xsl:call-template>
4211 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4213 <name type="corporate">
4214 <xsl:for-each select="marc:subfield[@code='a']">
4216 <xsl:value-of select="."></xsl:value-of>
4219 <xsl:for-each select="marc:subfield[@code='b']">
4221 <xsl:value-of select="."></xsl:value-of>
4225 <xsl:call-template name="specialSubfieldSelect">
4226 <xsl:with-param name="anyCodes">c</xsl:with-param>
4227 <xsl:with-param name="axis">t</xsl:with-param>
4228 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
4229 </xsl:call-template>
4231 <xsl:call-template name="role"></xsl:call-template>
4233 <xsl:call-template name="relatedForm"></xsl:call-template>
4236 <xsl:for-each select="marc:datafield[@tag=811]">
4237 <relatedItem type="series">
4240 <xsl:call-template name="chopPunctuation">
4241 <xsl:with-param name="chopString">
4242 <xsl:call-template name="specialSubfieldSelect">
4243 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
4244 <xsl:with-param name="axis">t</xsl:with-param>
4245 <xsl:with-param name="afterCodes">g</xsl:with-param>
4246 </xsl:call-template>
4248 </xsl:call-template>
4250 <xsl:call-template name="relatedPartNumName"/>
4252 <name type="conference">
4254 <xsl:call-template name="specialSubfieldSelect">
4255 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
4256 <xsl:with-param name="axis">t</xsl:with-param>
4257 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
4258 </xsl:call-template>
4260 <xsl:call-template name="role"/>
4262 <xsl:call-template name="relatedForm"/>
4265 <xsl:for-each select="marc:datafield[@tag='830']">
4266 <relatedItem type="series">
4267 <xsl:variable name="titleChop">
4268 <xsl:call-template name="chopPunctuation">
4269 <xsl:with-param name="chopString">
4270 <xsl:call-template name="subfieldSelect">
4271 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
4272 </xsl:call-template>
4274 </xsl:call-template>
4278 <xsl:value-of select="$titleChop" />
4280 <xsl:call-template name="part"/>
4282 <titleInfo type="nfi">
4284 <xsl:when test="@ind2>0">
4286 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
4289 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
4294 <xsl:value-of select="$titleChop" />
4298 <xsl:call-template name="part"/>
4300 <xsl:call-template name="relatedForm"/>
4303 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
4306 <xsl:value-of select="."/>
4307 </internetMediaType>
4310 <xsl:for-each select="marc:datafield[@tag='020']">
4311 <xsl:call-template name="isInvalid">
4312 <xsl:with-param name="type">isbn</xsl:with-param>
4313 </xsl:call-template>
4314 <xsl:if test="marc:subfield[@code='a']">
4315 <identifier type="isbn">
4316 <xsl:value-of select="marc:subfield[@code='a']"/>
4320 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
4321 <xsl:call-template name="isInvalid">
4322 <xsl:with-param name="type">isrc</xsl:with-param>
4323 </xsl:call-template>
4324 <xsl:if test="marc:subfield[@code='a']">
4325 <identifier type="isrc">
4326 <xsl:value-of select="marc:subfield[@code='a']"/>
4330 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
4331 <xsl:call-template name="isInvalid">
4332 <xsl:with-param name="type">ismn</xsl:with-param>
4333 </xsl:call-template>
4334 <xsl:if test="marc:subfield[@code='a']">
4335 <identifier type="ismn">
4336 <xsl:value-of select="marc:subfield[@code='a']"/>
4340 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
4341 <xsl:call-template name="isInvalid">
4342 <xsl:with-param name="type">sici</xsl:with-param>
4343 </xsl:call-template>
4344 <identifier type="sici">
4345 <xsl:call-template name="subfieldSelect">
4346 <xsl:with-param name="codes">ab</xsl:with-param>
4347 </xsl:call-template>
4350 <xsl:for-each select="marc:datafield[@tag='022']">
4351 <xsl:call-template name="isInvalid">
4352 <xsl:with-param name="type">issn</xsl:with-param>
4353 </xsl:call-template>
4354 <identifier type="issn">
4355 <xsl:value-of select="marc:subfield[@code='a']"/>
4358 <xsl:for-each select="marc:datafield[@tag='010']">
4359 <xsl:call-template name="isInvalid">
4360 <xsl:with-param name="type">lccn</xsl:with-param>
4361 </xsl:call-template>
4362 <identifier type="lccn">
4363 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
4366 <xsl:for-each select="marc:datafield[@tag='028']">
4368 <xsl:attribute name="type">
4370 <xsl:when test="@ind1='0'">issue number</xsl:when>
4371 <xsl:when test="@ind1='1'">matrix number</xsl:when>
4372 <xsl:when test="@ind1='2'">music plate</xsl:when>
4373 <xsl:when test="@ind1='3'">music publisher</xsl:when>
4374 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
4377 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
4378 <xsl:call-template name="subfieldSelect">
4379 <xsl:with-param name="codes">
4381 <xsl:when test="@ind1='0'">ba</xsl:when>
4382 <xsl:otherwise>ab</xsl:otherwise>
4385 </xsl:call-template>
4388 <xsl:for-each select="marc:datafield[@tag='037']">
4389 <identifier type="stock number">
4390 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
4391 <xsl:call-template name="subfieldSelect">
4392 <xsl:with-param name="codes">ab</xsl:with-param>
4393 </xsl:call-template>
4396 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
4398 <xsl:attribute name="type">
4400 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
4401 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
4402 <xsl:otherwise>uri</xsl:otherwise>
4406 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
4407 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
4410 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
4414 <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
4415 <identifier type="hdl">
4416 <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
4417 <xsl:attribute name="displayLabel">
4418 <xsl:call-template name="subfieldSelect">
4419 <xsl:with-param name="codes">y3z</xsl:with-param>
4420 </xsl:call-template>
4423 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
4427 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
4428 <identifier type="upc">
4429 <xsl:call-template name="isInvalid"/>
4430 <xsl:value-of select="marc:subfield[@code='a']"/>
4433 <!-- 1/04 fix added $y -->
4434 <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
4437 <xsl:if test="marc:subfield[@code='y' or @code='3']">
4438 <xsl:attribute name="displayLabel">
4439 <xsl:call-template name="subfieldSelect">
4440 <xsl:with-param name="codes">y3</xsl:with-param>
4441 </xsl:call-template>
4444 <xsl:if test="marc:subfield[@code='z' ]">
4445 <xsl:attribute name="note">
4446 <xsl:call-template name="subfieldSelect">
4447 <xsl:with-param name="codes">z</xsl:with-param>
4448 </xsl:call-template>
4451 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
4457 <!-- 3.2 change tmee 856z -->
4460 <xsl:for-each select="marc:datafield[@tag=852]">
4463 <xsl:call-template name="displayLabel"></xsl:call-template>
4464 <xsl:call-template name="subfieldSelect">
4465 <xsl:with-param name="codes">abje</xsl:with-param>
4466 </xsl:call-template>
4470 <xsl:for-each select="marc:datafield[@tag=506]">
4471 <accessCondition type="restrictionOnAccess">
4472 <xsl:call-template name="subfieldSelect">
4473 <xsl:with-param name="codes">abcd35</xsl:with-param>
4474 </xsl:call-template>
4477 <xsl:for-each select="marc:datafield[@tag=540]">
4478 <accessCondition type="useAndReproduction">
4479 <xsl:call-template name="subfieldSelect">
4480 <xsl:with-param name="codes">abcde35</xsl:with-param>
4481 </xsl:call-template>
4485 <xsl:for-each select="marc:datafield[@tag=040]">
4486 <recordContentSource authority="marcorg">
4487 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
4488 </recordContentSource>
4490 <xsl:for-each select="marc:controlfield[@tag=008]">
4491 <recordCreationDate encoding="marc">
4492 <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
4493 </recordCreationDate>
4495 <xsl:for-each select="marc:controlfield[@tag=005]">
4496 <recordChangeDate encoding="iso8601">
4497 <xsl:value-of select="."></xsl:value-of>
4500 <xsl:for-each select="marc:controlfield[@tag=001]">
4502 <xsl:if test="../marc:controlfield[@tag=003]">
4503 <xsl:attribute name="source">
4504 <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
4507 <xsl:value-of select="."></xsl:value-of>
4510 <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
4511 <languageOfCataloging>
4512 <languageTerm authority="iso639-2b" type="code">
4513 <xsl:value-of select="."></xsl:value-of>
4515 </languageOfCataloging>
4519 <xsl:template name="displayForm">
4520 <xsl:for-each select="marc:subfield[@code='c']">
4522 <xsl:value-of select="."></xsl:value-of>
4526 <xsl:template name="affiliation">
4527 <xsl:for-each select="marc:subfield[@code='u']">
4529 <xsl:value-of select="."></xsl:value-of>
4533 <xsl:template name="uri">
4534 <xsl:for-each select="marc:subfield[@code='u']">
4535 <xsl:attribute name="xlink:href">
4536 <xsl:value-of select="."></xsl:value-of>
4539 <xsl:for-each select="marc:subfield[@code='0']">
4541 <xsl:when test="contains(text(), ')')">
4542 <xsl:attribute name="xlink:href">
4543 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
4547 <xsl:attribute name="xlink:href">
4548 <xsl:value-of select="."></xsl:value-of>
4554 <xsl:template name="role">
4555 <xsl:for-each select="marc:subfield[@code='e']">
4557 <roleTerm type="text">
4558 <xsl:value-of select="."></xsl:value-of>
4562 <xsl:for-each select="marc:subfield[@code='4']">
4564 <roleTerm authority="marcrelator" type="code">
4565 <xsl:value-of select="."></xsl:value-of>
4570 <xsl:template name="part">
4571 <xsl:variable name="partNumber">
4572 <xsl:call-template name="specialSubfieldSelect">
4573 <xsl:with-param name="axis">n</xsl:with-param>
4574 <xsl:with-param name="anyCodes">n</xsl:with-param>
4575 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4576 </xsl:call-template>
4578 <xsl:variable name="partName">
4579 <xsl:call-template name="specialSubfieldSelect">
4580 <xsl:with-param name="axis">p</xsl:with-param>
4581 <xsl:with-param name="anyCodes">p</xsl:with-param>
4582 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4583 </xsl:call-template>
4585 <xsl:if test="string-length(normalize-space($partNumber))">
4587 <xsl:call-template name="chopPunctuation">
4588 <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
4589 </xsl:call-template>
4592 <xsl:if test="string-length(normalize-space($partName))">
4594 <xsl:call-template name="chopPunctuation">
4595 <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
4596 </xsl:call-template>
4600 <xsl:template name="relatedPart">
4601 <xsl:if test="@tag=773">
4602 <xsl:for-each select="marc:subfield[@code='g']">
4605 <xsl:value-of select="."></xsl:value-of>
4609 <xsl:for-each select="marc:subfield[@code='q']">
4611 <xsl:call-template name="parsePart"></xsl:call-template>
4616 <xsl:template name="relatedPartNumName">
4617 <xsl:variable name="partNumber">
4618 <xsl:call-template name="specialSubfieldSelect">
4619 <xsl:with-param name="axis">g</xsl:with-param>
4620 <xsl:with-param name="anyCodes">g</xsl:with-param>
4621 <xsl:with-param name="afterCodes">pst</xsl:with-param>
4622 </xsl:call-template>
4624 <xsl:variable name="partName">
4625 <xsl:call-template name="specialSubfieldSelect">
4626 <xsl:with-param name="axis">p</xsl:with-param>
4627 <xsl:with-param name="anyCodes">p</xsl:with-param>
4628 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
4629 </xsl:call-template>
4631 <xsl:if test="string-length(normalize-space($partNumber))">
4633 <xsl:value-of select="$partNumber"></xsl:value-of>
4636 <xsl:if test="string-length(normalize-space($partName))">
4638 <xsl:value-of select="$partName"></xsl:value-of>
4642 <xsl:template name="relatedName">
4643 <xsl:for-each select="marc:subfield[@code='a']">
4646 <xsl:value-of select="."></xsl:value-of>
4651 <xsl:template name="relatedForm">
4652 <xsl:for-each select="marc:subfield[@code='h']">
4653 <physicalDescription>
4655 <xsl:value-of select="."></xsl:value-of>
4657 </physicalDescription>
4660 <xsl:template name="relatedExtent">
4661 <xsl:for-each select="marc:subfield[@code='h']">
4662 <physicalDescription>
4664 <xsl:value-of select="."></xsl:value-of>
4666 </physicalDescription>
4669 <xsl:template name="relatedNote">
4670 <xsl:for-each select="marc:subfield[@code='n']">
4672 <xsl:value-of select="."></xsl:value-of>
4676 <xsl:template name="relatedSubject">
4677 <xsl:for-each select="marc:subfield[@code='j']">
4679 <temporal encoding="iso8601">
4680 <xsl:call-template name="chopPunctuation">
4681 <xsl:with-param name="chopString" select="."></xsl:with-param>
4682 </xsl:call-template>
4687 <xsl:template name="relatedIdentifierISSN">
4688 <xsl:for-each select="marc:subfield[@code='x']">
4689 <identifier type="issn">
4690 <xsl:value-of select="."></xsl:value-of>
4694 <xsl:template name="relatedIdentifierLocal">
4695 <xsl:for-each select="marc:subfield[@code='w']">
4696 <identifier type="local">
4697 <xsl:value-of select="."></xsl:value-of>
4701 <xsl:template name="relatedIdentifier">
4702 <xsl:for-each select="marc:subfield[@code='o']">
4704 <xsl:value-of select="."></xsl:value-of>
4708 <xsl:template name="relatedItem76X-78X">
4709 <xsl:call-template name="displayLabel"></xsl:call-template>
4710 <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
4711 <xsl:call-template name="relatedName"></xsl:call-template>
4712 <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
4713 <xsl:call-template name="relatedLanguage"></xsl:call-template>
4714 <xsl:call-template name="relatedExtent"></xsl:call-template>
4715 <xsl:call-template name="relatedNote"></xsl:call-template>
4716 <xsl:call-template name="relatedSubject"></xsl:call-template>
4717 <xsl:call-template name="relatedIdentifier"></xsl:call-template>
4718 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
4719 <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
4720 <xsl:call-template name="relatedPart"></xsl:call-template>
4722 <xsl:template name="subjectGeographicZ">
4724 <xsl:call-template name="chopPunctuation">
4725 <xsl:with-param name="chopString" select="."></xsl:with-param>
4726 </xsl:call-template>
4729 <xsl:template name="subjectTemporalY">
4731 <xsl:call-template name="chopPunctuation">
4732 <xsl:with-param name="chopString" select="."></xsl:with-param>
4733 </xsl:call-template>
4736 <xsl:template name="subjectTopic">
4738 <xsl:call-template name="chopPunctuation">
4739 <xsl:with-param name="chopString" select="."></xsl:with-param>
4740 </xsl:call-template>
4743 <!-- 3.2 change tmee 6xx $v genre -->
4744 <xsl:template name="subjectGenre">
4746 <xsl:call-template name="chopPunctuation">
4747 <xsl:with-param name="chopString" select="."></xsl:with-param>
4748 </xsl:call-template>
4752 <xsl:template name="nameABCDN">
4753 <xsl:for-each select="marc:subfield[@code='a']">
4755 <xsl:call-template name="chopPunctuation">
4756 <xsl:with-param name="chopString" select="."></xsl:with-param>
4757 </xsl:call-template>
4760 <xsl:for-each select="marc:subfield[@code='b']">
4762 <xsl:value-of select="."></xsl:value-of>
4765 <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
4767 <xsl:call-template name="subfieldSelect">
4768 <xsl:with-param name="codes">cdn</xsl:with-param>
4769 </xsl:call-template>
4773 <xsl:template name="nameABCDQ">
4775 <xsl:call-template name="chopPunctuation">
4776 <xsl:with-param name="chopString">
4777 <xsl:call-template name="subfieldSelect">
4778 <xsl:with-param name="codes">aq</xsl:with-param>
4779 </xsl:call-template>
4781 <xsl:with-param name="punctuation">
4782 <xsl:text>:,;/ </xsl:text>
4784 </xsl:call-template>
4786 <xsl:call-template name="termsOfAddress"></xsl:call-template>
4787 <xsl:call-template name="nameDate"></xsl:call-template>
4789 <xsl:template name="nameACDEQ">
4791 <xsl:call-template name="subfieldSelect">
4792 <xsl:with-param name="codes">acdeq</xsl:with-param>
4793 </xsl:call-template>
4796 <xsl:template name="constituentOrRelatedType">
4797 <xsl:if test="@ind2=2">
4798 <xsl:attribute name="type">constituent</xsl:attribute>
4801 <xsl:template name="relatedTitle">
4802 <xsl:for-each select="marc:subfield[@code='t']">
4805 <xsl:call-template name="chopPunctuation">
4806 <xsl:with-param name="chopString">
4807 <xsl:value-of select="."></xsl:value-of>
4809 </xsl:call-template>
4814 <xsl:template name="relatedTitle76X-78X">
4815 <xsl:for-each select="marc:subfield[@code='t']">
4818 <xsl:call-template name="chopPunctuation">
4819 <xsl:with-param name="chopString">
4820 <xsl:value-of select="."></xsl:value-of>
4822 </xsl:call-template>
4824 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4825 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4829 <xsl:for-each select="marc:subfield[@code='p']">
4830 <titleInfo type="abbreviated">
4832 <xsl:call-template name="chopPunctuation">
4833 <xsl:with-param name="chopString">
4834 <xsl:value-of select="."></xsl:value-of>
4836 </xsl:call-template>
4838 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4839 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4843 <xsl:for-each select="marc:subfield[@code='s']">
4844 <titleInfo type="uniform">
4846 <xsl:call-template name="chopPunctuation">
4847 <xsl:with-param name="chopString">
4848 <xsl:value-of select="."></xsl:value-of>
4850 </xsl:call-template>
4852 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
4853 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
4858 <xsl:template name="relatedOriginInfo">
4859 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
4861 <xsl:if test="@tag=775">
4862 <xsl:for-each select="marc:subfield[@code='f']">
4865 <xsl:attribute name="type">code</xsl:attribute>
4866 <xsl:attribute name="authority">marcgac</xsl:attribute>
4867 <xsl:value-of select="."></xsl:value-of>
4872 <xsl:for-each select="marc:subfield[@code='d']">
4874 <xsl:value-of select="."></xsl:value-of>
4877 <xsl:for-each select="marc:subfield[@code='b']">
4879 <xsl:value-of select="."></xsl:value-of>
4885 <xsl:template name="relatedLanguage">
4886 <xsl:for-each select="marc:subfield[@code='e']">
4887 <xsl:call-template name="getLanguage">
4888 <xsl:with-param name="langString">
4889 <xsl:value-of select="."></xsl:value-of>
4891 </xsl:call-template>
4894 <xsl:template name="nameDate">
4895 <xsl:for-each select="marc:subfield[@code='d']">
4896 <namePart type="date">
4897 <xsl:call-template name="chopPunctuation">
4898 <xsl:with-param name="chopString" select="."></xsl:with-param>
4899 </xsl:call-template>
4903 <xsl:template name="subjectAuthority">
4904 <xsl:if test="@ind2!=4">
4905 <xsl:if test="@ind2!=' '">
4906 <xsl:if test="@ind2!=8">
4907 <xsl:if test="@ind2!=9">
4908 <xsl:attribute name="authority">
4910 <xsl:when test="@ind2=0">lcsh</xsl:when>
4911 <xsl:when test="@ind2=1">lcshac</xsl:when>
4912 <xsl:when test="@ind2=2">mesh</xsl:when>
4914 <xsl:when test="@ind2=3">nal</xsl:when>
4915 <xsl:when test="@ind2=5">csh</xsl:when>
4916 <xsl:when test="@ind2=6">rvm</xsl:when>
4917 <xsl:when test="@ind2=7">
4918 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
4927 <xsl:template name="subjectAnyOrder">
4928 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
4930 <xsl:when test="@code='v'">
4931 <xsl:call-template name="subjectGenre"></xsl:call-template>
4933 <xsl:when test="@code='x'">
4934 <xsl:call-template name="subjectTopic"></xsl:call-template>
4936 <xsl:when test="@code='y'">
4937 <xsl:call-template name="subjectTemporalY"></xsl:call-template>
4939 <xsl:when test="@code='z'">
4940 <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
4945 <xsl:template name="specialSubfieldSelect">
4946 <xsl:param name="anyCodes"></xsl:param>
4947 <xsl:param name="axis"></xsl:param>
4948 <xsl:param name="beforeCodes"></xsl:param>
4949 <xsl:param name="afterCodes"></xsl:param>
4950 <xsl:variable name="str">
4951 <xsl:for-each select="marc:subfield">
4952 <xsl:if test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
4953 <xsl:value-of select="text()"></xsl:value-of>
4954 <xsl:text> </xsl:text>
4958 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
4961 <!-- 3.2 change tmee 6xx $v genre -->
4962 <xsl:template match="marc:datafield[@tag=600]">
4964 <xsl:call-template name="subjectAuthority"></xsl:call-template>
4965 <name type="personal">
4966 <xsl:call-template name="uri" />
4967 <xsl:call-template name="termsOfAddress"></xsl:call-template>
4969 <xsl:call-template name="chopPunctuation">
4970 <xsl:with-param name="chopString">
4971 <xsl:call-template name="subfieldSelect">
4972 <xsl:with-param name="codes">aq</xsl:with-param>
4973 </xsl:call-template>
4975 </xsl:call-template>
4977 <xsl:call-template name="nameDate"></xsl:call-template>
4978 <xsl:call-template name="affiliation"></xsl:call-template>
4979 <xsl:call-template name="role"></xsl:call-template>
4981 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
4984 <xsl:template match="marc:datafield[@tag=610]">
4986 <xsl:call-template name="subjectAuthority"></xsl:call-template>
4987 <name type="corporate">
4988 <xsl:call-template name="uri" />
4989 <xsl:for-each select="marc:subfield[@code='a']">
4991 <xsl:value-of select="."></xsl:value-of>
4994 <xsl:for-each select="marc:subfield[@code='b']">
4996 <xsl:value-of select="."></xsl:value-of>
4999 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
5001 <xsl:call-template name="subfieldSelect">
5002 <xsl:with-param name="codes">cdnp</xsl:with-param>
5003 </xsl:call-template>
5006 <xsl:call-template name="role"></xsl:call-template>
5008 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5011 <xsl:template match="marc:datafield[@tag=611]">
5013 <xsl:call-template name="subjectAuthority"></xsl:call-template>
5014 <name type="conference">
5015 <xsl:call-template name="uri" />
5017 <xsl:call-template name="subfieldSelect">
5018 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
5019 </xsl:call-template>
5021 <xsl:for-each select="marc:subfield[@code='4']">
5023 <roleTerm authority="marcrelator" type="code">
5024 <xsl:value-of select="."></xsl:value-of>
5029 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5032 <xsl:template match="marc:datafield[@tag=630]">
5034 <xsl:call-template name="subjectAuthority"></xsl:call-template>
5035 <xsl:variable name="titleChop">
5036 <xsl:call-template name="chopPunctuation">
5037 <xsl:with-param name="chopString">
5038 <xsl:call-template name="subfieldSelect">
5039 <xsl:with-param name="codes">adfhklor</xsl:with-param>
5040 </xsl:call-template>
5042 </xsl:call-template>
5046 <xsl:value-of select="$titleChop" />
5048 <xsl:call-template name="part"></xsl:call-template>
5050 <titleInfo type="nfi">
5052 <xsl:when test="@ind1>0">
5054 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
5057 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
5059 <xsl:call-template name="part"/>
5063 <xsl:value-of select="$titleChop" />
5067 <xsl:call-template name="part"></xsl:call-template>
5069 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5072 <xsl:template match="marc:datafield[@tag=650]">
5074 <xsl:call-template name="subjectAuthority"></xsl:call-template>
5076 <xsl:call-template name="uri" />
5077 <xsl:call-template name="chopPunctuation">
5078 <xsl:with-param name="chopString">
5079 <xsl:call-template name="subfieldSelect">
5080 <xsl:with-param name="codes">abcd</xsl:with-param>
5081 </xsl:call-template>
5083 </xsl:call-template>
5085 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5088 <xsl:template match="marc:datafield[@tag=651]">
5090 <xsl:call-template name="subjectAuthority"></xsl:call-template>
5091 <xsl:for-each select="marc:subfield[@code='a']">
5093 <xsl:call-template name="uri" />
5094 <xsl:call-template name="chopPunctuation">
5095 <xsl:with-param name="chopString" select="."></xsl:with-param>
5096 </xsl:call-template>
5099 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
5102 <xsl:template match="marc:datafield[@tag=653]">
5104 <xsl:for-each select="marc:subfield[@code='a']">
5106 <xsl:call-template name="uri" />
5107 <xsl:value-of select="."></xsl:value-of>
5112 <xsl:template match="marc:datafield[@tag=656]">
5114 <xsl:if test="marc:subfield[@code=2]">
5115 <xsl:attribute name="authority">
5116 <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
5120 <xsl:call-template name="uri" />
5121 <xsl:call-template name="chopPunctuation">
5122 <xsl:with-param name="chopString">
5123 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
5125 </xsl:call-template>
5129 <xsl:template name="termsOfAddress">
5130 <xsl:if test="marc:subfield[@code='b' or @code='c']">
5131 <namePart type="termsOfAddress">
5132 <xsl:call-template name="chopPunctuation">
5133 <xsl:with-param name="chopString">
5134 <xsl:call-template name="subfieldSelect">
5135 <xsl:with-param name="codes">bc</xsl:with-param>
5136 </xsl:call-template>
5138 </xsl:call-template>
5142 <xsl:template name="displayLabel">
5143 <xsl:if test="marc:subfield[@code='i']">
5144 <xsl:attribute name="displayLabel">
5145 <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
5148 <xsl:if test="marc:subfield[@code='3']">
5149 <xsl:attribute name="displayLabel">
5150 <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
5154 <xsl:template name="isInvalid">
5155 <xsl:param name="type"/>
5156 <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
5158 <xsl:attribute name="type">
5159 <xsl:value-of select="$type"/>
5161 <xsl:attribute name="invalid">
5162 <xsl:text>yes</xsl:text>
5164 <xsl:if test="marc:subfield[@code='z']">
5165 <xsl:value-of select="marc:subfield[@code='z']"/>
5167 <xsl:if test="marc:subfield[@code='y']">
5168 <xsl:value-of select="marc:subfield[@code='y']"/>
5173 <xsl:template name="subtitle">
5174 <xsl:if test="marc:subfield[@code='b']">
5176 <xsl:call-template name="chopPunctuation">
5177 <xsl:with-param name="chopString">
5178 <xsl:value-of select="marc:subfield[@code='b']"/>
5179 <!--<xsl:call-template name="subfieldSelect">
5180 <xsl:with-param name="codes">b</xsl:with-param>
5181 </xsl:call-template>-->
5183 </xsl:call-template>
5187 <xsl:template name="script">
5188 <xsl:param name="scriptCode"></xsl:param>
5189 <xsl:attribute name="script">
5191 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
5192 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
5193 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
5194 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
5195 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
5196 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
5200 <xsl:template name="parsePart">
5201 <!-- assumes 773$q= 1:2:3<4
5202 with up to 3 levels and one optional start page
5204 <xsl:variable name="level1">
5206 <xsl:when test="contains(text(),':')">
5208 <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
5210 <xsl:when test="not(contains(text(),':'))">
5212 <xsl:if test="contains(text(),'<')">
5214 <xsl:value-of select="substring-before(text(),'<')"></xsl:value-of>
5216 <xsl:if test="not(contains(text(),'<'))">
5218 <xsl:value-of select="text()"></xsl:value-of>
5223 <xsl:variable name="sici2">
5225 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
5226 <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
5229 <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
5233 <xsl:variable name="level2">
5235 <xsl:when test="contains($sici2,':')">
5237 <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
5239 <xsl:when test="contains($sici2,'<')">
5241 <xsl:value-of select="substring-before($sici2,'<')"></xsl:value-of>
5244 <xsl:value-of select="$sici2"></xsl:value-of>
5249 <xsl:variable name="sici3">
5251 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
5252 <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
5255 <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
5259 <xsl:variable name="level3">
5261 <xsl:when test="contains($sici3,'<')">
5263 <xsl:value-of select="substring-before($sici3,'<')"></xsl:value-of>
5266 <xsl:value-of select="$sici3"></xsl:value-of>
5271 <xsl:variable name="page">
5272 <xsl:if test="contains(text(),'<')">
5273 <xsl:value-of select="substring-after(text(),'<')"></xsl:value-of>
5276 <xsl:if test="$level1">
5279 <xsl:value-of select="$level1"></xsl:value-of>
5283 <xsl:if test="$level2">
5286 <xsl:value-of select="$level2"></xsl:value-of>
5290 <xsl:if test="$level3">
5293 <xsl:value-of select="$level3"></xsl:value-of>
5297 <xsl:if test="$page">
5298 <extent unit="page">
5300 <xsl:value-of select="$page"></xsl:value-of>
5305 <xsl:template name="getLanguage">
5306 <xsl:param name="langString"></xsl:param>
5307 <xsl:param name="controlField008-35-37"></xsl:param>
5308 <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
5310 <xsl:when test="$length=0"></xsl:when>
5311 <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
5312 <xsl:call-template name="getLanguage">
5313 <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
5314 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
5315 </xsl:call-template>
5319 <languageTerm authority="iso639-2b" type="code">
5320 <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
5323 <xsl:call-template name="getLanguage">
5324 <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
5325 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
5326 </xsl:call-template>
5330 <xsl:template name="isoLanguage">
5331 <xsl:param name="currentLanguage"></xsl:param>
5332 <xsl:param name="usedLanguages"></xsl:param>
5333 <xsl:param name="remainingLanguages"></xsl:param>
5335 <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
5336 <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
5338 <xsl:if test="@code!='a'">
5339 <xsl:attribute name="objectPart">
5341 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
5342 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
5343 <xsl:when test="@code='e'">libretto</xsl:when>
5344 <xsl:when test="@code='f'">table of contents</xsl:when>
5345 <xsl:when test="@code='g'">accompanying material</xsl:when>
5346 <xsl:when test="@code='h'">translation</xsl:when>
5350 <languageTerm authority="iso639-2b" type="code">
5351 <xsl:value-of select="$currentLanguage"></xsl:value-of>
5354 <xsl:call-template name="isoLanguage">
5355 <xsl:with-param name="currentLanguage">
5356 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
5358 <xsl:with-param name="usedLanguages">
5359 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
5361 <xsl:with-param name="remainingLanguages">
5362 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
5364 </xsl:call-template>
5367 <xsl:call-template name="isoLanguage">
5368 <xsl:with-param name="currentLanguage">
5369 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
5371 <xsl:with-param name="usedLanguages">
5372 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
5374 <xsl:with-param name="remainingLanguages">
5375 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
5377 </xsl:call-template>
5381 <xsl:template name="chopBrackets">
5382 <xsl:param name="chopString"></xsl:param>
5383 <xsl:variable name="string">
5384 <xsl:call-template name="chopPunctuation">
5385 <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
5386 </xsl:call-template>
5388 <xsl:if test="substring($string, 1,1)='['">
5389 <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
5391 <xsl:if test="substring($string, 1,1)!='['">
5392 <xsl:value-of select="$string"></xsl:value-of>
5395 <xsl:template name="rfcLanguages">
5396 <xsl:param name="nodeNum"></xsl:param>
5397 <xsl:param name="usedLanguages"></xsl:param>
5398 <xsl:param name="controlField008-35-37"></xsl:param>
5399 <xsl:variable name="currentLanguage" select="."></xsl:variable>
5401 <xsl:when test="not($currentLanguage)"></xsl:when>
5402 <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
5403 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
5405 <xsl:if test="@code!='a'">
5406 <xsl:attribute name="objectPart">
5408 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
5409 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
5410 <xsl:when test="@code='e'">libretto</xsl:when>
5411 <xsl:when test="@code='f'">table of contents</xsl:when>
5412 <xsl:when test="@code='g'">accompanying material</xsl:when>
5413 <xsl:when test="@code='h'">translation</xsl:when>
5417 <languageTerm authority="rfc3066" type="code">
5418 <xsl:value-of select="$currentLanguage"/>
5427 <xsl:template name="datafield">
5428 <xsl:param name="tag"/>
5429 <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
5430 <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
5431 <xsl:param name="subfields"/>
5432 <xsl:element name="marc:datafield">
5433 <xsl:attribute name="tag">
5434 <xsl:value-of select="$tag"/>
5436 <xsl:attribute name="ind1">
5437 <xsl:value-of select="$ind1"/>
5439 <xsl:attribute name="ind2">
5440 <xsl:value-of select="$ind2"/>
5442 <xsl:copy-of select="$subfields"/>
5446 <xsl:template name="subfieldSelect">
5447 <xsl:param name="codes"/>
5448 <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
5449 <xsl:variable name="str">
5450 <xsl:for-each select="marc:subfield">
5451 <xsl:if test="contains($codes, @code)">
5452 <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
5456 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
5459 <xsl:template name="buildSpaces">
5460 <xsl:param name="spaces"/>
5461 <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
5462 <xsl:if test="$spaces>0">
5463 <xsl:value-of select="$char"/>
5464 <xsl:call-template name="buildSpaces">
5465 <xsl:with-param name="spaces" select="$spaces - 1"/>
5466 <xsl:with-param name="char" select="$char"/>
5467 </xsl:call-template>
5471 <xsl:template name="chopPunctuation">
5472 <xsl:param name="chopString"/>
5473 <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
5474 <xsl:variable name="length" select="string-length($chopString)"/>
5476 <xsl:when test="$length=0"/>
5477 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
5478 <xsl:call-template name="chopPunctuation">
5479 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
5480 <xsl:with-param name="punctuation" select="$punctuation"/>
5481 </xsl:call-template>
5483 <xsl:when test="not($chopString)"/>
5484 <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
5488 <xsl:template name="chopPunctuationFront">
5489 <xsl:param name="chopString"/>
5490 <xsl:variable name="length" select="string-length($chopString)"/>
5492 <xsl:when test="$length=0"/>
5493 <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
5494 <xsl:call-template name="chopPunctuationFront">
5495 <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
5496 </xsl:call-template>
5498 <xsl:when test="not($chopString)"/>
5499 <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
5502 </xsl:stylesheet>$$ WHERE name = 'mods32';
5505 -- 954.data.MODS33-xsl.sql
5506 UPDATE config.xml_transform SET xslt=$$<xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim"
5507 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5508 exclude-result-prefixes="xlink marc" version="1.0">
5509 <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
5511 <xsl:variable name="ascii">
5512 <xsl:text> !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
5515 <xsl:variable name="latin1">
5516 <xsl:text> ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
5518 <!-- Characters that usually don't need to be escaped -->
5519 <xsl:variable name="safe">
5520 <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
5523 <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
5525 <!-- Evergreen specific: revert Revision 1.23, so we can have those authority xlink attributes back. -->
5527 <!--MARC21slim2MODS3-3.xsl
5528 Revision 1.27 - Mapped 648 to <subject> 2009/03/13 tmee
5529 Revision 1.26 - Added subfield $s mapping for 130/240/730 2008/10/16 tmee
5530 Revision 1.25 - Mapped 040e to <descriptiveStandard> and Leader/18 to <descriptive standard>aacr2 2008/09/18 tmee
5531 Revision 1.24 - Mapped 852 subfields $h, $i, $j, $k, $l, $m, $t to <shelfLocation> and 852 subfield $u to <physicalLocation> with @xlink 2008/09/17 tmee
5532 Revision 1.23 - Commented out xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711 as these are currently unactionable 2008/09/17 tmee
5533 Revision 1.22 - Mapped 022 subfield $l to type "issn-l" subfield $m to output identifier element with corresponding @type and @invalid eq 'yes'2008/09/17 tmee
5534 Revision 1.21 - Mapped 856 ind2=1 or ind2=2 to <relatedItem><location><url> 2008/07/03 tmee
5535 Revision 1.20 - Added genre w/@auth="contents of 2" and type= "musical composition" 2008/07/01 tmee
5536 Revision 1.19 - Added genre offprint for 008/24+ BK code 2 2008/07/01 tmee
5537 Revision 1.18 - Added xlink/uri for subfield 0 for 130/240/730, 100/700, 110/710, 111/711 2008/06/26 tmee
5538 Revision 1.17 - Added mapping of 662 2008/05/14 tmee
5539 Revision 1.16 - Changed @authority from "marc" to "marcgt" for 007 and 008 codes mapped to a term in <genre> 2007/07/10 tmee
5540 Revision 1.15 - For field 630, moved call to part template outside title element 2007/07/10 tmee
5541 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
5542 Revision 1.13 - Changed order of output under cartographics to reflect schema 2006/11/28 tmee
5543 Revision 1.12 - Updated to reflect MODS 3.2 Mapping 2006/10/11 tmee
5544 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language> 2006/04/08 jrad
5545 Revision 1.10 - MODS 3.1 revisions to language and classification elements (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers) 2006/02/06 ggar
5546 Revision 1.9 - Subfield $y was added to field 242 2004/09/02 10:57 jrad
5547 Revision 1.8 - Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
5548 Revision 1.7 - 2004/03/25 08:29 jrad
5549 Revision 1.6 - Various validation fixes 2004/02/20 ntra
5550 Revision 1.5 - MODS2 to MODS3 updates, language unstacking and de-duping, chopPunctuation expanded 2003/10/02 16:18:58 ntra
5551 Revision 1.3 - Additional Changes not related to MODS Version 2.0 by ntra
5552 Revision 1.2 - Added Log Comment 2003/03/24 19:37:42 ckeith
5554 <xsl:template match="/">
5556 <xsl:when test="//marc:collection">
5557 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5558 xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
5559 <xsl:for-each select="//marc:collection/marc:record">
5560 <mods version="3.3">
5561 <xsl:call-template name="marcRecord"/>
5567 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
5568 xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
5569 <xsl:for-each select="//marc:record">
5570 <xsl:call-template name="marcRecord"/>
5576 <xsl:template name="marcRecord">
5577 <xsl:variable name="leader" select="marc:leader"/>
5578 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
5579 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
5580 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
5581 <xsl:variable name="typeOf008">
5583 <xsl:when test="$leader6='a'">
5586 test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
5587 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
5590 <xsl:when test="$leader6='t'">BK</xsl:when>
5591 <xsl:when test="$leader6='p'">MM</xsl:when>
5592 <xsl:when test="$leader6='m'">CF</xsl:when>
5593 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
5594 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
5595 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'"
5599 <xsl:for-each select="marc:datafield[@tag='245']">
5601 <xsl:variable name="title">
5603 <xsl:when test="marc:subfield[@code='b']">
5604 <xsl:call-template name="specialSubfieldSelect">
5605 <xsl:with-param name="axis">b</xsl:with-param>
5606 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
5607 </xsl:call-template>
5610 <xsl:call-template name="subfieldSelect">
5611 <xsl:with-param name="codes">abfgk</xsl:with-param>
5612 </xsl:call-template>
5616 <xsl:variable name="titleChop">
5617 <xsl:call-template name="chopPunctuation">
5618 <xsl:with-param name="chopString">
5619 <xsl:value-of select="$title"/>
5621 </xsl:call-template>
5624 <xsl:when test="@ind2>0">
5626 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
5629 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
5634 <xsl:value-of select="$titleChop"/>
5638 <xsl:if test="marc:subfield[@code='b']">
5640 <xsl:call-template name="chopPunctuation">
5641 <xsl:with-param name="chopString">
5642 <xsl:call-template name="specialSubfieldSelect">
5643 <xsl:with-param name="axis">b</xsl:with-param>
5644 <xsl:with-param name="anyCodes">b</xsl:with-param>
5645 <xsl:with-param name="afterCodes">afgk</xsl:with-param>
5646 </xsl:call-template>
5648 </xsl:call-template>
5651 <xsl:call-template name="part"/>
5654 <xsl:for-each select="marc:datafield[@tag='210']">
5655 <titleInfo type="abbreviated">
5657 <xsl:call-template name="chopPunctuation">
5658 <xsl:with-param name="chopString">
5659 <xsl:call-template name="subfieldSelect">
5660 <xsl:with-param name="codes">a</xsl:with-param>
5661 </xsl:call-template>
5663 </xsl:call-template>
5665 <xsl:call-template name="subtitle"/>
5668 <xsl:for-each select="marc:datafield[@tag='242']">
5669 <titleInfo type="translated">
5670 <!--09/01/04 Added subfield $y-->
5671 <xsl:for-each select="marc:subfield[@code='y']">
5672 <xsl:attribute name="lang">
5673 <xsl:value-of select="text()"/>
5676 <xsl:for-each select="marc:subfield[@code='i']">
5677 <xsl:attribute name="displayLabel">
5678 <xsl:value-of select="text()"/>
5682 <xsl:call-template name="chopPunctuation">
5683 <xsl:with-param name="chopString">
5684 <xsl:call-template name="subfieldSelect">
5685 <!-- 1/04 removed $h, b -->
5686 <xsl:with-param name="codes">a</xsl:with-param>
5687 </xsl:call-template>
5689 </xsl:call-template>
5692 <xsl:call-template name="subtitle"/>
5693 <xsl:call-template name="part"/>
5696 <xsl:for-each select="marc:datafield[@tag='246']">
5697 <titleInfo type="alternative">
5698 <xsl:for-each select="marc:subfield[@code='i']">
5699 <xsl:attribute name="displayLabel">
5700 <xsl:value-of select="text()"/>
5704 <xsl:call-template name="chopPunctuation">
5705 <xsl:with-param name="chopString">
5706 <xsl:call-template name="subfieldSelect">
5707 <!-- 1/04 removed $h, $b -->
5708 <xsl:with-param name="codes">af</xsl:with-param>
5709 </xsl:call-template>
5711 </xsl:call-template>
5713 <xsl:call-template name="subtitle"/>
5714 <xsl:call-template name="part"/>
5718 select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
5719 <titleInfo type="uniform">
5721 <xsl:call-template name="uri"/>
5723 <xsl:variable name="str">
5724 <xsl:for-each select="marc:subfield">
5726 test="(contains('adfklmors',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
5727 <xsl:value-of select="text()"/>
5728 <xsl:text> </xsl:text>
5732 <xsl:call-template name="chopPunctuation">
5733 <xsl:with-param name="chopString">
5734 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
5736 </xsl:call-template>
5738 <xsl:call-template name="part"/>
5741 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
5742 <titleInfo type="alternative">
5744 <xsl:call-template name="chopPunctuation">
5745 <xsl:with-param name="chopString">
5746 <xsl:call-template name="subfieldSelect">
5747 <xsl:with-param name="codes">ah</xsl:with-param>
5748 </xsl:call-template>
5750 </xsl:call-template>
5752 <xsl:call-template name="part"/>
5755 <xsl:for-each select="marc:datafield[@tag='100']">
5756 <name type="personal">
5758 <xsl:call-template name="uri"/>
5760 <xsl:call-template name="nameABCDQ"/>
5761 <xsl:call-template name="affiliation"/>
5763 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5765 <xsl:call-template name="role"/>
5768 <xsl:for-each select="marc:datafield[@tag='110']">
5769 <name type="corporate">
5771 <xsl:call-template name="uri"/>
5773 <xsl:call-template name="nameABCDN"/>
5775 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5777 <xsl:call-template name="role"/>
5780 <xsl:for-each select="marc:datafield[@tag='111']">
5781 <name type="conference">
5783 <xsl:call-template name="uri"/>
5785 <xsl:call-template name="nameACDEQ"/>
5787 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
5789 <xsl:call-template name="role"/>
5792 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
5793 <name type="personal">
5795 <xsl:call-template name="uri"/>
5797 <xsl:call-template name="nameABCDQ"/>
5798 <xsl:call-template name="affiliation"/>
5799 <xsl:call-template name="role"/>
5802 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
5803 <name type="corporate">
5805 <xsl:call-template name="uri"/>
5807 <xsl:call-template name="nameABCDN"/>
5808 <xsl:call-template name="role"/>
5811 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
5812 <name type="conference">
5814 <xsl:call-template name="uri"/>
5816 <xsl:call-template name="nameACDEQ"/>
5817 <xsl:call-template name="role"/>
5820 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
5822 <xsl:if test="@ind1=1">
5823 <xsl:attribute name="type">
5824 <xsl:text>personal</xsl:text>
5828 <xsl:value-of select="marc:subfield[@code='a']"/>
5830 <xsl:call-template name="role"/>
5834 <xsl:if test="$leader7='c'">
5835 <xsl:attribute name="collection">yes</xsl:attribute>
5837 <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
5838 <xsl:attribute name="manuscript">yes</xsl:attribute>
5841 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
5842 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
5843 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
5844 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
5845 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
5846 <xsl:when test="$leader6='k'">still image</xsl:when>
5847 <xsl:when test="$leader6='g'">moving image</xsl:when>
5848 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
5849 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
5850 <xsl:when test="$leader6='p'">mixed material</xsl:when>
5853 <xsl:if test="substring($controlField008,26,1)='d'">
5854 <genre authority="marcgt">globe</genre>
5857 test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
5858 <genre authority="marcgt">remote-sensing image</genre>
5860 <xsl:if test="$typeOf008='MP'">
5861 <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"/>
5864 test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
5865 <genre authority="marcgt">map</genre>
5868 test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
5869 <genre authority="marcgt">atlas</genre>
5873 <xsl:if test="$typeOf008='SE'">
5874 <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"/>
5876 <xsl:when test="$controlField008-21='d'">
5877 <genre authority="marcgt">database</genre>
5879 <xsl:when test="$controlField008-21='l'">
5880 <genre authority="marcgt">loose-leaf</genre>
5882 <xsl:when test="$controlField008-21='m'">
5883 <genre authority="marcgt">series</genre>
5885 <xsl:when test="$controlField008-21='n'">
5886 <genre authority="marcgt">newspaper</genre>
5888 <xsl:when test="$controlField008-21='p'">
5889 <genre authority="marcgt">periodical</genre>
5891 <xsl:when test="$controlField008-21='w'">
5892 <genre authority="marcgt">web site</genre>
5896 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
5897 <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"/>
5899 <xsl:when test="contains($controlField008-24,'a')">
5900 <genre authority="marcgt">abstract or summary</genre>
5902 <xsl:when test="contains($controlField008-24,'b')">
5903 <genre authority="marcgt">bibliography</genre>
5905 <xsl:when test="contains($controlField008-24,'c')">
5906 <genre authority="marcgt">catalog</genre>
5908 <xsl:when test="contains($controlField008-24,'d')">
5909 <genre authority="marcgt">dictionary</genre>
5911 <xsl:when test="contains($controlField008-24,'e')">
5912 <genre authority="marcgt">encyclopedia</genre>
5914 <xsl:when test="contains($controlField008-24,'f')">
5915 <genre authority="marcgt">handbook</genre>
5917 <xsl:when test="contains($controlField008-24,'g')">
5918 <genre authority="marcgt">legal article</genre>
5920 <xsl:when test="contains($controlField008-24,'i')">
5921 <genre authority="marcgt">index</genre>
5923 <xsl:when test="contains($controlField008-24,'k')">
5924 <genre authority="marcgt">discography</genre>
5926 <xsl:when test="contains($controlField008-24,'l')">
5927 <genre authority="marcgt">legislation</genre>
5929 <xsl:when test="contains($controlField008-24,'m')">
5930 <genre authority="marcgt">theses</genre>
5932 <xsl:when test="contains($controlField008-24,'n')">
5933 <genre authority="marcgt">survey of literature</genre>
5935 <xsl:when test="contains($controlField008-24,'o')">
5936 <genre authority="marcgt">review</genre>
5938 <xsl:when test="contains($controlField008-24,'p')">
5939 <genre authority="marcgt">programmed text</genre>
5941 <xsl:when test="contains($controlField008-24,'q')">
5942 <genre authority="marcgt">filmography</genre>
5944 <xsl:when test="contains($controlField008-24,'r')">
5945 <genre authority="marcgt">directory</genre>
5947 <xsl:when test="contains($controlField008-24,'s')">
5948 <genre authority="marcgt">statistics</genre>
5950 <xsl:when test="contains($controlField008-24,'t')">
5951 <genre authority="marcgt">technical report</genre>
5953 <xsl:when test="contains($controlField008-24,'v')">
5954 <genre authority="marcgt">legal case and case notes</genre>
5956 <xsl:when test="contains($controlField008-24,'w')">
5957 <genre authority="marcgt">law report or digest</genre>
5959 <xsl:when test="contains($controlField008-24,'z')">
5960 <genre authority="marcgt">treaty</genre>
5963 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
5965 <xsl:when test="$controlField008-29='1'">
5966 <genre authority="marcgt">conference publication</genre>
5970 <xsl:if test="$typeOf008='CF'">
5971 <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"/>
5973 <xsl:when test="$controlField008-26='a'">
5974 <genre authority="marcgt">numeric data</genre>
5976 <xsl:when test="$controlField008-26='e'">
5977 <genre authority="marcgt">database</genre>
5979 <xsl:when test="$controlField008-26='f'">
5980 <genre authority="marcgt">font</genre>
5982 <xsl:when test="$controlField008-26='g'">
5983 <genre authority="marcgt">game</genre>
5987 <xsl:if test="$typeOf008='BK'">
5988 <xsl:if test="substring($controlField008,25,1)='j'">
5989 <genre authority="marcgt">patent</genre>
5991 <xsl:if test="substring($controlField008,25,1)='2'">
5992 <genre authority="marcgt">offprint</genre>
5994 <xsl:if test="substring($controlField008,31,1)='1'">
5995 <genre authority="marcgt">festschrift</genre>
5997 <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"/>
5999 test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
6000 <genre authority="marcgt">biography</genre>
6002 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
6004 <xsl:when test="$controlField008-33='e'">
6005 <genre authority="marcgt">essay</genre>
6007 <xsl:when test="$controlField008-33='d'">
6008 <genre authority="marcgt">drama</genre>
6010 <xsl:when test="$controlField008-33='c'">
6011 <genre authority="marcgt">comic strip</genre>
6013 <xsl:when test="$controlField008-33='l'">
6014 <genre authority="marcgt">fiction</genre>
6016 <xsl:when test="$controlField008-33='h'">
6017 <genre authority="marcgt">humor, satire</genre>
6019 <xsl:when test="$controlField008-33='i'">
6020 <genre authority="marcgt">letter</genre>
6022 <xsl:when test="$controlField008-33='f'">
6023 <genre authority="marcgt">novel</genre>
6025 <xsl:when test="$controlField008-33='j'">
6026 <genre authority="marcgt">short story</genre>
6028 <xsl:when test="$controlField008-33='s'">
6029 <genre authority="marcgt">speech</genre>
6033 <xsl:if test="$typeOf008='MU'">
6034 <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>
6035 <xsl:if test="contains($controlField008-30-31,'b')">
6036 <genre authority="marcgt">biography</genre>
6038 <xsl:if test="contains($controlField008-30-31,'c')">
6039 <genre authority="marcgt">conference publication</genre>
6041 <xsl:if test="contains($controlField008-30-31,'d')">
6042 <genre authority="marcgt">drama</genre>
6044 <xsl:if test="contains($controlField008-30-31,'e')">
6045 <genre authority="marcgt">essay</genre>
6047 <xsl:if test="contains($controlField008-30-31,'f')">
6048 <genre authority="marcgt">fiction</genre>
6050 <xsl:if test="contains($controlField008-30-31,'o')">
6051 <genre authority="marcgt">folktale</genre>
6053 <xsl:if test="contains($controlField008-30-31,'h')">
6054 <genre authority="marcgt">history</genre>
6056 <xsl:if test="contains($controlField008-30-31,'k')">
6057 <genre authority="marcgt">humor, satire</genre>
6059 <xsl:if test="contains($controlField008-30-31,'m')">
6060 <genre authority="marcgt">memoir</genre>
6062 <xsl:if test="contains($controlField008-30-31,'p')">
6063 <genre authority="marcgt">poetry</genre>
6065 <xsl:if test="contains($controlField008-30-31,'r')">
6066 <genre authority="marcgt">rehearsal</genre>
6068 <xsl:if test="contains($controlField008-30-31,'g')">
6069 <genre authority="marcgt">reporting</genre>
6071 <xsl:if test="contains($controlField008-30-31,'s')">
6072 <genre authority="marcgt">sound</genre>
6074 <xsl:if test="contains($controlField008-30-31,'l')">
6075 <genre authority="marcgt">speech</genre>
6078 <xsl:if test="$typeOf008='VM'">
6079 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"/>
6081 <xsl:when test="$controlField008-33='a'">
6082 <genre authority="marcgt">art original</genre>
6084 <xsl:when test="$controlField008-33='b'">
6085 <genre authority="marcgt">kit</genre>
6087 <xsl:when test="$controlField008-33='c'">
6088 <genre authority="marcgt">art reproduction</genre>
6090 <xsl:when test="$controlField008-33='d'">
6091 <genre authority="marcgt">diorama</genre>
6093 <xsl:when test="$controlField008-33='f'">
6094 <genre authority="marcgt">filmstrip</genre>
6096 <xsl:when test="$controlField008-33='g'">
6097 <genre authority="marcgt">legal article</genre>
6099 <xsl:when test="$controlField008-33='i'">
6100 <genre authority="marcgt">picture</genre>
6102 <xsl:when test="$controlField008-33='k'">
6103 <genre authority="marcgt">graphic</genre>
6105 <xsl:when test="$controlField008-33='l'">
6106 <genre authority="marcgt">technical drawing</genre>
6108 <xsl:when test="$controlField008-33='m'">
6109 <genre authority="marcgt">motion picture</genre>
6111 <xsl:when test="$controlField008-33='n'">
6112 <genre authority="marcgt">chart</genre>
6114 <xsl:when test="$controlField008-33='o'">
6115 <genre authority="marcgt">flash card</genre>
6117 <xsl:when test="$controlField008-33='p'">
6118 <genre authority="marcgt">microscope slide</genre>
6121 test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
6122 <genre authority="marcgt">model</genre>
6124 <xsl:when test="$controlField008-33='r'">
6125 <genre authority="marcgt">realia</genre>
6127 <xsl:when test="$controlField008-33='s'">
6128 <genre authority="marcgt">slide</genre>
6130 <xsl:when test="$controlField008-33='t'">
6131 <genre authority="marcgt">transparency</genre>
6133 <xsl:when test="$controlField008-33='v'">
6134 <genre authority="marcgt">videorecording</genre>
6136 <xsl:when test="$controlField008-33='w'">
6137 <genre authority="marcgt">toy</genre>
6142 <!-- 1.20 047 genre tmee-->
6144 <xsl:for-each select="marc:datafield[@tag=047]">
6145 <genre authority="marcgt">
6146 <xsl:attribute name="authority">
6147 <xsl:value-of select="marc:subfield[@code='2']"/>
6149 <xsl:call-template name="subfieldSelect">
6150 <xsl:with-param name="codes">abcdef</xsl:with-param>
6151 <xsl:with-param name="delimeter">-</xsl:with-param>
6152 </xsl:call-template>
6155 <xsl:for-each select="marc:datafield[@tag=655]">
6156 <genre authority="marcgt">
6157 <xsl:attribute name="authority">
6158 <xsl:value-of select="marc:subfield[@code='2']"/>
6160 <xsl:call-template name="subfieldSelect">
6161 <xsl:with-param name="codes">abvxyz</xsl:with-param>
6162 <xsl:with-param name="delimeter">-</xsl:with-param>
6163 </xsl:call-template>
6167 <xsl:variable name="MARCpublicationCode"
6168 select="normalize-space(substring($controlField008,16,3))"/>
6169 <xsl:if test="translate($MARCpublicationCode,'|','')">
6172 <xsl:attribute name="type">code</xsl:attribute>
6173 <xsl:attribute name="authority">marccountry</xsl:attribute>
6174 <xsl:value-of select="$MARCpublicationCode"/>
6178 <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
6181 <xsl:attribute name="type">code</xsl:attribute>
6182 <xsl:attribute name="authority">iso3166</xsl:attribute>
6183 <xsl:value-of select="."/>
6187 <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
6190 <xsl:attribute name="type">text</xsl:attribute>
6191 <xsl:call-template name="chopPunctuationFront">
6192 <xsl:with-param name="chopString">
6193 <xsl:call-template name="chopPunctuation">
6194 <xsl:with-param name="chopString" select="."/>
6195 </xsl:call-template>
6197 </xsl:call-template>
6201 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
6202 <dateValid point="start">
6203 <xsl:value-of select="."/>
6206 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
6207 <dateValid point="end">
6208 <xsl:value-of select="."/>
6211 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
6213 <xsl:value-of select="."/>
6217 select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
6219 <xsl:when test="@code='b'">
6221 <xsl:call-template name="chopPunctuation">
6222 <xsl:with-param name="chopString" select="."/>
6223 <xsl:with-param name="punctuation">
6224 <xsl:text>:,;/ </xsl:text>
6226 </xsl:call-template>
6229 <xsl:when test="@code='c'">
6231 <xsl:call-template name="chopPunctuation">
6232 <xsl:with-param name="chopString" select="."/>
6233 </xsl:call-template>
6236 <xsl:when test="@code='g'">
6238 <xsl:value-of select="."/>
6243 <xsl:variable name="dataField260c">
6244 <xsl:call-template name="chopPunctuation">
6245 <xsl:with-param name="chopString"
6246 select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
6247 </xsl:call-template>
6249 <xsl:variable name="controlField008-7-10"
6250 select="normalize-space(substring($controlField008, 8, 4))"/>
6251 <xsl:variable name="controlField008-11-14"
6252 select="normalize-space(substring($controlField008, 12, 4))"/>
6253 <xsl:variable name="controlField008-6"
6254 select="normalize-space(substring($controlField008, 7, 1))"/>
6256 test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
6257 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
6258 <dateIssued encoding="marc">
6259 <xsl:value-of select="$controlField008-7-10"/>
6264 test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
6265 <xsl:if test="$controlField008-7-10">
6266 <dateIssued encoding="marc" point="start">
6267 <xsl:value-of select="$controlField008-7-10"/>
6272 test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
6273 <xsl:if test="$controlField008-11-14">
6274 <dateIssued encoding="marc" point="end">
6275 <xsl:value-of select="$controlField008-11-14"/>
6279 <xsl:if test="$controlField008-6='q'">
6280 <xsl:if test="$controlField008-7-10">
6281 <dateIssued encoding="marc" point="start" qualifier="questionable">
6282 <xsl:value-of select="$controlField008-7-10"/>
6286 <xsl:if test="$controlField008-6='q'">
6287 <xsl:if test="$controlField008-11-14">
6288 <dateIssued encoding="marc" point="end" qualifier="questionable">
6289 <xsl:value-of select="$controlField008-11-14"/>
6293 <xsl:if test="$controlField008-6='t'">
6294 <xsl:if test="$controlField008-11-14">
6295 <copyrightDate encoding="marc">
6296 <xsl:value-of select="$controlField008-11-14"/>
6301 select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
6302 <dateCaptured encoding="iso8601">
6303 <xsl:value-of select="."/>
6306 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
6307 <dateCaptured encoding="iso8601" point="start">
6308 <xsl:value-of select="."/>
6311 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
6312 <dateCaptured encoding="iso8601" point="end">
6313 <xsl:value-of select="."/>
6316 <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
6318 <xsl:value-of select="."/>
6321 <xsl:for-each select="marc:leader">
6325 test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'"
6326 >monographic</xsl:when>
6327 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'"
6328 >continuing</xsl:when>
6332 <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
6334 <xsl:call-template name="subfieldSelect">
6335 <xsl:with-param name="codes">ab</xsl:with-param>
6336 </xsl:call-template>
6340 <xsl:variable name="controlField008-35-37"
6341 select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"/>
6342 <xsl:if test="$controlField008-35-37">
6344 <languageTerm authority="iso639-2b" type="code">
6345 <xsl:value-of select="substring($controlField008,36,3)"/>
6349 <xsl:for-each select="marc:datafield[@tag=041]">
6351 select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
6352 <xsl:variable name="langCodes" select="."/>
6354 <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
6355 <!-- not stacked but could be repeated -->
6356 <xsl:call-template name="rfcLanguages">
6357 <xsl:with-param name="nodeNum">
6358 <xsl:value-of select="1"/>
6360 <xsl:with-param name="usedLanguages">
6363 <xsl:with-param name="controlField008-35-37">
6364 <xsl:value-of select="$controlField008-35-37"/>
6366 </xsl:call-template>
6370 <xsl:variable name="allLanguages">
6371 <xsl:copy-of select="$langCodes"/>
6373 <xsl:variable name="currentLanguage">
6374 <xsl:value-of select="substring($allLanguages,1,3)"/>
6376 <xsl:call-template name="isoLanguage">
6377 <xsl:with-param name="currentLanguage">
6378 <xsl:value-of select="substring($allLanguages,1,3)"/>
6380 <xsl:with-param name="remainingLanguages">
6382 select="substring($allLanguages,4,string-length($allLanguages)-3)"
6385 <xsl:with-param name="usedLanguages">
6386 <xsl:if test="$controlField008-35-37">
6387 <xsl:value-of select="$controlField008-35-37"/>
6390 </xsl:call-template>
6395 <xsl:variable name="physicalDescription">
6396 <!--3.2 change tmee 007/11 -->
6397 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
6398 <digitalOrigin>reformatted digital</digitalOrigin>
6400 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
6401 <digitalOrigin>digitized microfilm</digitalOrigin>
6403 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
6404 <digitalOrigin>digitized other analog</digitalOrigin>
6406 <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"/>
6407 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"/>
6408 <xsl:variable name="check008-23">
6410 test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
6411 <xsl:value-of select="true()"/>
6414 <xsl:variable name="check008-29">
6415 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
6416 <xsl:value-of select="true()"/>
6421 test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
6422 <form authority="marcform">braille</form>
6425 test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
6426 <form authority="marcform">print</form>
6429 test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
6430 <form authority="marcform">electronic</form>
6433 test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
6434 <form authority="marcform">microfiche</form>
6437 test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
6438 <form authority="marcform">microfilm</form>
6442 <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
6443 <form authority="gmd">
6444 <xsl:call-template name="chopBrackets">
6445 <xsl:with-param name="chopString">
6446 <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"
6449 </xsl:call-template>
6452 <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
6453 <form authority="gmd">
6454 <xsl:call-template name="chopBrackets">
6455 <xsl:with-param name="chopString">
6456 <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"
6459 </xsl:call-template>
6462 <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
6463 <form authority="gmd">
6464 <xsl:call-template name="chopBrackets">
6465 <xsl:with-param name="chopString">
6466 <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"
6469 </xsl:call-template>
6472 <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
6473 <form authority="gmd">
6474 <xsl:call-template name="chopBrackets">
6475 <xsl:with-param name="chopString">
6476 <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"
6479 </xsl:call-template>
6482 <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
6483 <form authority="gmd">
6484 <xsl:call-template name="chopBrackets">
6485 <xsl:with-param name="chopString">
6486 <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"
6489 </xsl:call-template>
6492 <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
6493 <form authority="gmd">
6494 <xsl:call-template name="chopBrackets">
6495 <xsl:with-param name="chopString">
6496 <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"
6499 </xsl:call-template>
6502 <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
6504 <xsl:value-of select="."/>
6507 <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
6509 <xsl:when test="substring(text(),14,1)='a'">
6510 <reformattingQuality>access</reformattingQuality>
6512 <xsl:when test="substring(text(),14,1)='p'">
6513 <reformattingQuality>preservation</reformattingQuality>
6515 <xsl:when test="substring(text(),14,1)='r'">
6516 <reformattingQuality>replacement</reformattingQuality>
6520 <!--3.2 change tmee 007/01 -->
6522 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
6523 <form authority="smd">chip cartridge</form>
6526 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
6527 <form authority="smd">computer optical disc cartridge</form>
6530 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
6531 <form authority="smd">magnetic disc</form>
6534 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
6535 <form authority="smd">magneto-optical disc</form>
6538 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
6539 <form authority="smd">optical disc</form>
6542 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
6543 <form authority="smd">remote</form>
6546 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
6547 <form authority="smd">tape cartridge</form>
6550 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
6551 <form authority="smd">tape cassette</form>
6554 test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
6555 <form authority="smd">tape reel</form>
6559 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
6560 <form authority="smd">celestial globe</form>
6563 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
6564 <form authority="smd">earth moon globe</form>
6567 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
6568 <form authority="smd">planetary or lunar globe</form>
6571 test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
6572 <form authority="smd">terrestrial globe</form>
6576 test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
6577 <form authority="smd">kit</form>
6581 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
6582 <form authority="smd">atlas</form>
6585 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
6586 <form authority="smd">diagram</form>
6589 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
6590 <form authority="smd">map</form>
6593 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
6594 <form authority="smd">model</form>
6597 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
6598 <form authority="smd">profile</form>
6601 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
6602 <form authority="smd">remote-sensing image</form>
6605 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
6606 <form authority="smd">section</form>
6609 test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
6610 <form authority="smd">view</form>
6614 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
6615 <form authority="smd">aperture card</form>
6618 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
6619 <form authority="smd">microfiche</form>
6622 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
6623 <form authority="smd">microfiche cassette</form>
6626 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
6627 <form authority="smd">microfilm cartridge</form>
6630 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
6631 <form authority="smd">microfilm cassette</form>
6634 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
6635 <form authority="smd">microfilm reel</form>
6638 test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
6639 <form authority="smd">microopaque</form>
6643 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
6644 <form authority="smd">film cartridge</form>
6647 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
6648 <form authority="smd">film cassette</form>
6651 test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
6652 <form authority="smd">film reel</form>
6656 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
6657 <form authority="smd">chart</form>
6660 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
6661 <form authority="smd">collage</form>
6664 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
6665 <form authority="smd">drawing</form>
6668 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
6669 <form authority="smd">flash card</form>
6672 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
6673 <form authority="smd">painting</form>
6676 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
6677 <form authority="smd">photomechanical print</form>
6680 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
6681 <form authority="smd">photonegative</form>
6684 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
6685 <form authority="smd">photoprint</form>
6688 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
6689 <form authority="smd">picture</form>
6692 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
6693 <form authority="smd">print</form>
6696 test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
6697 <form authority="smd">technical drawing</form>
6701 test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
6702 <form authority="smd">notated music</form>
6706 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
6707 <form authority="smd">filmslip</form>
6710 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
6711 <form authority="smd">filmstrip cartridge</form>
6714 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
6715 <form authority="smd">filmstrip roll</form>
6718 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
6719 <form authority="smd">other filmstrip type</form>
6722 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
6723 <form authority="smd">slide</form>
6726 test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
6727 <form authority="smd">transparency</form>
6730 test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
6731 <form authority="smd">remote-sensing image</form>
6734 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
6735 <form authority="smd">cylinder</form>
6738 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
6739 <form authority="smd">roll</form>
6742 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
6743 <form authority="smd">sound cartridge</form>
6746 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
6747 <form authority="smd">sound cassette</form>
6750 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
6751 <form authority="smd">sound disc</form>
6754 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
6755 <form authority="smd">sound-tape reel</form>
6758 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
6759 <form authority="smd">sound-track film</form>
6762 test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
6763 <form authority="smd">wire recording</form>
6767 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
6768 <form authority="smd">braille</form>
6771 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
6772 <form authority="smd">combination</form>
6775 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
6776 <form authority="smd">moon</form>
6779 test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
6780 <form authority="smd">tactile, with no writing system</form>
6784 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
6785 <form authority="smd">braille</form>
6788 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
6789 <form authority="smd">large print</form>
6792 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
6793 <form authority="smd">regular print</form>
6796 test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
6797 <form authority="smd">text in looseleaf binder</form>
6801 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
6802 <form authority="smd">videocartridge</form>
6805 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
6806 <form authority="smd">videocassette</form>
6809 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
6810 <form authority="smd">videodisc</form>
6813 test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
6814 <form authority="smd">videoreel</form>
6818 select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
6820 <xsl:value-of select="."/>
6821 </internetMediaType>
6823 <xsl:for-each select="marc:datafield[@tag=300]">
6825 <xsl:call-template name="subfieldSelect">
6826 <xsl:with-param name="codes">abce</xsl:with-param>
6827 </xsl:call-template>
6831 <xsl:if test="string-length(normalize-space($physicalDescription))">
6832 <physicalDescription>
6833 <xsl:copy-of select="$physicalDescription"/>
6834 </physicalDescription>
6836 <xsl:for-each select="marc:datafield[@tag=520]">
6838 <xsl:call-template name="uri"/>
6839 <xsl:call-template name="subfieldSelect">
6840 <xsl:with-param name="codes">ab</xsl:with-param>
6841 </xsl:call-template>
6844 <xsl:for-each select="marc:datafield[@tag=505]">
6846 <xsl:call-template name="uri"/>
6847 <xsl:call-template name="subfieldSelect">
6848 <xsl:with-param name="codes">agrt</xsl:with-param>
6849 </xsl:call-template>
6852 <xsl:for-each select="marc:datafield[@tag=521]">
6854 <xsl:call-template name="subfieldSelect">
6855 <xsl:with-param name="codes">ab</xsl:with-param>
6856 </xsl:call-template>
6859 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
6860 <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"/>
6863 <xsl:when test="$controlField008-22='d'">
6864 <targetAudience authority="marctarget">adolescent</targetAudience>
6866 <xsl:when test="$controlField008-22='e'">
6867 <targetAudience authority="marctarget">adult</targetAudience>
6869 <xsl:when test="$controlField008-22='g'">
6870 <targetAudience authority="marctarget">general</targetAudience>
6873 test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
6874 <targetAudience authority="marctarget">juvenile</targetAudience>
6876 <xsl:when test="$controlField008-22='a'">
6877 <targetAudience authority="marctarget">preschool</targetAudience>
6879 <xsl:when test="$controlField008-22='f'">
6880 <targetAudience authority="marctarget">specialized</targetAudience>
6884 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
6885 <note type="statement of responsibility">
6886 <xsl:value-of select="."/>
6889 <xsl:for-each select="marc:datafield[@tag=500]">
6891 <xsl:value-of select="marc:subfield[@code='a']"/>
6892 <xsl:call-template name="uri"/>
6896 <!--3.2 change tmee additional note fields-->
6898 <xsl:for-each select="marc:datafield[@tag=506]">
6899 <note type="restrictions">
6900 <xsl:call-template name="uri"/>
6901 <xsl:variable name="str">
6902 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6903 <xsl:value-of select="."/>
6904 <xsl:text> </xsl:text>
6907 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6911 <xsl:for-each select="marc:datafield[@tag=510]">
6912 <note type="citation/reference">
6913 <xsl:call-template name="uri"/>
6914 <xsl:variable name="str">
6915 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6916 <xsl:value-of select="."/>
6917 <xsl:text> </xsl:text>
6920 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6925 <xsl:for-each select="marc:datafield[@tag=511]">
6926 <note type="performers">
6927 <xsl:call-template name="uri"/>
6928 <xsl:value-of select="marc:subfield[@code='a']"/>
6931 <xsl:for-each select="marc:datafield[@tag=518]">
6933 <xsl:call-template name="uri"/>
6934 <xsl:value-of select="marc:subfield[@code='a']"/>
6938 <xsl:for-each select="marc:datafield[@tag=530]">
6939 <note type="additional physical form">
6940 <xsl:call-template name="uri"/>
6941 <xsl:variable name="str">
6942 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6943 <xsl:value-of select="."/>
6944 <xsl:text> </xsl:text>
6947 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6951 <xsl:for-each select="marc:datafield[@tag=533]">
6952 <note type="reproduction">
6953 <xsl:call-template name="uri"/>
6954 <xsl:variable name="str">
6955 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6956 <xsl:value-of select="."/>
6957 <xsl:text> </xsl:text>
6960 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6964 <xsl:for-each select="marc:datafield[@tag=534]">
6965 <note type="original version">
6966 <xsl:call-template name="uri"/>
6967 <xsl:variable name="str">
6968 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6969 <xsl:value-of select="."/>
6970 <xsl:text> </xsl:text>
6973 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6977 <xsl:for-each select="marc:datafield[@tag=538]">
6978 <note type="system details">
6979 <xsl:call-template name="uri"/>
6980 <xsl:variable name="str">
6981 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6982 <xsl:value-of select="."/>
6983 <xsl:text> </xsl:text>
6986 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
6990 <xsl:for-each select="marc:datafield[@tag=583]">
6991 <note type="action">
6992 <xsl:call-template name="uri"/>
6993 <xsl:variable name="str">
6994 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
6995 <xsl:value-of select="."/>
6996 <xsl:text> </xsl:text>
6999 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
7004 select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
7006 <xsl:call-template name="uri"/>
7007 <xsl:variable name="str">
7008 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
7009 <xsl:value-of select="."/>
7010 <xsl:text> </xsl:text>
7013 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
7017 select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
7021 <xsl:call-template name="subfieldSelect">
7022 <xsl:with-param name="codes">defg</xsl:with-param>
7023 </xsl:call-template>
7028 <xsl:for-each select="marc:datafield[@tag=043]">
7030 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
7032 <xsl:attribute name="authority">
7033 <xsl:if test="@code='a'">
7034 <xsl:text>marcgac</xsl:text>
7036 <xsl:if test="@code='b'">
7037 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"/>
7039 <xsl:if test="@code='c'">
7040 <xsl:text>iso3166</xsl:text>
7043 <xsl:value-of select="self::marc:subfield"/>
7048 <!-- tmee 2006/11/27 -->
7049 <xsl:for-each select="marc:datafield[@tag=255]">
7051 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
7053 <xsl:if test="@code='a'">
7055 <xsl:value-of select="."/>
7058 <xsl:if test="@code='b'">
7060 <xsl:value-of select="."/>
7063 <xsl:if test="@code='c'">
7065 <xsl:value-of select="."/>
7073 <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"/>
7074 <xsl:apply-templates select="marc:datafield[@tag=656]"/>
7075 <xsl:for-each select="marc:datafield[@tag=752 or @tag=662]">
7077 <hierarchicalGeographic>
7078 <xsl:for-each select="marc:subfield[@code='a']">
7080 <xsl:call-template name="chopPunctuation">
7081 <xsl:with-param name="chopString" select="."/>
7082 </xsl:call-template>
7085 <xsl:for-each select="marc:subfield[@code='b']">
7087 <xsl:call-template name="chopPunctuation">
7088 <xsl:with-param name="chopString" select="."/>
7089 </xsl:call-template>
7092 <xsl:for-each select="marc:subfield[@code='c']">
7094 <xsl:call-template name="chopPunctuation">
7095 <xsl:with-param name="chopString" select="."/>
7096 </xsl:call-template>
7099 <xsl:for-each select="marc:subfield[@code='d']">
7101 <xsl:call-template name="chopPunctuation">
7102 <xsl:with-param name="chopString" select="."/>
7103 </xsl:call-template>
7106 <xsl:for-each select="marc:subfield[@code='e']">
7108 <xsl:call-template name="chopPunctuation">
7109 <xsl:with-param name="chopString" select="."/>
7110 </xsl:call-template>
7113 <xsl:for-each select="marc:subfield[@code='g']">
7115 <xsl:call-template name="chopPunctuation">
7116 <xsl:with-param name="chopString" select="."/>
7117 </xsl:call-template>
7120 <xsl:for-each select="marc:subfield[@code='h']">
7121 <extraterrestrialArea>
7122 <xsl:call-template name="chopPunctuation">
7123 <xsl:with-param name="chopString" select="."/>
7124 </xsl:call-template>
7125 </extraterrestrialArea>
7127 </hierarchicalGeographic>
7130 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
7133 <xsl:when test="@ind1=2">
7134 <temporal encoding="iso8601" point="start">
7135 <xsl:call-template name="chopPunctuation">
7136 <xsl:with-param name="chopString">
7137 <xsl:value-of select="marc:subfield[@code='b'][1]"/>
7139 </xsl:call-template>
7141 <temporal encoding="iso8601" point="end">
7142 <xsl:call-template name="chopPunctuation">
7143 <xsl:with-param name="chopString">
7144 <xsl:value-of select="marc:subfield[@code='b'][2]"/>
7146 </xsl:call-template>
7150 <xsl:for-each select="marc:subfield[@code='b']">
7151 <temporal encoding="iso8601">
7152 <xsl:call-template name="chopPunctuation">
7153 <xsl:with-param name="chopString" select="."/>
7154 </xsl:call-template>
7161 <xsl:for-each select="marc:datafield[@tag=050]">
7162 <xsl:for-each select="marc:subfield[@code='b']">
7163 <classification authority="lcc">
7164 <xsl:if test="../marc:subfield[@code='3']">
7165 <xsl:attribute name="displayLabel">
7166 <xsl:value-of select="../marc:subfield[@code='3']"/>
7169 <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"/>
7170 <xsl:text> </xsl:text>
7171 <xsl:value-of select="text()"/>
7175 select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
7176 <classification authority="lcc">
7177 <xsl:if test="../marc:subfield[@code='3']">
7178 <xsl:attribute name="displayLabel">
7179 <xsl:value-of select="../marc:subfield[@code='3']"/>
7182 <xsl:value-of select="text()"/>
7186 <xsl:for-each select="marc:datafield[@tag=082]">
7187 <classification authority="ddc">
7188 <xsl:if test="marc:subfield[@code='2']">
7189 <xsl:attribute name="edition">
7190 <xsl:value-of select="marc:subfield[@code='2']"/>
7193 <xsl:call-template name="subfieldSelect">
7194 <xsl:with-param name="codes">ab</xsl:with-param>
7195 </xsl:call-template>
7198 <xsl:for-each select="marc:datafield[@tag=080]">
7199 <classification authority="udc">
7200 <xsl:call-template name="subfieldSelect">
7201 <xsl:with-param name="codes">abx</xsl:with-param>
7202 </xsl:call-template>
7205 <xsl:for-each select="marc:datafield[@tag=060]">
7206 <classification authority="nlm">
7207 <xsl:call-template name="subfieldSelect">
7208 <xsl:with-param name="codes">ab</xsl:with-param>
7209 </xsl:call-template>
7212 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
7213 <classification authority="sudocs">
7214 <xsl:value-of select="marc:subfield[@code='a']"/>
7217 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
7218 <classification authority="candoc">
7219 <xsl:value-of select="marc:subfield[@code='a']"/>
7222 <xsl:for-each select="marc:datafield[@tag=086]">
7224 <xsl:attribute name="authority">
7225 <xsl:value-of select="marc:subfield[@code='2']"/>
7227 <xsl:value-of select="marc:subfield[@code='a']"/>
7230 <xsl:for-each select="marc:datafield[@tag=084]">
7232 <xsl:attribute name="authority">
7233 <xsl:value-of select="marc:subfield[@code='2']"/>
7235 <xsl:call-template name="subfieldSelect">
7236 <xsl:with-param name="codes">ab</xsl:with-param>
7237 </xsl:call-template>
7240 <xsl:for-each select="marc:datafield[@tag=440]">
7241 <relatedItem type="series">
7244 <xsl:call-template name="chopPunctuation">
7245 <xsl:with-param name="chopString">
7246 <xsl:call-template name="subfieldSelect">
7247 <xsl:with-param name="codes">av</xsl:with-param>
7248 </xsl:call-template>
7250 </xsl:call-template>
7252 <xsl:call-template name="part"/>
7256 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
7257 <relatedItem type="series">
7260 <xsl:call-template name="chopPunctuation">
7261 <xsl:with-param name="chopString">
7262 <xsl:call-template name="subfieldSelect">
7263 <xsl:with-param name="codes">av</xsl:with-param>
7264 </xsl:call-template>
7266 </xsl:call-template>
7268 <xsl:call-template name="part"/>
7272 <xsl:for-each select="marc:datafield[@tag=510]">
7273 <relatedItem type="isReferencedBy">
7275 <xsl:call-template name="subfieldSelect">
7276 <xsl:with-param name="codes">abcx3</xsl:with-param>
7277 </xsl:call-template>
7281 <xsl:for-each select="marc:datafield[@tag=534]">
7282 <relatedItem type="original">
7283 <xsl:call-template name="relatedTitle"/>
7284 <xsl:call-template name="relatedName"/>
7285 <xsl:if test="marc:subfield[@code='b' or @code='c']">
7287 <xsl:for-each select="marc:subfield[@code='c']">
7289 <xsl:value-of select="."/>
7292 <xsl:for-each select="marc:subfield[@code='b']">
7294 <xsl:value-of select="."/>
7299 <xsl:call-template name="relatedIdentifierISSN"/>
7300 <xsl:for-each select="marc:subfield[@code='z']">
7301 <identifier type="isbn">
7302 <xsl:value-of select="."/>
7305 <xsl:call-template name="relatedNote"/>
7308 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
7310 <xsl:call-template name="constituentOrRelatedType"/>
7313 <xsl:call-template name="chopPunctuation">
7314 <xsl:with-param name="chopString">
7315 <xsl:call-template name="specialSubfieldSelect">
7316 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7317 <xsl:with-param name="axis">t</xsl:with-param>
7318 <xsl:with-param name="afterCodes">g</xsl:with-param>
7319 </xsl:call-template>
7321 </xsl:call-template>
7323 <xsl:call-template name="part"/>
7325 <name type="personal">
7327 <xsl:call-template name="specialSubfieldSelect">
7328 <xsl:with-param name="anyCodes">aq</xsl:with-param>
7329 <xsl:with-param name="axis">t</xsl:with-param>
7330 <xsl:with-param name="beforeCodes">g</xsl:with-param>
7331 </xsl:call-template>
7333 <xsl:call-template name="termsOfAddress"/>
7334 <xsl:call-template name="nameDate"/>
7335 <xsl:call-template name="role"/>
7337 <xsl:call-template name="relatedForm"/>
7338 <xsl:call-template name="relatedIdentifierISSN"/>
7341 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
7343 <xsl:call-template name="constituentOrRelatedType"/>
7346 <xsl:call-template name="chopPunctuation">
7347 <xsl:with-param name="chopString">
7348 <xsl:call-template name="specialSubfieldSelect">
7349 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7350 <xsl:with-param name="axis">t</xsl:with-param>
7351 <xsl:with-param name="afterCodes">dg</xsl:with-param>
7352 </xsl:call-template>
7354 </xsl:call-template>
7356 <xsl:call-template name="relatedPartNumName"/>
7358 <name type="corporate">
7359 <xsl:for-each select="marc:subfield[@code='a']">
7361 <xsl:value-of select="."/>
7364 <xsl:for-each select="marc:subfield[@code='b']">
7366 <xsl:value-of select="."/>
7369 <xsl:variable name="tempNamePart">
7370 <xsl:call-template name="specialSubfieldSelect">
7371 <xsl:with-param name="anyCodes">c</xsl:with-param>
7372 <xsl:with-param name="axis">t</xsl:with-param>
7373 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
7374 </xsl:call-template>
7376 <xsl:if test="normalize-space($tempNamePart)">
7378 <xsl:value-of select="$tempNamePart"/>
7381 <xsl:call-template name="role"/>
7383 <xsl:call-template name="relatedForm"/>
7384 <xsl:call-template name="relatedIdentifierISSN"/>
7387 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
7389 <xsl:call-template name="constituentOrRelatedType"/>
7392 <xsl:call-template name="chopPunctuation">
7393 <xsl:with-param name="chopString">
7394 <xsl:call-template name="specialSubfieldSelect">
7395 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
7396 <xsl:with-param name="axis">t</xsl:with-param>
7397 <xsl:with-param name="afterCodes">g</xsl:with-param>
7398 </xsl:call-template>
7400 </xsl:call-template>
7402 <xsl:call-template name="relatedPartNumName"/>
7404 <name type="conference">
7406 <xsl:call-template name="specialSubfieldSelect">
7407 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
7408 <xsl:with-param name="axis">t</xsl:with-param>
7409 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
7410 </xsl:call-template>
7413 <xsl:call-template name="relatedForm"/>
7414 <xsl:call-template name="relatedIdentifierISSN"/>
7417 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
7419 <xsl:call-template name="constituentOrRelatedType"/>
7422 <xsl:call-template name="chopPunctuation">
7423 <xsl:with-param name="chopString">
7424 <xsl:call-template name="subfieldSelect">
7425 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
7426 </xsl:call-template>
7428 </xsl:call-template>
7430 <xsl:call-template name="part"/>
7432 <xsl:call-template name="relatedForm"/>
7433 <xsl:call-template name="relatedIdentifierISSN"/>
7436 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
7438 <xsl:call-template name="constituentOrRelatedType"/>
7441 <xsl:call-template name="chopPunctuation">
7442 <xsl:with-param name="chopString">
7443 <xsl:value-of select="marc:subfield[@code='a']"/>
7445 </xsl:call-template>
7447 <xsl:call-template name="part"/>
7449 <xsl:call-template name="relatedForm"/>
7452 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
7453 <relatedItem type="series">
7454 <xsl:call-template name="relatedItem76X-78X"/>
7458 select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
7460 <xsl:call-template name="relatedItem76X-78X"/>
7463 <xsl:for-each select="marc:datafield[@tag=775]">
7464 <relatedItem type="otherVersion">
7465 <xsl:call-template name="relatedItem76X-78X"/>
7468 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
7469 <relatedItem type="constituent">
7470 <xsl:call-template name="relatedItem76X-78X"/>
7473 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
7474 <relatedItem type="host">
7475 <xsl:call-template name="relatedItem76X-78X"/>
7478 <xsl:for-each select="marc:datafield[@tag=776]">
7479 <relatedItem type="otherFormat">
7480 <xsl:call-template name="relatedItem76X-78X"/>
7483 <xsl:for-each select="marc:datafield[@tag=780]">
7484 <relatedItem type="preceding">
7485 <xsl:call-template name="relatedItem76X-78X"/>
7488 <xsl:for-each select="marc:datafield[@tag=785]">
7489 <relatedItem type="succeeding">
7490 <xsl:call-template name="relatedItem76X-78X"/>
7493 <xsl:for-each select="marc:datafield[@tag=786]">
7494 <relatedItem type="original">
7495 <xsl:call-template name="relatedItem76X-78X"/>
7498 <xsl:for-each select="marc:datafield[@tag=800]">
7499 <relatedItem type="series">
7502 <xsl:call-template name="chopPunctuation">
7503 <xsl:with-param name="chopString">
7504 <xsl:call-template name="specialSubfieldSelect">
7505 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7506 <xsl:with-param name="axis">t</xsl:with-param>
7507 <xsl:with-param name="afterCodes">g</xsl:with-param>
7508 </xsl:call-template>
7510 </xsl:call-template>
7512 <xsl:call-template name="part"/>
7514 <name type="personal">
7516 <xsl:call-template name="chopPunctuation">
7517 <xsl:with-param name="chopString">
7518 <xsl:call-template name="specialSubfieldSelect">
7519 <xsl:with-param name="anyCodes">aq</xsl:with-param>
7520 <xsl:with-param name="axis">t</xsl:with-param>
7521 <xsl:with-param name="beforeCodes">g</xsl:with-param>
7522 </xsl:call-template>
7524 </xsl:call-template>
7526 <xsl:call-template name="termsOfAddress"/>
7527 <xsl:call-template name="nameDate"/>
7528 <xsl:call-template name="role"/>
7530 <xsl:call-template name="relatedForm"/>
7533 <xsl:for-each select="marc:datafield[@tag=810]">
7534 <relatedItem type="series">
7537 <xsl:call-template name="chopPunctuation">
7538 <xsl:with-param name="chopString">
7539 <xsl:call-template name="specialSubfieldSelect">
7540 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
7541 <xsl:with-param name="axis">t</xsl:with-param>
7542 <xsl:with-param name="afterCodes">dg</xsl:with-param>
7543 </xsl:call-template>
7545 </xsl:call-template>
7547 <xsl:call-template name="relatedPartNumName"/>
7549 <name type="corporate">
7550 <xsl:for-each select="marc:subfield[@code='a']">
7552 <xsl:value-of select="."/>
7555 <xsl:for-each select="marc:subfield[@code='b']">
7557 <xsl:value-of select="."/>
7561 <xsl:call-template name="specialSubfieldSelect">
7562 <xsl:with-param name="anyCodes">c</xsl:with-param>
7563 <xsl:with-param name="axis">t</xsl:with-param>
7564 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
7565 </xsl:call-template>
7567 <xsl:call-template name="role"/>
7569 <xsl:call-template name="relatedForm"/>
7572 <xsl:for-each select="marc:datafield[@tag=811]">
7573 <relatedItem type="series">
7576 <xsl:call-template name="chopPunctuation">
7577 <xsl:with-param name="chopString">
7578 <xsl:call-template name="specialSubfieldSelect">
7579 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
7580 <xsl:with-param name="axis">t</xsl:with-param>
7581 <xsl:with-param name="afterCodes">g</xsl:with-param>
7582 </xsl:call-template>
7584 </xsl:call-template>
7586 <xsl:call-template name="relatedPartNumName"/>
7588 <name type="conference">
7590 <xsl:call-template name="specialSubfieldSelect">
7591 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
7592 <xsl:with-param name="axis">t</xsl:with-param>
7593 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
7594 </xsl:call-template>
7596 <xsl:call-template name="role"/>
7598 <xsl:call-template name="relatedForm"/>
7601 <xsl:for-each select="marc:datafield[@tag='830']">
7602 <relatedItem type="series">
7605 <xsl:call-template name="chopPunctuation">
7606 <xsl:with-param name="chopString">
7607 <xsl:call-template name="subfieldSelect">
7608 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
7609 </xsl:call-template>
7611 </xsl:call-template>
7613 <xsl:call-template name="part"/>
7615 <xsl:call-template name="relatedForm"/>
7618 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
7621 <xsl:value-of select="."/>
7622 </internetMediaType>
7625 <xsl:for-each select="marc:datafield[@tag='020']">
7626 <xsl:call-template name="isInvalid">
7627 <xsl:with-param name="type">isbn</xsl:with-param>
7628 </xsl:call-template>
7629 <xsl:if test="marc:subfield[@code='a']">
7630 <identifier type="isbn">
7631 <xsl:value-of select="marc:subfield[@code='a']"/>
7635 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
7636 <xsl:call-template name="isInvalid">
7637 <xsl:with-param name="type">isrc</xsl:with-param>
7638 </xsl:call-template>
7639 <xsl:if test="marc:subfield[@code='a']">
7640 <identifier type="isrc">
7641 <xsl:value-of select="marc:subfield[@code='a']"/>
7645 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
7646 <xsl:call-template name="isInvalid">
7647 <xsl:with-param name="type">ismn</xsl:with-param>
7648 </xsl:call-template>
7649 <xsl:if test="marc:subfield[@code='a']">
7650 <identifier type="ismn">
7651 <xsl:value-of select="marc:subfield[@code='a']"/>
7655 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
7656 <xsl:call-template name="isInvalid">
7657 <xsl:with-param name="type">sici</xsl:with-param>
7658 </xsl:call-template>
7659 <identifier type="sici">
7660 <xsl:call-template name="subfieldSelect">
7661 <xsl:with-param name="codes">ab</xsl:with-param>
7662 </xsl:call-template>
7665 <xsl:for-each select="marc:datafield[@tag='022']">
7666 <xsl:if test="marc:subfield[@code='a']">
7667 <xsl:call-template name="isInvalid">
7668 <xsl:with-param name="type">issn</xsl:with-param>
7669 </xsl:call-template>
7670 <identifier type="issn">
7671 <xsl:value-of select="marc:subfield[@code='a']"/>
7674 <xsl:if test="marc:subfield[@code='l']">
7675 <xsl:call-template name="isInvalid">
7676 <xsl:with-param name="type">issn-l</xsl:with-param>
7677 </xsl:call-template>
7678 <identifier type="issn-l">
7679 <xsl:value-of select="marc:subfield[@code='l']"/>
7686 <xsl:for-each select="marc:datafield[@tag='010']">
7687 <xsl:call-template name="isInvalid">
7688 <xsl:with-param name="type">lccn</xsl:with-param>
7689 </xsl:call-template>
7690 <identifier type="lccn">
7691 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
7694 <xsl:for-each select="marc:datafield[@tag='028']">
7696 <xsl:attribute name="type">
7698 <xsl:when test="@ind1='0'">issue number</xsl:when>
7699 <xsl:when test="@ind1='1'">matrix number</xsl:when>
7700 <xsl:when test="@ind1='2'">music plate</xsl:when>
7701 <xsl:when test="@ind1='3'">music publisher</xsl:when>
7702 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
7705 <!--<xsl:call-template name="isInvalid"/>-->
7706 <!-- no $z in 028 -->
7707 <xsl:call-template name="subfieldSelect">
7708 <xsl:with-param name="codes">
7710 <xsl:when test="@ind1='0'">ba</xsl:when>
7711 <xsl:otherwise>ab</xsl:otherwise>
7714 </xsl:call-template>
7717 <xsl:for-each select="marc:datafield[@tag='037']">
7718 <identifier type="stock number">
7719 <!--<xsl:call-template name="isInvalid"/>-->
7720 <!-- no $z in 037 -->
7721 <xsl:call-template name="subfieldSelect">
7722 <xsl:with-param name="codes">ab</xsl:with-param>
7723 </xsl:call-template>
7726 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
7728 <xsl:attribute name="type">
7731 test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')"
7734 test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')"
7736 <xsl:otherwise>uri</xsl:otherwise>
7741 test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
7743 select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
7747 <xsl:value-of select="marc:subfield[@code='u']"/>
7752 test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
7753 <identifier type="hdl">
7754 <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
7755 <xsl:attribute name="displayLabel">
7756 <xsl:call-template name="subfieldSelect">
7757 <xsl:with-param name="codes">y3z</xsl:with-param>
7758 </xsl:call-template>
7762 select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"
7767 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
7768 <identifier type="upc">
7769 <xsl:call-template name="isInvalid"/>
7770 <xsl:value-of select="marc:subfield[@code='a']"/>
7774 <!-- 1/04 fix added $y -->
7777 <xsl:for-each select="marc:datafield[@tag=856][@ind2=1][marc:subfield[@code='u']]">
7778 <relatedItem type="otherVersion">
7781 <xsl:if test="marc:subfield[@code='y' or @code='3']">
7782 <xsl:attribute name="displayLabel">
7783 <xsl:call-template name="subfieldSelect">
7784 <xsl:with-param name="codes">y3</xsl:with-param>
7785 </xsl:call-template>
7788 <xsl:if test="marc:subfield[@code='z' ]">
7789 <xsl:attribute name="note">
7790 <xsl:call-template name="subfieldSelect">
7791 <xsl:with-param name="codes">z</xsl:with-param>
7792 </xsl:call-template>
7795 <xsl:value-of select="marc:subfield[@code='u']"/>
7800 <xsl:for-each select="marc:datafield[@tag=856][@ind2=2][marc:subfield[@code='u']]">
7804 <xsl:if test="marc:subfield[@code='y' or @code='3']">
7805 <xsl:attribute name="displayLabel">
7806 <xsl:call-template name="subfieldSelect">
7807 <xsl:with-param name="codes">y3</xsl:with-param>
7808 </xsl:call-template>
7811 <xsl:if test="marc:subfield[@code='z' ]">
7812 <xsl:attribute name="note">
7813 <xsl:call-template name="subfieldSelect">
7814 <xsl:with-param name="codes">z</xsl:with-param>
7815 </xsl:call-template>
7818 <xsl:value-of select="marc:subfield[@code='u']"/>
7824 <!-- 3.2 change tmee 856z -->
7827 <xsl:for-each select="marc:datafield[@tag=852]">
7829 <xsl:if test="marc:subfield[@code='a' or @code='b' or @code='e']">
7831 <xsl:call-template name="subfieldSelect">
7832 <xsl:with-param name="codes">abe</xsl:with-param>
7833 </xsl:call-template>
7837 <xsl:if test="marc:subfield[@code='u']">
7839 <xsl:call-template name="uri"/>
7840 <xsl:call-template name="subfieldSelect">
7841 <xsl:with-param name="codes">u</xsl:with-param>
7842 </xsl:call-template>
7847 test="marc:subfield[@code='h' or @code='i' or @code='j' or @code='k' or @code='l' or @code='m' or @code='t']">
7849 <xsl:call-template name="subfieldSelect">
7850 <xsl:with-param name="codes">hijklmt</xsl:with-param>
7851 </xsl:call-template>
7857 <xsl:for-each select="marc:datafield[@tag=506]">
7858 <accessCondition type="restrictionOnAccess">
7859 <xsl:call-template name="subfieldSelect">
7860 <xsl:with-param name="codes">abcd35</xsl:with-param>
7861 </xsl:call-template>
7864 <xsl:for-each select="marc:datafield[@tag=540]">
7865 <accessCondition type="useAndReproduction">
7866 <xsl:call-template name="subfieldSelect">
7867 <xsl:with-param name="codes">abcde35</xsl:with-param>
7868 </xsl:call-template>
7876 <xsl:for-each select="marc:leader[substring($leader,19,1)='a']">
7877 <descriptionStandard>aacr2</descriptionStandard>
7880 <xsl:for-each select="marc:datafield[@tag=040]">
7881 <xsl:if test="marc:subfield[@code='e']">
7882 <descriptionStandard>
7883 <xsl:value-of select="marc:subfield[@code='e']"/>
7884 </descriptionStandard>
7886 <recordContentSource authority="marcorg">
7887 <xsl:value-of select="marc:subfield[@code='a']"/>
7888 </recordContentSource>
7890 <xsl:for-each select="marc:controlfield[@tag=008]">
7891 <recordCreationDate encoding="marc">
7892 <xsl:value-of select="substring(.,1,6)"/>
7893 </recordCreationDate>
7896 <xsl:for-each select="marc:controlfield[@tag=005]">
7897 <recordChangeDate encoding="iso8601">
7898 <xsl:value-of select="."/>
7901 <xsl:for-each select="marc:controlfield[@tag=001]">
7903 <xsl:if test="../marc:controlfield[@tag=003]">
7904 <xsl:attribute name="source">
7905 <xsl:value-of select="../marc:controlfield[@tag=003]"/>
7908 <xsl:value-of select="."/>
7911 <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
7912 <languageOfCataloging>
7913 <languageTerm authority="iso639-2b" type="code">
7914 <xsl:value-of select="."/>
7916 </languageOfCataloging>
7920 <xsl:template name="displayForm">
7921 <xsl:for-each select="marc:subfield[@code='c']">
7923 <xsl:value-of select="."/>
7927 <xsl:template name="affiliation">
7928 <xsl:for-each select="marc:subfield[@code='u']">
7930 <xsl:value-of select="."/>
7934 <xsl:template name="uri">
7935 <xsl:for-each select="marc:subfield[@code='u']">
7936 <xsl:attribute name="xlink:href">
7937 <xsl:value-of select="."/>
7940 <xsl:for-each select="marc:subfield[@code='0']">
7942 <xsl:when test="contains(text(), ')')">
7943 <xsl:attribute name="xlink:href">
7944 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
7948 <xsl:attribute name="xlink:href">
7949 <xsl:value-of select="."></xsl:value-of>
7955 <xsl:template name="role">
7956 <xsl:for-each select="marc:subfield[@code='e']">
7958 <roleTerm type="text">
7959 <xsl:value-of select="."/>
7963 <xsl:for-each select="marc:subfield[@code='4']">
7965 <roleTerm authority="marcrelator" type="code">
7966 <xsl:value-of select="."/>
7971 <xsl:template name="part">
7972 <xsl:variable name="partNumber">
7973 <xsl:call-template name="specialSubfieldSelect">
7974 <xsl:with-param name="axis">n</xsl:with-param>
7975 <xsl:with-param name="anyCodes">n</xsl:with-param>
7976 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
7977 </xsl:call-template>
7979 <xsl:variable name="partName">
7980 <xsl:call-template name="specialSubfieldSelect">
7981 <xsl:with-param name="axis">p</xsl:with-param>
7982 <xsl:with-param name="anyCodes">p</xsl:with-param>
7983 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
7984 </xsl:call-template>
7986 <xsl:if test="string-length(normalize-space($partNumber))">
7988 <xsl:call-template name="chopPunctuation">
7989 <xsl:with-param name="chopString" select="$partNumber"/>
7990 </xsl:call-template>
7993 <xsl:if test="string-length(normalize-space($partName))">
7995 <xsl:call-template name="chopPunctuation">
7996 <xsl:with-param name="chopString" select="$partName"/>
7997 </xsl:call-template>
8001 <xsl:template name="relatedPart">
8002 <xsl:if test="@tag=773">
8003 <xsl:for-each select="marc:subfield[@code='g']">
8006 <xsl:value-of select="."/>
8010 <xsl:for-each select="marc:subfield[@code='q']">
8012 <xsl:call-template name="parsePart"/>
8017 <xsl:template name="relatedPartNumName">
8018 <xsl:variable name="partNumber">
8019 <xsl:call-template name="specialSubfieldSelect">
8020 <xsl:with-param name="axis">g</xsl:with-param>
8021 <xsl:with-param name="anyCodes">g</xsl:with-param>
8022 <xsl:with-param name="afterCodes">pst</xsl:with-param>
8023 </xsl:call-template>
8025 <xsl:variable name="partName">
8026 <xsl:call-template name="specialSubfieldSelect">
8027 <xsl:with-param name="axis">p</xsl:with-param>
8028 <xsl:with-param name="anyCodes">p</xsl:with-param>
8029 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
8030 </xsl:call-template>
8032 <xsl:if test="string-length(normalize-space($partNumber))">
8034 <xsl:value-of select="$partNumber"/>
8037 <xsl:if test="string-length(normalize-space($partName))">
8039 <xsl:value-of select="$partName"/>
8043 <xsl:template name="relatedName">
8044 <xsl:for-each select="marc:subfield[@code='a']">
8047 <xsl:value-of select="."/>
8052 <xsl:template name="relatedForm">
8053 <xsl:for-each select="marc:subfield[@code='h']">
8054 <physicalDescription>
8056 <xsl:value-of select="."/>
8058 </physicalDescription>
8061 <xsl:template name="relatedExtent">
8062 <xsl:for-each select="marc:subfield[@code='h']">
8063 <physicalDescription>
8065 <xsl:value-of select="."/>
8067 </physicalDescription>
8070 <xsl:template name="relatedNote">
8071 <xsl:for-each select="marc:subfield[@code='n']">
8073 <xsl:value-of select="."/>
8077 <xsl:template name="relatedSubject">
8078 <xsl:for-each select="marc:subfield[@code='j']">
8080 <temporal encoding="iso8601">
8081 <xsl:call-template name="chopPunctuation">
8082 <xsl:with-param name="chopString" select="."/>
8083 </xsl:call-template>
8088 <xsl:template name="relatedIdentifierISSN">
8089 <xsl:for-each select="marc:subfield[@code='x']">
8090 <identifier type="issn">
8091 <xsl:value-of select="."/>
8095 <xsl:template name="relatedIdentifierLocal">
8096 <xsl:for-each select="marc:subfield[@code='w']">
8097 <identifier type="local">
8098 <xsl:value-of select="."/>
8102 <xsl:template name="relatedIdentifier">
8103 <xsl:for-each select="marc:subfield[@code='o']">
8105 <xsl:value-of select="."/>
8109 <xsl:template name="relatedItem76X-78X">
8110 <xsl:call-template name="displayLabel"/>
8111 <xsl:call-template name="relatedTitle76X-78X"/>
8112 <xsl:call-template name="relatedName"/>
8113 <xsl:call-template name="relatedOriginInfo"/>
8114 <xsl:call-template name="relatedLanguage"/>
8115 <xsl:call-template name="relatedExtent"/>
8116 <xsl:call-template name="relatedNote"/>
8117 <xsl:call-template name="relatedSubject"/>
8118 <xsl:call-template name="relatedIdentifier"/>
8119 <xsl:call-template name="relatedIdentifierISSN"/>
8120 <xsl:call-template name="relatedIdentifierLocal"/>
8121 <xsl:call-template name="relatedPart"/>
8123 <xsl:template name="subjectGeographicZ">
8125 <xsl:call-template name="chopPunctuation">
8126 <xsl:with-param name="chopString" select="."/>
8127 </xsl:call-template>
8130 <xsl:template name="subjectTemporalY">
8132 <xsl:call-template name="chopPunctuation">
8133 <xsl:with-param name="chopString" select="."/>
8134 </xsl:call-template>
8137 <xsl:template name="subjectTopic">
8139 <xsl:call-template name="chopPunctuation">
8140 <xsl:with-param name="chopString" select="."/>
8141 </xsl:call-template>
8144 <!-- 3.2 change tmee 6xx $v genre -->
8145 <xsl:template name="subjectGenre">
8147 <xsl:call-template name="chopPunctuation">
8148 <xsl:with-param name="chopString" select="."/>
8149 </xsl:call-template>
8153 <xsl:template name="nameABCDN">
8154 <xsl:for-each select="marc:subfield[@code='a']">
8156 <xsl:call-template name="chopPunctuation">
8157 <xsl:with-param name="chopString" select="."/>
8158 </xsl:call-template>
8161 <xsl:for-each select="marc:subfield[@code='b']">
8163 <xsl:value-of select="."/>
8167 test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
8169 <xsl:call-template name="subfieldSelect">
8170 <xsl:with-param name="codes">cdn</xsl:with-param>
8171 </xsl:call-template>
8175 <xsl:template name="nameABCDQ">
8177 <xsl:call-template name="chopPunctuation">
8178 <xsl:with-param name="chopString">
8179 <xsl:call-template name="subfieldSelect">
8180 <xsl:with-param name="codes">aq</xsl:with-param>
8181 </xsl:call-template>
8183 <xsl:with-param name="punctuation">
8184 <xsl:text>:,;/ </xsl:text>
8186 </xsl:call-template>
8188 <xsl:call-template name="termsOfAddress"/>
8189 <xsl:call-template name="nameDate"/>
8191 <xsl:template name="nameACDEQ">
8193 <xsl:call-template name="subfieldSelect">
8194 <xsl:with-param name="codes">acdeq</xsl:with-param>
8195 </xsl:call-template>
8198 <xsl:template name="constituentOrRelatedType">
8199 <xsl:if test="@ind2=2">
8200 <xsl:attribute name="type">constituent</xsl:attribute>
8203 <xsl:template name="relatedTitle">
8204 <xsl:for-each select="marc:subfield[@code='t']">
8207 <xsl:call-template name="chopPunctuation">
8208 <xsl:with-param name="chopString">
8209 <xsl:value-of select="."/>
8211 </xsl:call-template>
8216 <xsl:template name="relatedTitle76X-78X">
8217 <xsl:for-each select="marc:subfield[@code='t']">
8220 <xsl:call-template name="chopPunctuation">
8221 <xsl:with-param name="chopString">
8222 <xsl:value-of select="."/>
8224 </xsl:call-template>
8226 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8227 <xsl:call-template name="relatedPartNumName"/>
8231 <xsl:for-each select="marc:subfield[@code='p']">
8232 <titleInfo type="abbreviated">
8234 <xsl:call-template name="chopPunctuation">
8235 <xsl:with-param name="chopString">
8236 <xsl:value-of select="."/>
8238 </xsl:call-template>
8240 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8241 <xsl:call-template name="relatedPartNumName"/>
8245 <xsl:for-each select="marc:subfield[@code='s']">
8246 <titleInfo type="uniform">
8248 <xsl:call-template name="chopPunctuation">
8249 <xsl:with-param name="chopString">
8250 <xsl:value-of select="."/>
8252 </xsl:call-template>
8254 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
8255 <xsl:call-template name="relatedPartNumName"/>
8260 <xsl:template name="relatedOriginInfo">
8261 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
8263 <xsl:if test="@tag=775">
8264 <xsl:for-each select="marc:subfield[@code='f']">
8267 <xsl:attribute name="type">code</xsl:attribute>
8268 <xsl:attribute name="authority">marcgac</xsl:attribute>
8269 <xsl:value-of select="."/>
8274 <xsl:for-each select="marc:subfield[@code='d']">
8276 <xsl:value-of select="."/>
8279 <xsl:for-each select="marc:subfield[@code='b']">
8281 <xsl:value-of select="."/>
8287 <xsl:template name="relatedLanguage">
8288 <xsl:for-each select="marc:subfield[@code='e']">
8289 <xsl:call-template name="getLanguage">
8290 <xsl:with-param name="langString">
8291 <xsl:value-of select="."/>
8293 </xsl:call-template>
8296 <xsl:template name="nameDate">
8297 <xsl:for-each select="marc:subfield[@code='d']">
8298 <namePart type="date">
8299 <xsl:call-template name="chopPunctuation">
8300 <xsl:with-param name="chopString" select="."/>
8301 </xsl:call-template>
8305 <xsl:template name="subjectAuthority">
8306 <xsl:if test="@ind2!=4">
8307 <xsl:if test="@ind2!=' '">
8308 <xsl:if test="@ind2!=8">
8309 <xsl:if test="@ind2!=9">
8310 <xsl:attribute name="authority">
8312 <xsl:when test="@ind2=0">lcsh</xsl:when>
8313 <xsl:when test="@ind2=1">lcshac</xsl:when>
8314 <xsl:when test="@ind2=2">mesh</xsl:when>
8316 <xsl:when test="@ind2=3">nal</xsl:when>
8317 <xsl:when test="@ind2=5">csh</xsl:when>
8318 <xsl:when test="@ind2=6">rvm</xsl:when>
8319 <xsl:when test="@ind2=7">
8320 <xsl:value-of select="marc:subfield[@code='2']"/>
8329 <xsl:template name="subjectAnyOrder">
8330 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
8332 <xsl:when test="@code='v'">
8333 <xsl:call-template name="subjectGenre"/>
8335 <xsl:when test="@code='x'">
8336 <xsl:call-template name="subjectTopic"/>
8338 <xsl:when test="@code='y'">
8339 <xsl:call-template name="subjectTemporalY"/>
8341 <xsl:when test="@code='z'">
8342 <xsl:call-template name="subjectGeographicZ"/>
8347 <xsl:template name="specialSubfieldSelect">
8348 <xsl:param name="anyCodes"/>
8349 <xsl:param name="axis"/>
8350 <xsl:param name="beforeCodes"/>
8351 <xsl:param name="afterCodes"/>
8352 <xsl:variable name="str">
8353 <xsl:for-each select="marc:subfield">
8355 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])">
8356 <xsl:value-of select="text()"/>
8357 <xsl:text> </xsl:text>
8361 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
8364 <!-- 3.2 change tmee 6xx $v genre -->
8365 <xsl:template match="marc:datafield[@tag=600]">
8367 <xsl:call-template name="subjectAuthority"/>
8368 <name type="personal">
8369 <xsl:call-template name="termsOfAddress"/>
8371 <xsl:call-template name="chopPunctuation">
8372 <xsl:with-param name="chopString">
8373 <xsl:call-template name="subfieldSelect">
8374 <xsl:with-param name="codes">aq</xsl:with-param>
8375 </xsl:call-template>
8377 </xsl:call-template>
8379 <xsl:call-template name="nameDate"/>
8380 <xsl:call-template name="affiliation"/>
8381 <xsl:call-template name="role"/>
8383 <xsl:call-template name="subjectAnyOrder"/>
8386 <xsl:template match="marc:datafield[@tag=610]">
8388 <xsl:call-template name="subjectAuthority"/>
8389 <name type="corporate">
8390 <xsl:for-each select="marc:subfield[@code='a']">
8392 <xsl:value-of select="."/>
8395 <xsl:for-each select="marc:subfield[@code='b']">
8397 <xsl:value-of select="."/>
8400 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
8402 <xsl:call-template name="subfieldSelect">
8403 <xsl:with-param name="codes">cdnp</xsl:with-param>
8404 </xsl:call-template>
8407 <xsl:call-template name="role"/>
8409 <xsl:call-template name="subjectAnyOrder"/>
8412 <xsl:template match="marc:datafield[@tag=611]">
8414 <xsl:call-template name="subjectAuthority"/>
8415 <name type="conference">
8417 <xsl:call-template name="subfieldSelect">
8418 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
8419 </xsl:call-template>
8421 <xsl:for-each select="marc:subfield[@code='4']">
8423 <roleTerm authority="marcrelator" type="code">
8424 <xsl:value-of select="."/>
8429 <xsl:call-template name="subjectAnyOrder"/>
8432 <xsl:template match="marc:datafield[@tag=630]">
8434 <xsl:call-template name="subjectAuthority"/>
8437 <xsl:call-template name="chopPunctuation">
8438 <xsl:with-param name="chopString">
8439 <xsl:call-template name="subfieldSelect">
8440 <xsl:with-param name="codes">adfhklor</xsl:with-param>
8441 </xsl:call-template>
8443 </xsl:call-template>
8445 <xsl:call-template name="part"/>
8447 <xsl:call-template name="subjectAnyOrder"/>
8450 <!-- 1.27 648 tmee-->
8451 <xsl:template match="marc:datafield[@tag=648]">
8453 <xsl:if test="marc:subfield[@code=2]">
8454 <xsl:attribute name="authority">
8455 <xsl:value-of select="marc:subfield[@code=2]"/>
8458 <xsl:call-template name="uri"/>
8460 <xsl:call-template name="subjectAuthority"/>
8462 <xsl:call-template name="chopPunctuation">
8463 <xsl:with-param name="chopString">
8464 <xsl:call-template name="subfieldSelect">
8465 <xsl:with-param name="codes">abcd</xsl:with-param>
8466 </xsl:call-template>
8468 </xsl:call-template>
8470 <xsl:call-template name="subjectAnyOrder"/>
8474 <xsl:template match="marc:datafield[@tag=650]">
8476 <xsl:call-template name="subjectAuthority"/>
8478 <xsl:call-template name="chopPunctuation">
8479 <xsl:with-param name="chopString">
8480 <xsl:call-template name="subfieldSelect">
8481 <xsl:with-param name="codes">abcd</xsl:with-param>
8482 </xsl:call-template>
8484 </xsl:call-template>
8486 <xsl:call-template name="subjectAnyOrder"/>
8489 <xsl:template match="marc:datafield[@tag=651]">
8491 <xsl:call-template name="subjectAuthority"/>
8492 <xsl:for-each select="marc:subfield[@code='a']">
8494 <xsl:call-template name="chopPunctuation">
8495 <xsl:with-param name="chopString" select="."/>
8496 </xsl:call-template>
8499 <xsl:call-template name="subjectAnyOrder"/>
8502 <xsl:template match="marc:datafield[@tag=653]">
8504 <xsl:for-each select="marc:subfield[@code='a']">
8506 <xsl:value-of select="."/>
8511 <xsl:template match="marc:datafield[@tag=656]">
8513 <xsl:if test="marc:subfield[@code=2]">
8514 <xsl:attribute name="authority">
8515 <xsl:value-of select="marc:subfield[@code=2]"/>
8519 <xsl:call-template name="chopPunctuation">
8520 <xsl:with-param name="chopString">
8521 <xsl:value-of select="marc:subfield[@code='a']"/>
8523 </xsl:call-template>
8527 <xsl:template name="termsOfAddress">
8528 <xsl:if test="marc:subfield[@code='b' or @code='c']">
8529 <namePart type="termsOfAddress">
8530 <xsl:call-template name="chopPunctuation">
8531 <xsl:with-param name="chopString">
8532 <xsl:call-template name="subfieldSelect">
8533 <xsl:with-param name="codes">bc</xsl:with-param>
8534 </xsl:call-template>
8536 </xsl:call-template>
8540 <xsl:template name="displayLabel">
8541 <xsl:if test="marc:subfield[@code='i']">
8542 <xsl:attribute name="displayLabel">
8543 <xsl:value-of select="marc:subfield[@code='i']"/>
8546 <xsl:if test="marc:subfield[@code='3']">
8547 <xsl:attribute name="displayLabel">
8548 <xsl:value-of select="marc:subfield[@code='3']"/>
8552 <xsl:template name="isInvalid">
8553 <xsl:param name="type"/>
8555 test="marc:subfield[@code='z'] or marc:subfield[@code='y'] or marc:subfield[@code='m']">
8557 <xsl:attribute name="type">
8558 <xsl:value-of select="$type"/>
8560 <xsl:attribute name="invalid">
8561 <xsl:text>yes</xsl:text>
8563 <xsl:if test="marc:subfield[@code='z']">
8564 <xsl:value-of select="marc:subfield[@code='z']"/>
8566 <xsl:if test="marc:subfield[@code='y']">
8567 <xsl:value-of select="marc:subfield[@code='y']"/>
8569 <xsl:if test="marc:subfield[@code='m']">
8570 <xsl:value-of select="marc:subfield[@code='m']"/>
8575 <xsl:template name="subtitle">
8576 <xsl:if test="marc:subfield[@code='b']">
8578 <xsl:call-template name="chopPunctuation">
8579 <xsl:with-param name="chopString">
8580 <xsl:value-of select="marc:subfield[@code='b']"/>
8581 <!--<xsl:call-template name="subfieldSelect">
8582 <xsl:with-param name="codes">b</xsl:with-param>
8583 </xsl:call-template>-->
8585 </xsl:call-template>
8589 <xsl:template name="script">
8590 <xsl:param name="scriptCode"/>
8591 <xsl:attribute name="script">
8593 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
8594 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
8595 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
8596 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
8597 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
8598 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
8602 <xsl:template name="parsePart">
8603 <!-- assumes 773$q= 1:2:3<4
8604 with up to 3 levels and one optional start page
8606 <xsl:variable name="level1">
8608 <xsl:when test="contains(text(),':')">
8610 <xsl:value-of select="substring-before(text(),':')"/>
8612 <xsl:when test="not(contains(text(),':'))">
8614 <xsl:if test="contains(text(),'<')">
8616 <xsl:value-of select="substring-before(text(),'<')"/>
8618 <xsl:if test="not(contains(text(),'<'))">
8620 <xsl:value-of select="text()"/>
8625 <xsl:variable name="sici2">
8627 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
8628 <xsl:value-of select="substring(substring-after(text(),$level1),2)"/>
8631 <xsl:value-of select="substring-after(text(),$level1)"/>
8635 <xsl:variable name="level2">
8637 <xsl:when test="contains($sici2,':')">
8639 <xsl:value-of select="substring-before($sici2,':')"/>
8641 <xsl:when test="contains($sici2,'<')">
8643 <xsl:value-of select="substring-before($sici2,'<')"/>
8646 <xsl:value-of select="$sici2"/>
8651 <xsl:variable name="sici3">
8653 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
8654 <xsl:value-of select="substring(substring-after($sici2,$level2),2)"/>
8657 <xsl:value-of select="substring-after($sici2,$level2)"/>
8661 <xsl:variable name="level3">
8663 <xsl:when test="contains($sici3,'<')">
8665 <xsl:value-of select="substring-before($sici3,'<')"/>
8668 <xsl:value-of select="$sici3"/>
8673 <xsl:variable name="page">
8674 <xsl:if test="contains(text(),'<')">
8675 <xsl:value-of select="substring-after(text(),'<')"/>
8678 <xsl:if test="$level1">
8681 <xsl:value-of select="$level1"/>
8685 <xsl:if test="$level2">
8688 <xsl:value-of select="$level2"/>
8692 <xsl:if test="$level3">
8695 <xsl:value-of select="$level3"/>
8699 <xsl:if test="$page">
8700 <extent unit="page">
8702 <xsl:value-of select="$page"/>
8707 <xsl:template name="getLanguage">
8708 <xsl:param name="langString"/>
8709 <xsl:param name="controlField008-35-37"/>
8710 <xsl:variable name="length" select="string-length($langString)"/>
8712 <xsl:when test="$length=0"/>
8713 <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
8714 <xsl:call-template name="getLanguage">
8715 <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
8716 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
8717 </xsl:call-template>
8721 <languageTerm authority="iso639-2b" type="code">
8722 <xsl:value-of select="substring($langString,1,3)"/>
8725 <xsl:call-template name="getLanguage">
8726 <xsl:with-param name="langString" select="substring($langString,4,$length)"/>
8727 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"/>
8728 </xsl:call-template>
8732 <xsl:template name="isoLanguage">
8733 <xsl:param name="currentLanguage"/>
8734 <xsl:param name="usedLanguages"/>
8735 <xsl:param name="remainingLanguages"/>
8737 <xsl:when test="string-length($currentLanguage)=0"/>
8738 <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
8740 <xsl:if test="@code!='a'">
8741 <xsl:attribute name="objectPart">
8743 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
8744 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
8745 <xsl:when test="@code='e'">libretto</xsl:when>
8746 <xsl:when test="@code='f'">table of contents</xsl:when>
8747 <xsl:when test="@code='g'">accompanying material</xsl:when>
8748 <xsl:when test="@code='h'">translation</xsl:when>
8752 <languageTerm authority="iso639-2b" type="code">
8753 <xsl:value-of select="$currentLanguage"/>
8756 <xsl:call-template name="isoLanguage">
8757 <xsl:with-param name="currentLanguage">
8758 <xsl:value-of select="substring($remainingLanguages,1,3)"/>
8760 <xsl:with-param name="usedLanguages">
8761 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
8763 <xsl:with-param name="remainingLanguages">
8765 select="substring($remainingLanguages,4,string-length($remainingLanguages))"
8768 </xsl:call-template>
8771 <xsl:call-template name="isoLanguage">
8772 <xsl:with-param name="currentLanguage">
8773 <xsl:value-of select="substring($remainingLanguages,1,3)"/>
8775 <xsl:with-param name="usedLanguages">
8776 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"/>
8778 <xsl:with-param name="remainingLanguages">
8780 select="substring($remainingLanguages,4,string-length($remainingLanguages))"
8783 </xsl:call-template>
8787 <xsl:template name="chopBrackets">
8788 <xsl:param name="chopString"/>
8789 <xsl:variable name="string">
8790 <xsl:call-template name="chopPunctuation">
8791 <xsl:with-param name="chopString" select="$chopString"/>
8792 </xsl:call-template>
8794 <xsl:if test="substring($string, 1,1)='['">
8795 <xsl:value-of select="substring($string,2, string-length($string)-2)"/>
8797 <xsl:if test="substring($string, 1,1)!='['">
8798 <xsl:value-of select="$string"/>
8801 <xsl:template name="rfcLanguages">
8802 <xsl:param name="nodeNum"/>
8803 <xsl:param name="usedLanguages"/>
8804 <xsl:param name="controlField008-35-37"/>
8805 <xsl:variable name="currentLanguage" select="."/>
8807 <xsl:when test="not($currentLanguage)"/>
8809 test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
8810 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
8812 <xsl:if test="@code!='a'">
8813 <xsl:attribute name="objectPart">
8815 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
8816 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
8817 <xsl:when test="@code='e'">libretto</xsl:when>
8818 <xsl:when test="@code='f'">table of contents</xsl:when>
8819 <xsl:when test="@code='g'">accompanying material</xsl:when>
8820 <xsl:when test="@code='h'">translation</xsl:when>
8824 <languageTerm authority="rfc3066" type="code">
8825 <xsl:value-of select="$currentLanguage"/>
8830 <xsl:otherwise> </xsl:otherwise>
8834 <xsl:template name="datafield">
8835 <xsl:param name="tag"/>
8836 <xsl:param name="ind1">
8837 <xsl:text> </xsl:text>
8839 <xsl:param name="ind2">
8840 <xsl:text> </xsl:text>
8842 <xsl:param name="subfields"/>
8843 <xsl:element name="marc:datafield">
8844 <xsl:attribute name="tag">
8845 <xsl:value-of select="$tag"/>
8847 <xsl:attribute name="ind1">
8848 <xsl:value-of select="$ind1"/>
8850 <xsl:attribute name="ind2">
8851 <xsl:value-of select="$ind2"/>
8853 <xsl:copy-of select="$subfields"/>
8857 <xsl:template name="subfieldSelect">
8858 <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
8859 <xsl:param name="delimeter">
8860 <xsl:text> </xsl:text>
8862 <xsl:variable name="str">
8863 <xsl:for-each select="marc:subfield">
8864 <xsl:if test="contains($codes, @code)">
8865 <xsl:value-of select="text()"/>
8866 <xsl:value-of select="$delimeter"/>
8870 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
8873 <xsl:template name="buildSpaces">
8874 <xsl:param name="spaces"/>
8875 <xsl:param name="char">
8876 <xsl:text> </xsl:text>
8878 <xsl:if test="$spaces>0">
8879 <xsl:value-of select="$char"/>
8880 <xsl:call-template name="buildSpaces">
8881 <xsl:with-param name="spaces" select="$spaces - 1"/>
8882 <xsl:with-param name="char" select="$char"/>
8883 </xsl:call-template>
8887 <xsl:template name="chopPunctuation">
8888 <xsl:param name="chopString"/>
8889 <xsl:param name="punctuation">
8890 <xsl:text>.:,;/ </xsl:text>
8892 <xsl:variable name="length" select="string-length($chopString)"/>
8894 <xsl:when test="$length=0"/>
8895 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
8896 <xsl:call-template name="chopPunctuation">
8897 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
8898 <xsl:with-param name="punctuation" select="$punctuation"/>
8899 </xsl:call-template>
8901 <xsl:when test="not($chopString)"/>
8903 <xsl:value-of select="$chopString"/>
8908 <xsl:template name="chopPunctuationFront">
8909 <xsl:param name="chopString"/>
8910 <xsl:variable name="length" select="string-length($chopString)"/>
8912 <xsl:when test="$length=0"/>
8913 <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
8914 <xsl:call-template name="chopPunctuationFront">
8915 <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
8917 </xsl:call-template>
8919 <xsl:when test="not($chopString)"/>
8921 <xsl:value-of select="$chopString"/>
8926 <xsl:template name="chopPunctuationBack">
8927 <xsl:param name="chopString"/>
8928 <xsl:param name="punctuation">
8929 <xsl:text>.:,;/] </xsl:text>
8931 <xsl:variable name="length" select="string-length($chopString)"/>
8933 <xsl:when test="$length=0"/>
8934 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
8935 <xsl:call-template name="chopPunctuation">
8936 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
8937 <xsl:with-param name="punctuation" select="$punctuation"/>
8938 </xsl:call-template>
8940 <xsl:when test="not($chopString)"/>
8942 <xsl:value-of select="$chopString"/>
8947 <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
8948 <xsl:template name="url-encode">
8950 <xsl:param name="str"/>
8952 <xsl:if test="$str">
8953 <xsl:variable name="first-char" select="substring($str,1,1)"/>
8955 <xsl:when test="contains($safe,$first-char)">
8956 <xsl:value-of select="$first-char"/>
8959 <xsl:variable name="codepoint">
8961 <xsl:when test="contains($ascii,$first-char)">
8963 select="string-length(substring-before($ascii,$first-char)) + 32"
8966 <xsl:when test="contains($latin1,$first-char)">
8968 select="string-length(substring-before($latin1,$first-char)) + 160"/>
8972 <xsl:message terminate="no">Warning: string contains a character
8973 that is out of range! Substituting "?".</xsl:message>
8974 <xsl:text>63</xsl:text>
8978 <xsl:variable name="hex-digit1"
8979 select="substring($hex,floor($codepoint div 16) + 1,1)"/>
8980 <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
8981 <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
8982 <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
8985 <xsl:if test="string-length($str) > 1">
8986 <xsl:call-template name="url-encode">
8987 <xsl:with-param name="str" select="substring($str,2)"/>
8988 </xsl:call-template>
8992 </xsl:stylesheet>$$ WHERE name = 'mods33';
8995 INSERT INTO config.global_flag (name, value, enabled, label) VALUES
8997 'opac.browse.warnable_regexp_per_class',
8998 '{"title": "^(a|the|an)\\s"}',
9001 'opac.browse.warnable_regexp_per_class',
9002 'Map of search classes to regular expressions to warn user about leading articles.',
9008 'opac.browse.holdings_visibility_test_limit',
9012 'opac.browse.holdings_visibility_test_limit',
9013 'Don''t look for more than this number of records with holdings when displaying browse headings with visible record counts.',
9019 ALTER TABLE metabib.browse_entry DROP CONSTRAINT browse_entry_value_key;
9020 ALTER TABLE metabib.browse_entry ADD COLUMN sort_value TEXT;
9021 DELETE FROM metabib.browse_entry_def_map; -- Yeah.
9022 DELETE FROM metabib.browse_entry WHERE sort_value IS NULL;
9023 ALTER TABLE metabib.browse_entry ALTER COLUMN sort_value SET NOT NULL;
9024 ALTER TABLE metabib.browse_entry ADD UNIQUE (sort_value, value);
9025 DROP TRIGGER IF EXISTS mbe_sort_value ON metabib.browse_entry;
9027 CREATE INDEX browse_entry_sort_value_idx
9028 ON metabib.browse_entry USING BTREE (sort_value);
9030 -- NOTE If I understand ordered indices correctly, an index on sort_value DESC
9031 -- is not actually needed, even though we do have a query that does ORDER BY
9032 -- on this column in that direction. The previous index serves for both
9033 -- directions, and ordering in an index is only helpful for multi-column
9034 -- indices, I think. See http://www.postgresql.org/docs/9.1/static/indexes-ordering.html
9036 -- CREATE INDEX CONCURRENTLY browse_entry_sort_value_idx_desc
9037 -- ON metabib.browse_entry USING BTREE (sort_value DESC);
9039 CREATE TYPE metabib.flat_browse_entry_appearance AS (
9040 browse_entry BIGINT,
9044 sources INT, -- visible ones, that is
9045 row_number INT, -- internal use, sort of
9046 accurate BOOL, -- Count in sources field is accurate? Not
9047 -- if we had more than a browse superpage
9048 -- of records to look at.
9053 CREATE OR REPLACE FUNCTION metabib.browse_pivot(
9056 ) RETURNS BIGINT AS $p$
9060 SELECT INTO id mbe.id FROM metabib.browse_entry mbe
9061 JOIN metabib.browse_entry_def_map mbedm ON (
9062 mbedm.entry = mbe.id AND
9063 mbedm.def = ANY(search_field)
9065 WHERE mbe.sort_value >= public.search_normalize(browse_term)
9066 ORDER BY mbe.sort_value, mbe.value LIMIT 1;
9070 $p$ LANGUAGE PLPGSQL;
9072 CREATE OR REPLACE FUNCTION metabib.staged_browse(
9076 context_locations INT[],
9078 browse_superpage_size INT,
9079 count_up_from_zero BOOL, -- if false, count down from -1
9082 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9087 result_row metabib.flat_browse_entry_appearance%ROWTYPE;
9088 results_skipped INT := 0;
9089 row_counter INT := 0;
9094 all_records BIGINT[];
9095 superpage_of_records BIGINT[];
9098 IF count_up_from_zero THEN
9104 OPEN curs FOR EXECUTE query;
9107 FETCH curs INTO rec;
9109 IF result_row.pivot_point IS NOT NULL THEN
9110 RETURN NEXT result_row;
9115 -- Gather aggregate data based on the MBE row we're looking at now
9116 SELECT INTO all_records, result_row.authorities, result_row.fields
9117 ARRAY_AGG(DISTINCT source),
9118 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT authority), $$,$$),
9119 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT def), $$,$$)
9120 FROM metabib.browse_entry_def_map
9121 WHERE entry = rec.id
9122 AND def = ANY(fields);
9124 result_row.sources := 0;
9126 full_end := ARRAY_LENGTH(all_records, 1);
9127 superpage_size := COALESCE(browse_superpage_size, full_end);
9129 slice_end := superpage_size;
9131 WHILE result_row.sources = 0 AND slice_start <= full_end LOOP
9132 superpage_of_records := all_records[slice_start:slice_end];
9134 'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
9135 '1::INT AS rel FROM (SELECT UNNEST(' ||
9136 quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
9138 -- We use search.query_parser_fts() for visibility testing.
9139 -- We're calling it once per browse-superpage worth of records
9140 -- out of the set of records related to a given mbe, until we've
9141 -- either exhausted that set of records or found at least 1
9144 SELECT INTO result_row.sources visible
9145 FROM search.query_parser_fts(
9146 context_org, NULL, qpfts_query, NULL,
9147 context_locations, 0, NULL, NULL, FALSE, staff, FALSE
9149 WHERE qpfts.rel IS NULL;
9151 slice_start := slice_start + superpage_size;
9152 slice_end := slice_end + superpage_size;
9155 -- Accurate? Well, probably.
9156 result_row.accurate := browse_superpage_size IS NULL OR
9157 browse_superpage_size >= full_end;
9159 IF result_row.sources > 0 THEN
9160 -- We've got a browse entry with visible holdings. Yay.
9163 -- The function that calls this function needs row_number in order
9164 -- to correctly order results from two different runs of this
9166 result_row.row_number := row_number;
9168 -- Now, if row_counter is still less than limit, return a row. If
9169 -- not, but it is less than next_pivot_pos, continue on without
9170 -- returning actual result rows until we find
9171 -- that next pivot, and return it.
9173 IF row_counter < result_limit THEN
9174 result_row.browse_entry := rec.id;
9175 result_row.value := rec.value;
9177 RETURN NEXT result_row;
9179 result_row.browse_entry := NULL;
9180 result_row.authorities := NULL;
9181 result_row.fields := NULL;
9182 result_row.value := NULL;
9183 result_row.sources := NULL;
9184 result_row.accurate := NULL;
9185 result_row.pivot_point := rec.id;
9187 IF row_counter >= next_pivot_pos THEN
9188 RETURN NEXT result_row;
9193 IF count_up_from_zero THEN
9194 row_number := row_number + 1;
9196 row_number := row_number - 1;
9199 -- row_counter is different from row_number.
9200 -- It simply counts up from zero so that we know when
9201 -- we've reached our limit.
9202 row_counter := row_counter + 1;
9206 $p$ LANGUAGE PLPGSQL;
9208 CREATE OR REPLACE FUNCTION metabib.browse(
9211 context_org INT DEFAULT NULL,
9212 context_loc_group INT DEFAULT NULL,
9213 staff BOOL DEFAULT FALSE,
9214 pivot_id BIGINT DEFAULT NULL,
9215 result_limit INT DEFAULT 10
9216 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9221 pivot_sort_value TEXT;
9222 pivot_sort_fallback TEXT;
9223 context_locations INT[];
9224 browse_superpage_size INT;
9225 results_skipped INT := 0;
9229 forward_to_pivot INT;
9231 -- First, find the pivot if we were given a browse term but not a pivot.
9232 IF pivot_id IS NULL THEN
9233 pivot_id := metabib.browse_pivot(search_field, browse_term);
9236 SELECT INTO pivot_sort_value, pivot_sort_fallback
9237 sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
9239 -- Bail if we couldn't find a pivot.
9240 IF pivot_sort_value IS NULL THEN
9244 -- Transform the context_loc_group argument (if any) (logc at the
9245 -- TPAC layer) into a form we'll be able to use.
9246 IF context_loc_group IS NOT NULL THEN
9247 SELECT INTO context_locations ARRAY_AGG(location)
9248 FROM asset.copy_location_group_map
9249 WHERE lgroup = context_loc_group;
9252 -- Get the configured size of browse superpages.
9253 SELECT INTO browse_superpage_size value -- NULL ok
9254 FROM config.global_flag
9255 WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
9257 -- First we're going to search backward from the pivot, then we're going
9258 -- to search forward. In each direction, we need two limits. At the
9259 -- lesser of the two limits, we delineate the edge of the result set
9260 -- we're going to return. At the greater of the two limits, we find the
9261 -- pivot value that would represent an offset from the current pivot
9262 -- at a distance of one "page" in either direction, where a "page" is a
9263 -- result set of the size specified in the "result_limit" argument.
9265 -- The two limits in each direction make four derived values in total,
9266 -- and we calculate them now.
9267 back_limit := CEIL(result_limit::FLOAT / 2);
9268 back_to_pivot := result_limit;
9269 forward_limit := result_limit / 2;
9270 forward_to_pivot := result_limit - 1;
9272 -- This is the meat of the SQL query that finds browse entries. We'll
9273 -- pass this to a function which uses it with a cursor, so that individual
9274 -- rows may be fetched in a loop until some condition is satisfied, without
9275 -- waiting for a result set of fixed size to be collected all at once.
9281 FROM metabib.browse_entry mbe
9282 WHERE EXISTS (SELECT 1 FROM metabib.browse_entry_def_map mbedm WHERE
9283 mbedm.entry = mbe.id AND
9284 mbedm.def = ANY(' || quote_literal(search_field) || ')
9287 -- This is the variant of the query for browsing backward.
9288 back_query := core_query ||
9289 ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
9290 ' ORDER BY mbe.sort_value DESC, mbe.value DESC ';
9292 -- This variant browses forward.
9293 forward_query := core_query ||
9294 ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
9295 ' ORDER BY mbe.sort_value, mbe.value ';
9297 -- We now call the function which applies a cursor to the provided
9298 -- queries, stopping at the appropriate limits and also giving us
9299 -- the next page's pivot.
9301 SELECT * FROM metabib.staged_browse(
9302 back_query, search_field, context_org, context_locations,
9303 staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
9305 SELECT * FROM metabib.staged_browse(
9306 forward_query, search_field, context_org, context_locations,
9307 staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
9308 ) ORDER BY row_number DESC;
9311 $p$ LANGUAGE PLPGSQL;
9313 CREATE OR REPLACE FUNCTION metabib.browse(
9316 context_org INT DEFAULT NULL,
9317 context_loc_group INT DEFAULT NULL,
9318 staff BOOL DEFAULT FALSE,
9319 pivot_id BIGINT DEFAULT NULL,
9320 result_limit INT DEFAULT 10
9321 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
9323 RETURN QUERY SELECT * FROM metabib.browse(
9324 (SELECT COALESCE(ARRAY_AGG(id), ARRAY[]::INT[])
9325 FROM config.metabib_field WHERE field_class = search_class),
9334 $p$ LANGUAGE PLPGSQL;
9336 UPDATE config.metabib_field
9338 xpath = $$//mods32:mods/mods32:relatedItem[@type="series"]/mods32:titleInfo[@type="nfi"]$$,
9339 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9342 field_class = 'series' AND name = 'seriestitle' ;
9344 UPDATE config.metabib_field
9346 xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and not (@type)]$$,
9347 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9348 browse_xpath = NULL,
9351 field_class = 'title' AND name = 'proper' ;
9353 UPDATE config.metabib_field
9355 xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='alternative-nfi')]$$,
9356 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9359 field_class = 'title' AND name = 'alternative' ;
9361 UPDATE config.metabib_field
9363 xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='uniform-nfi')]$$,
9364 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9367 field_class = 'title' AND name = 'uniform' ;
9369 UPDATE config.metabib_field
9371 xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and (@type='translated-nfi')]$$,
9372 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
9375 field_class = 'title' AND name = 'translated' ;
9377 -- This keeps extra terms like "creator" out of browse headings.
9378 UPDATE config.metabib_field
9379 SET browse_xpath = $$//*[local-name()='namePart']$$ -- vim */
9382 browse_xpath IS NULL AND
9383 field_class = 'author';
9385 INSERT INTO config.org_unit_setting_type (
9386 name, label, grp, description, datatype
9388 'opac.browse.pager_shortcuts',
9389 'Paging shortcut links for OPAC Browse',
9391 'The characters in this string, in order, will be used as shortcut links for quick paging in the OPAC browse interface. Any sequence surrounded by asterisks will be taken as a whole label, not split into individual labels at the character level, but only the first character will serve as the basis of the search.',
9396 -- NOTE: very IDs are still correct for perms and event_def data at merge.
9398 SELECT evergreen.upgrade_deps_block_check('0817', :eg_version);
9402 INSERT INTO config.copy_status
9403 (id, name, holdable, opac_visible, copy_active, restrict_copy_delete)
9404 VALUES (16, oils_i18n_gettext(16, 'Long Overdue', 'ccs', 'name'), 'f', 'f', 'f', 't');
9406 -- checkin override perm
9408 INSERT INTO permission.perm_list (id, code, description) VALUES (
9410 'COPY_STATUS_LONGOVERDUE.override',
9413 'Allows the user to check-in long-overdue items, prompting ' ||
9414 'long-overdue check-in processing',
9420 'SET_CIRC_LONG_OVERDUE',
9423 'Allows the user to mark a circulation as long-overdue',
9431 INSERT INTO config.billing_type (id, owner, name) VALUES
9432 (10, 1, oils_i18n_gettext(
9433 10, 'Long-Overdue Materials', 'cbt', 'name')),
9434 (11, 1, oils_i18n_gettext(
9435 11, 'Long-Overdue Materials Processing Fee', 'cbt', 'name'));
9439 INSERT INTO config.org_unit_setting_type
9440 (name, grp, datatype, label, description) VALUES
9442 'circ.longoverdue_immediately_available',
9445 'circ.longoverdue_immediately_available',
9446 'Long-Overdue Items Usable on Checkin',
9451 'circ.longoverdue_immediately_available',
9452 'Long-overdue items are usable on checkin instead of going "home" first',
9457 'circ.longoverdue_materials_processing_fee',
9458 'finance', 'currency',
9460 'circ.longoverdue_materials_processing_fee',
9461 'Long-Overdue Materials Processing Fee',
9466 'circ.longoverdue_materials_processing_fee',
9467 'Long-Overdue Materials Processing Fee',
9472 'circ.max_accept_return_of_longoverdue',
9475 'circ.max_accept_return_of_longoverdue',
9476 'Long-Overdue Max Return Interval',
9481 'circ.max_accept_return_of_longoverdue',
9482 'Long-overdue check-in processing (voiding fees, re-instating ' ||
9483 'overdues, etc.) will not take place for items that have been ' ||
9484 'overdue for (or have last activity older than) this amount of time',
9489 'circ.restore_overdue_on_longoverdue_return',
9492 'circ.restore_overdue_on_longoverdue_return',
9493 'Restore Overdues on Long-Overdue Item Return',
9498 'circ.restore_overdue_on_longoverdue_return',
9499 'Restore Overdues on Long-Overdue Item Return',
9504 'circ.void_longoverdue_on_checkin',
9507 'circ.void_longoverdue_on_checkin',
9508 'Void Long-Overdue Item Billing When Returned',
9513 'circ.void_longoverdue_on_checkin',
9514 'Void Long-Overdue Item Billing When Returned',
9519 'circ.void_longoverdue_proc_fee_on_checkin',
9522 'circ.void_longoverdue_proc_fee_on_checkin',
9523 'Void Processing Fee on Long-Overdue Item Return',
9528 'circ.void_longoverdue_proc_fee_on_checkin',
9529 'Void Processing Fee on Long-Overdue Item Return',
9534 'circ.void_overdue_on_longoverdue',
9537 'circ.void_overdue_on_longoverdue',
9538 'Void Overdue Fines When Items are Marked Long-Overdue',
9543 'circ.void_overdue_on_longoverdue',
9544 'Void Overdue Fines When Items are Marked Long-Overdue',
9549 'circ.longoverdue.xact_open_on_zero',
9552 'circ.longoverdue.xact_open_on_zero',
9553 'Leave transaction open when long overdue balance equals zero',
9558 'circ.longoverdue.xact_open_on_zero',
9559 'Leave transaction open when long-overdue balance equals zero. ' ||
9560 'This leaves the lost copy on the patron record when it is paid',
9565 'circ.longoverdue.use_last_activity_date_on_return',
9568 'circ.longoverdue.use_last_activity_date_on_return',
9569 'Long-Overdue Check-In Interval Uses Last Activity Date',
9574 'circ.longoverdue.use_last_activity_date_on_return',
9575 'Use the long-overdue last-activity date instead of the due_date to ' ||
9576 'determine whether the item has been checked out too long to ' ||
9577 'perform long-overdue check-in processing. If set, the system ' ||
9578 'will first check the last payment time, followed by the last ' ||
9579 'billing time, followed by the due date. See also ' ||
9580 'circ.max_accept_return_of_longoverdue',
9586 -- mark long-overdue reactor
9588 INSERT INTO action_trigger.reactor (module, description) VALUES
9589 ( 'MarkItemLongOverdue',
9591 'MarkItemLongOverdue',
9592 'Marks a circulating item as long-overdue and applies configured ' ||
9593 'penalties. Also creates events for the longoverdue.auto hook',
9599 INSERT INTO action_trigger.validator (module, description) VALUES (
9600 'PatronNotInCollections',
9601 'Event is valid if the linked patron is not in collections processing ' ||
9602 'at the context org unit'
9606 INSERT INTO action_trigger.event_definition
9607 (id, active, owner, name, hook, validator, reactor, delay, delay_field)
9609 49, FALSE, 1, '6 Month Overdue Mark Long-Overdue',
9610 'checkout.due', 'PatronNotInCollections',
9611 'MarkItemLongOverdue', '6 months', 'due_date'
9615 INSERT INTO action_trigger.event_params (event_def, param, value) VALUES
9616 (49, 'editor', '''1''');
9618 -- new longoverdue and longervdue.auto hook.
9620 INSERT INTO action_trigger.hook (key,core_type,description) VALUES (
9623 'Circulating Item marked long-overdue'
9626 INSERT INTO action_trigger.hook (key,core_type,description) VALUES (
9629 'Circulating Item automatically marked long-overdue'
9632 -- sample longoverdue.auto notification reactor
9635 INSERT INTO action_trigger.event_definition
9636 (id, active, owner, name, hook, validator, reactor, group_field, template)
9638 50, FALSE, 1, '6 Month Long Overdue Notice',
9639 'longoverdue.auto', 'NOOP_True', 'SendEmail', 'usr',
9642 [%- user = target.0.usr -%]
9643 To: [%- params.recipient_email || user.email %]
9644 From: [%- params.sender_email || default_sender %]
9645 Subject: Overdue Items Marked Long Overdue
9647 Dear [% user.family_name %], [% user.first_given_name %]
9648 The following items are 6 months overdue and have been marked Long Overdue.
9650 [% FOR circ IN target %]
9651 [%- copy_details = helpers.get_copy_bib_basics(circ.target_copy.id) -%]
9652 Title: [% copy_details.title %], by [% copy_details.author %]
9653 Call Number: [% circ.target_copy.call_number.label %]
9654 Shelving Location: [% circ.target_copy.location.name %]
9655 Barcode: [% circ.target_copy.barcode %]
9656 Due: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
9657 Item Cost: [% helpers.get_copy_price(circ.target_copy) %]
9658 Total Owed For Transaction: [% circ.billable_transaction.summary.balance_owed %]
9659 Library: [% circ.circ_lib.name %]
9667 INSERT INTO action_trigger.environment (event_def, path) VALUES
9668 (50, 'target_copy.call_number'),
9670 (50, 'billable_transaction.summary'),
9671 (50, 'circ_lib.billing_address'),
9672 (50, 'target_copy.location');
9677 SELECT evergreen.upgrade_deps_block_check('0822', :eg_version);
9679 ALTER TABLE action.hold_request
9680 ADD COLUMN behind_desk BOOLEAN NOT NULL DEFAULT FALSE;
9682 -- The value on the hold is the new arbiter of whether a
9683 -- hold should be held behind the desk and reported as such
9684 -- Update existing holds that would in the current regime
9685 -- be considered behind-the-desk holds to use the new column
9687 UPDATE action.hold_request ahr
9688 SET behind_desk = TRUE
9689 FROM actor.usr_setting aus
9691 ahr.cancel_time IS NULL AND
9692 ahr.fulfillment_time IS NULL AND
9693 aus.usr = ahr.usr AND
9694 aus.name = 'circ.holds_behind_desk' AND
9695 aus.value = 'true' AND
9698 FROM actor.org_unit_ancestor_setting(
9699 'circ.holds.behind_desk_pickup_supported',
9702 WHERE value = 'true'
9707 SELECT evergreen.upgrade_deps_block_check('0823', :eg_version);
9709 -- Track the requesting user
9710 ALTER TABLE staging.user_stage
9711 ADD COLUMN requesting_usr INTEGER
9712 REFERENCES actor.usr(id) ON DELETE SET NULL;
9714 -- add county column to staged address tables and
9715 -- drop state requirement to match actor.usr_address
9716 ALTER TABLE staging.mailing_address_stage
9717 ADD COLUMN county TEXT,
9718 ALTER COLUMN state DROP DEFAULT,
9719 ALTER COLUMN state DROP NOT NULL;
9721 ALTER TABLE staging.billing_address_stage
9722 ADD COLUMN county TEXT,
9723 ALTER COLUMN state DROP DEFAULT,
9724 ALTER COLUMN state DROP NOT NULL;
9726 -- stored procedure for deleting expired pending patrons
9727 CREATE OR REPLACE FUNCTION staging.purge_pending_users() RETURNS VOID AS $$
9732 FOR org_id IN SELECT DISTINCT(home_ou) FROM staging.user_stage LOOP
9734 SELECT INTO intvl value FROM
9735 actor.org_unit_ancestor_setting(
9736 'opac.pending_user_expire_interval', org_id);
9738 CONTINUE WHEN intvl IS NULL OR intvl ILIKE 'null';
9740 -- de-JSON-ify the string
9741 SELECT INTO intvl TRIM(BOTH '"' FROM intvl);
9743 DELETE FROM staging.user_stage
9744 WHERE home_ou = org_id AND row_date + intvl::INTERVAL < NOW();
9748 $$ LANGUAGE PLPGSQL;
9751 INSERT INTO config.org_unit_setting_type
9752 (name, grp, datatype, label, description)
9754 'opac.allow_pending_user',
9758 'opac.allow_pending_user',
9759 'Allow Patron Self-Registration',
9764 'opac.allow_pending_user',
9765 'Allow patrons to self-register, creating pending user accounts',
9770 'opac.pending_user_expire_interval',
9774 'opac.pending_user_expire_interval',
9775 'Patron Self-Reg. Expire Interval',
9780 'opac.pending_user_expire_interval',
9781 'If set, this is the amount of time a pending user account will ' ||
9782 'be allowed to sit in the database. After this time, the pending ' ||
9783 'user information will be purged',
9788 'ui.patron.edit.aua.county.show',
9792 'ui.patron.edit.aua.county.require',
9793 'Show county field on patron registration',
9798 'ui.patron.edit.aua.county.require',
9799 'The county field will be shown on the patron registration screen',
9807 SELECT evergreen.upgrade_deps_block_check('0824', :eg_version);
9809 INSERT INTO config.org_unit_setting_type
9810 (grp, name, label, description, datatype, fm_class)
9813 'vandelay.item.barcode.auto',
9815 'vandelay.item.barcode.auto',
9816 'Vandelay Generate Default Barcodes',
9819 'vandelay.item.barcode.auto',
9820 'Auto-generate deault item barcodes when no item barcode is present',
9826 'vandelay.item.barcode.prefix',
9828 'vandelay.item.barcode.prefix',
9829 'Vandelay Default Barcode Prefix',
9832 'vandelay.item.barcode.prefix',
9833 'Apply this prefix to any auto-generated item barcodes',
9839 'vandelay.item.call_number.auto',
9841 'vandelay.item.call_number.auto',
9842 'Vandelay Generate Default Call Numbers',
9845 'vandelay.item.call_number.auto',
9846 'Auto-generate default item call numbers when no item call number is present',
9852 'vandelay.item.call_number.prefix',
9854 'vandelay.item.call_number.prefix',
9855 'Vandelay Default Call Number Prefix',
9858 'vandelay.item.call_number.prefix',
9859 'Apply this prefix to any auto-generated item call numbers',
9865 'vandelay.item.copy_location.default',
9867 'vandelay.item.copy_location.default',
9868 'Vandelay Default Copy Location',
9871 'vandelay.item.copy_location.default',
9872 'Default copy location value for imported items',
9878 'vandelay.item.circ_modifier.default',
9880 'vandelay.item.circ_modifier.default',
9881 'Vandelay Default Circulation Modifier',
9884 'vandelay.item.circ_modifier.default',
9885 'Default circulation modifier value for imported items',
9892 CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
9903 deposit_amount TEXT;
9917 tmp_attr_set RECORD;
9918 attr_set vandelay.import_item%ROWTYPE;
9925 SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
9929 attr_set.definition := attr_def.id;
9931 -- Build the combined XPath
9935 WHEN attr_def.owning_lib IS NULL THEN 'null()'
9936 WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.owning_lib || '"]'
9937 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.owning_lib
9942 WHEN attr_def.circ_lib IS NULL THEN 'null()'
9943 WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_lib || '"]'
9944 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_lib
9949 WHEN attr_def.call_number IS NULL THEN 'null()'
9950 WHEN LENGTH( attr_def.call_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.call_number || '"]'
9951 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.call_number
9956 WHEN attr_def.copy_number IS NULL THEN 'null()'
9957 WHEN LENGTH( attr_def.copy_number ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.copy_number || '"]'
9958 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.copy_number
9963 WHEN attr_def.status IS NULL THEN 'null()'
9964 WHEN LENGTH( attr_def.status ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.status || '"]'
9965 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.status
9970 WHEN attr_def.location IS NULL THEN 'null()'
9971 WHEN LENGTH( attr_def.location ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.location || '"]'
9972 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.location
9977 WHEN attr_def.circulate IS NULL THEN 'null()'
9978 WHEN LENGTH( attr_def.circulate ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circulate || '"]'
9979 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circulate
9984 WHEN attr_def.deposit IS NULL THEN 'null()'
9985 WHEN LENGTH( attr_def.deposit ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit || '"]'
9986 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit
9991 WHEN attr_def.deposit_amount IS NULL THEN 'null()'
9992 WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.deposit_amount || '"]'
9993 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.deposit_amount
9998 WHEN attr_def.ref IS NULL THEN 'null()'
9999 WHEN LENGTH( attr_def.ref ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.ref || '"]'
10000 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.ref
10005 WHEN attr_def.holdable IS NULL THEN 'null()'
10006 WHEN LENGTH( attr_def.holdable ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.holdable || '"]'
10007 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.holdable
10012 WHEN attr_def.price IS NULL THEN 'null()'
10013 WHEN LENGTH( attr_def.price ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.price || '"]'
10014 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.price
10019 WHEN attr_def.barcode IS NULL THEN 'null()'
10020 WHEN LENGTH( attr_def.barcode ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.barcode || '"]'
10021 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.barcode
10026 WHEN attr_def.circ_modifier IS NULL THEN 'null()'
10027 WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_modifier || '"]'
10028 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_modifier
10033 WHEN attr_def.circ_as_type IS NULL THEN 'null()'
10034 WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.circ_as_type || '"]'
10035 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.circ_as_type
10040 WHEN attr_def.alert_message IS NULL THEN 'null()'
10041 WHEN LENGTH( attr_def.alert_message ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.alert_message || '"]'
10042 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.alert_message
10047 WHEN attr_def.opac_visible IS NULL THEN 'null()'
10048 WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.opac_visible || '"]'
10049 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.opac_visible
10054 WHEN attr_def.pub_note IS NULL THEN 'null()'
10055 WHEN LENGTH( attr_def.pub_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.pub_note || '"]'
10056 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.pub_note
10060 WHEN attr_def.priv_note IS NULL THEN 'null()'
10061 WHEN LENGTH( attr_def.priv_note ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.priv_note || '"]'
10062 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.priv_note
10067 WHEN attr_def.internal_id IS NULL THEN 'null()'
10068 WHEN LENGTH( attr_def.internal_id ) = 1 THEN '//*[@tag="' || attr_def.tag || '"]/*[@code="' || attr_def.internal_id || '"]'
10069 ELSE '//*[@tag="' || attr_def.tag || '"]/*' || attr_def.internal_id
10075 owning_lib || '|' ||
10077 call_number || '|' ||
10078 copy_number || '|' ||
10081 circulate || '|' ||
10083 deposit_amount || '|' ||
10088 circ_modifier || '|' ||
10089 circ_as_type || '|' ||
10090 alert_message || '|' ||
10092 priv_note || '|' ||
10093 internal_id || '|' ||
10096 FOR tmp_attr_set IN
10098 FROM oils_xpath_table( 'id', 'marc', 'vandelay.queued_bib_record', xpath, 'id = ' || import_id )
10099 AS t( id INT, ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
10100 dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
10101 circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT, opac_vis TEXT )
10104 attr_set.import_error := NULL;
10105 attr_set.error_detail := NULL;
10106 attr_set.deposit_amount := NULL;
10107 attr_set.copy_number := NULL;
10108 attr_set.price := NULL;
10109 attr_set.circ_modifier := NULL;
10110 attr_set.location := NULL;
10111 attr_set.barcode := NULL;
10112 attr_set.call_number := NULL;
10114 IF tmp_attr_set.pr != '' THEN
10115 tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
10116 IF tmp_str = '' THEN
10117 attr_set.import_error := 'import.item.invalid.price';
10118 attr_set.error_detail := tmp_attr_set.pr; -- original value
10119 RETURN NEXT attr_set; CONTINUE;
10121 attr_set.price := tmp_str::NUMERIC(8,2);
10124 IF tmp_attr_set.dep_amount != '' THEN
10125 tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
10126 IF tmp_str = '' THEN
10127 attr_set.import_error := 'import.item.invalid.deposit_amount';
10128 attr_set.error_detail := tmp_attr_set.dep_amount;
10129 RETURN NEXT attr_set; CONTINUE;
10131 attr_set.deposit_amount := tmp_str::NUMERIC(8,2);
10134 IF tmp_attr_set.cnum != '' THEN
10135 tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
10136 IF tmp_str = '' THEN
10137 attr_set.import_error := 'import.item.invalid.copy_number';
10138 attr_set.error_detail := tmp_attr_set.cnum;
10139 RETURN NEXT attr_set; CONTINUE;
10141 attr_set.copy_number := tmp_str::INT;
10144 IF tmp_attr_set.ol != '' THEN
10145 SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
10147 attr_set.import_error := 'import.item.invalid.owning_lib';
10148 attr_set.error_detail := tmp_attr_set.ol;
10149 RETURN NEXT attr_set; CONTINUE;
10153 IF tmp_attr_set.clib != '' THEN
10154 SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
10156 attr_set.import_error := 'import.item.invalid.circ_lib';
10157 attr_set.error_detail := tmp_attr_set.clib;
10158 RETURN NEXT attr_set; CONTINUE;
10162 IF tmp_attr_set.cs != '' THEN
10163 SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
10165 attr_set.import_error := 'import.item.invalid.status';
10166 attr_set.error_detail := tmp_attr_set.cs;
10167 RETURN NEXT attr_set; CONTINUE;
10171 IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
10173 -- no circ mod defined, see if we should apply a default
10174 SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value)
10175 FROM actor.org_unit_ancestor_setting(
10176 'vandelay.item.circ_modifier.default',
10177 attr_set.owning_lib
10180 -- make sure the value from the org setting is still valid
10181 PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
10183 attr_set.import_error := 'import.item.invalid.circ_modifier';
10184 attr_set.error_detail := tmp_attr_set.circ_mod;
10185 RETURN NEXT attr_set; CONTINUE;
10190 SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
10192 attr_set.import_error := 'import.item.invalid.circ_modifier';
10193 attr_set.error_detail := tmp_attr_set.circ_mod;
10194 RETURN NEXT attr_set; CONTINUE;
10198 IF tmp_attr_set.circ_as != '' THEN
10199 SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
10201 attr_set.import_error := 'import.item.invalid.circ_as_type';
10202 attr_set.error_detail := tmp_attr_set.circ_as;
10203 RETURN NEXT attr_set; CONTINUE;
10207 IF COALESCE(tmp_attr_set.cl, '') = '' THEN
10208 -- no location specified, see if we should apply a default
10210 SELECT INTO attr_set.location TRIM(BOTH '"' FROM value)
10211 FROM actor.org_unit_ancestor_setting(
10212 'vandelay.item.copy_location.default',
10213 attr_set.owning_lib
10216 -- make sure the value from the org setting is still valid
10217 PERFORM 1 FROM asset.copy_location WHERE id = attr_set.location;
10219 attr_set.import_error := 'import.item.invalid.location';
10220 attr_set.error_detail := tmp_attr_set.cs;
10221 RETURN NEXT attr_set; CONTINUE;
10225 -- search up the org unit tree for a matching copy location
10226 WITH RECURSIVE anscestor_depth AS (
10228 out.depth AS depth,
10230 FROM actor.org_unit ou
10231 JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
10232 WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
10237 FROM actor.org_unit ou
10238 JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
10239 JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
10240 ) SELECT cpl.id INTO attr_set.location
10241 FROM anscestor_depth a
10242 JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
10243 WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
10244 ORDER BY a.depth DESC
10248 attr_set.import_error := 'import.item.invalid.location';
10249 attr_set.error_detail := tmp_attr_set.cs;
10250 RETURN NEXT attr_set; CONTINUE;
10254 attr_set.circulate :=
10255 LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
10256 OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
10258 attr_set.deposit :=
10259 LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
10260 OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
10262 attr_set.holdable :=
10263 LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
10264 OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
10266 attr_set.opac_visible :=
10267 LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
10268 OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
10271 LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
10272 OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
10274 attr_set.call_number := tmp_attr_set.cn; -- TEXT
10275 attr_set.barcode := tmp_attr_set.bc; -- TEXT,
10276 attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
10277 attr_set.pub_note := tmp_attr_set.note; -- TEXT,
10278 attr_set.priv_note := tmp_attr_set.pnote; -- TEXT,
10279 attr_set.alert_message := tmp_attr_set.amessage; -- TEXT,
10280 attr_set.internal_id := tmp_attr_set.internal_id::BIGINT;
10282 RETURN NEXT attr_set;
10291 $$ LANGUAGE PLPGSQL;
10294 SELECT evergreen.upgrade_deps_block_check('0826', :eg_version);
10296 INSERT INTO permission.perm_list ( id, code, description ) VALUES (
10298 'ADMIN_SERVER_ADDON_FOR_WORKSTATION',
10301 'Allows a user to specify which Server Add-ons get invoked at the current workstation',
10309 SELECT evergreen.upgrade_deps_block_check('0828', :eg_version);
10311 INSERT into config.org_unit_setting_type
10312 (name, grp, label, description, datatype)
10314 'opac.holds.org_unit_not_pickup_lib',
10316 oils_i18n_gettext('opac.holds.org_unit_not_pickup_lib',
10317 'OPAC: Org Unit is not a hold pickup library',
10319 oils_i18n_gettext('opac.holds.org_unit_not_pickup_lib',
10320 'If set, this org unit will not be offered to the patron as an '||
10321 'option for a hold pickup location. This setting has no affect '||
10322 'on searching or hold targeting',
10323 'coust', 'description'),
10329 -- Adds a setting for selecting the number of items per page of a my list.
10332 -- check whether patch can be applied
10333 SELECT evergreen.upgrade_deps_block_check('0829', :eg_version);
10335 INSERT INTO config.usr_setting_type (name,opac_visible,label,description,datatype)
10337 'opac.list_items_per_page',
10340 'opac.list_items_per_page',
10341 'List Items per Page',
10346 'opac.list_items_per_page',
10347 'A number designating the amount of list items displayed per page of a selected list.',
10355 -- Adds a setting for selecting the number of lists per page for my list.
10358 -- check whether patch can be applied
10359 SELECT evergreen.upgrade_deps_block_check('0830', :eg_version);
10361 INSERT INTO config.usr_setting_type (name,opac_visible,label,description,datatype)
10363 'opac.lists_per_page',
10366 'opac.lists_per_page',
10372 'opac.lists_per_page',
10373 'A number designating the amount of lists displayed per page.',
10381 SELECT evergreen.upgrade_deps_block_check('0831', :eg_version);
10383 -- TODO: check for penalty ID collision before master merge; affects
10384 -- config.standing_penalty and actor.calculate_system_penalties
10386 INSERT INTO config.standing_penalty
10387 (id, name, label, block_list, staff_alert)
10390 'PATRON_EXCEEDS_LONGOVERDUE_COUNT',
10393 'Patron Exceeds Max Long-Overdue Threshold',
10397 'CIRC|FULFILL|HOLD|CAPTURE|RENEW',
10402 CREATE OR REPLACE FUNCTION actor.calculate_system_penalties( match_user INT, context_org INT ) RETURNS SETOF actor.usr_standing_penalty AS $func$
10404 user_object actor.usr%ROWTYPE;
10405 new_sp_row actor.usr_standing_penalty%ROWTYPE;
10406 existing_sp_row actor.usr_standing_penalty%ROWTYPE;
10407 collections_fines permission.grp_penalty_threshold%ROWTYPE;
10408 max_fines permission.grp_penalty_threshold%ROWTYPE;
10409 max_overdue permission.grp_penalty_threshold%ROWTYPE;
10410 max_items_out permission.grp_penalty_threshold%ROWTYPE;
10411 max_lost permission.grp_penalty_threshold%ROWTYPE;
10412 max_longoverdue permission.grp_penalty_threshold%ROWTYPE;
10417 items_longoverdue INT;
10418 context_org_list INT[];
10419 current_fines NUMERIC(8,2) := 0.0;
10420 tmp_fines NUMERIC(8,2);
10423 tmp_org actor.org_unit%ROWTYPE;
10424 tmp_penalty config.standing_penalty%ROWTYPE;
10427 SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
10430 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10432 -- Fail if the user has a high fine balance
10434 tmp_grp := user_object.profile;
10436 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 1 AND org_unit = tmp_org.id;
10438 IF max_fines.threshold IS NULL THEN
10439 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10444 IF tmp_grp IS NULL THEN
10449 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10453 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10457 IF max_fines.threshold IS NOT NULL THEN
10461 FROM actor.usr_standing_penalty
10462 WHERE usr = match_user
10463 AND org_unit = max_fines.org_unit
10464 AND (stop_date IS NULL or stop_date > NOW())
10465 AND standing_penalty = 1;
10467 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10469 SELECT SUM(f.balance_owed) INTO current_fines
10470 FROM money.materialized_billable_xact_summary f
10473 FROM booking.reservation r
10474 WHERE r.usr = match_user
10475 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10476 AND xact_finish IS NULL
10479 FROM money.grocery g
10480 WHERE g.usr = match_user
10481 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10482 AND xact_finish IS NULL
10485 FROM action.circulation circ
10486 WHERE circ.usr = match_user
10487 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10488 AND xact_finish IS NULL ) l USING (id);
10490 IF current_fines >= max_fines.threshold THEN
10491 new_sp_row.usr := match_user;
10492 new_sp_row.org_unit := max_fines.org_unit;
10493 new_sp_row.standing_penalty := 1;
10494 RETURN NEXT new_sp_row;
10498 -- Start over for max overdue
10499 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10501 -- Fail if the user has too many overdue items
10503 tmp_grp := user_object.profile;
10506 SELECT * INTO max_overdue FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 2 AND org_unit = tmp_org.id;
10508 IF max_overdue.threshold IS NULL THEN
10509 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10514 IF tmp_grp IS NULL THEN
10519 IF max_overdue.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10523 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10527 IF max_overdue.threshold IS NOT NULL THEN
10531 FROM actor.usr_standing_penalty
10532 WHERE usr = match_user
10533 AND org_unit = max_overdue.org_unit
10534 AND (stop_date IS NULL or stop_date > NOW())
10535 AND standing_penalty = 2;
10537 SELECT INTO items_overdue COUNT(*)
10538 FROM action.circulation circ
10539 JOIN actor.org_unit_full_path( max_overdue.org_unit ) fp ON (circ.circ_lib = fp.id)
10540 WHERE circ.usr = match_user
10541 AND circ.checkin_time IS NULL
10542 AND circ.due_date < NOW()
10543 AND (circ.stop_fines = 'MAXFINES' OR circ.stop_fines IS NULL);
10545 IF items_overdue >= max_overdue.threshold::INT THEN
10546 new_sp_row.usr := match_user;
10547 new_sp_row.org_unit := max_overdue.org_unit;
10548 new_sp_row.standing_penalty := 2;
10549 RETURN NEXT new_sp_row;
10553 -- Start over for max out
10554 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10556 -- Fail if the user has too many checked out items
10558 tmp_grp := user_object.profile;
10560 SELECT * INTO max_items_out FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 3 AND org_unit = tmp_org.id;
10562 IF max_items_out.threshold IS NULL THEN
10563 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10568 IF tmp_grp IS NULL THEN
10573 IF max_items_out.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10577 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10582 -- Fail if the user has too many items checked out
10583 IF max_items_out.threshold IS NOT NULL THEN
10587 FROM actor.usr_standing_penalty
10588 WHERE usr = match_user
10589 AND org_unit = max_items_out.org_unit
10590 AND (stop_date IS NULL or stop_date > NOW())
10591 AND standing_penalty = 3;
10593 SELECT INTO items_out COUNT(*)
10594 FROM action.circulation circ
10595 JOIN actor.org_unit_full_path( max_items_out.org_unit ) fp ON (circ.circ_lib = fp.id)
10596 WHERE circ.usr = match_user
10597 AND circ.checkin_time IS NULL
10598 AND (circ.stop_fines IN (
10599 SELECT 'MAXFINES'::TEXT
10601 SELECT 'LONGOVERDUE'::TEXT
10603 SELECT 'LOST'::TEXT
10607 WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.tally_lost', circ.circ_lib)) ILIKE 'true' THEN 'true'
10612 SELECT 'CLAIMSRETURNED'::TEXT
10613 WHERE 'false' ILIKE
10616 WHEN (SELECT value FROM actor.org_unit_ancestor_setting('circ.do_not_tally_claims_returned', circ.circ_lib)) ILIKE 'true' THEN 'true'
10620 ) OR circ.stop_fines IS NULL)
10621 AND xact_finish IS NULL;
10623 IF items_out >= max_items_out.threshold::INT THEN
10624 new_sp_row.usr := match_user;
10625 new_sp_row.org_unit := max_items_out.org_unit;
10626 new_sp_row.standing_penalty := 3;
10627 RETURN NEXT new_sp_row;
10631 -- Start over for max lost
10632 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10634 -- Fail if the user has too many lost items
10636 tmp_grp := user_object.profile;
10639 SELECT * INTO max_lost FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 5 AND org_unit = tmp_org.id;
10641 IF max_lost.threshold IS NULL THEN
10642 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10647 IF tmp_grp IS NULL THEN
10652 IF max_lost.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10656 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10660 IF max_lost.threshold IS NOT NULL THEN
10664 FROM actor.usr_standing_penalty
10665 WHERE usr = match_user
10666 AND org_unit = max_lost.org_unit
10667 AND (stop_date IS NULL or stop_date > NOW())
10668 AND standing_penalty = 5;
10670 SELECT INTO items_lost COUNT(*)
10671 FROM action.circulation circ
10672 JOIN actor.org_unit_full_path( max_lost.org_unit ) fp ON (circ.circ_lib = fp.id)
10673 WHERE circ.usr = match_user
10674 AND circ.checkin_time IS NULL
10675 AND (circ.stop_fines = 'LOST')
10676 AND xact_finish IS NULL;
10678 IF items_lost >= max_lost.threshold::INT AND 0 < max_lost.threshold::INT THEN
10679 new_sp_row.usr := match_user;
10680 new_sp_row.org_unit := max_lost.org_unit;
10681 new_sp_row.standing_penalty := 5;
10682 RETURN NEXT new_sp_row;
10686 -- Start over for max longoverdue
10687 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10689 -- Fail if the user has too many longoverdue items
10691 tmp_grp := user_object.profile;
10694 SELECT * INTO max_longoverdue
10695 FROM permission.grp_penalty_threshold
10696 WHERE grp = tmp_grp AND
10698 org_unit = tmp_org.id;
10700 IF max_longoverdue.threshold IS NULL THEN
10701 SELECT parent INTO tmp_grp
10702 FROM permission.grp_tree WHERE id = tmp_grp;
10707 IF tmp_grp IS NULL THEN
10712 IF max_longoverdue.threshold IS NOT NULL
10713 OR tmp_org.parent_ou IS NULL THEN
10717 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10721 IF max_longoverdue.threshold IS NOT NULL THEN
10725 FROM actor.usr_standing_penalty
10726 WHERE usr = match_user
10727 AND org_unit = max_longoverdue.org_unit
10728 AND (stop_date IS NULL or stop_date > NOW())
10729 AND standing_penalty = 35;
10731 SELECT INTO items_longoverdue COUNT(*)
10732 FROM action.circulation circ
10733 JOIN actor.org_unit_full_path( max_longoverdue.org_unit ) fp
10734 ON (circ.circ_lib = fp.id)
10735 WHERE circ.usr = match_user
10736 AND circ.checkin_time IS NULL
10737 AND (circ.stop_fines = 'LONGOVERDUE')
10738 AND xact_finish IS NULL;
10740 IF items_longoverdue >= max_longoverdue.threshold::INT
10741 AND 0 < max_longoverdue.threshold::INT THEN
10742 new_sp_row.usr := match_user;
10743 new_sp_row.org_unit := max_longoverdue.org_unit;
10744 new_sp_row.standing_penalty := 35;
10745 RETURN NEXT new_sp_row;
10750 -- Start over for collections warning
10751 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10753 -- Fail if the user has a collections-level fine balance
10755 tmp_grp := user_object.profile;
10757 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 4 AND org_unit = tmp_org.id;
10759 IF max_fines.threshold IS NULL THEN
10760 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10765 IF tmp_grp IS NULL THEN
10770 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10774 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10778 IF max_fines.threshold IS NOT NULL THEN
10782 FROM actor.usr_standing_penalty
10783 WHERE usr = match_user
10784 AND org_unit = max_fines.org_unit
10785 AND (stop_date IS NULL or stop_date > NOW())
10786 AND standing_penalty = 4;
10788 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10790 SELECT SUM(f.balance_owed) INTO current_fines
10791 FROM money.materialized_billable_xact_summary f
10794 FROM booking.reservation r
10795 WHERE r.usr = match_user
10796 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10797 AND r.xact_finish IS NULL
10800 FROM money.grocery g
10801 WHERE g.usr = match_user
10802 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10803 AND g.xact_finish IS NULL
10806 FROM action.circulation circ
10807 WHERE circ.usr = match_user
10808 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10809 AND circ.xact_finish IS NULL ) l USING (id);
10811 IF current_fines >= max_fines.threshold THEN
10812 new_sp_row.usr := match_user;
10813 new_sp_row.org_unit := max_fines.org_unit;
10814 new_sp_row.standing_penalty := 4;
10815 RETURN NEXT new_sp_row;
10819 -- Start over for in collections
10820 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10822 -- Remove the in-collections penalty if the user has paid down enough
10823 -- This penalty is different, because this code is not responsible for creating
10824 -- new in-collections penalties, only for removing them
10826 tmp_grp := user_object.profile;
10828 SELECT * INTO max_fines FROM permission.grp_penalty_threshold WHERE grp = tmp_grp AND penalty = 30 AND org_unit = tmp_org.id;
10830 IF max_fines.threshold IS NULL THEN
10831 SELECT parent INTO tmp_grp FROM permission.grp_tree WHERE id = tmp_grp;
10836 IF tmp_grp IS NULL THEN
10841 IF max_fines.threshold IS NOT NULL OR tmp_org.parent_ou IS NULL THEN
10845 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10849 IF max_fines.threshold IS NOT NULL THEN
10851 SELECT INTO context_org_list ARRAY_ACCUM(id) FROM actor.org_unit_full_path( max_fines.org_unit );
10853 -- first, see if the user had paid down to the threshold
10854 SELECT SUM(f.balance_owed) INTO current_fines
10855 FROM money.materialized_billable_xact_summary f
10858 FROM booking.reservation r
10859 WHERE r.usr = match_user
10860 AND r.pickup_lib IN (SELECT * FROM unnest(context_org_list))
10861 AND r.xact_finish IS NULL
10864 FROM money.grocery g
10865 WHERE g.usr = match_user
10866 AND g.billing_location IN (SELECT * FROM unnest(context_org_list))
10867 AND g.xact_finish IS NULL
10870 FROM action.circulation circ
10871 WHERE circ.usr = match_user
10872 AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
10873 AND circ.xact_finish IS NULL ) l USING (id);
10875 IF current_fines IS NULL OR current_fines <= max_fines.threshold THEN
10876 -- patron has paid down enough
10878 SELECT INTO tmp_penalty * FROM config.standing_penalty WHERE id = 30;
10880 IF tmp_penalty.org_depth IS NOT NULL THEN
10882 -- since this code is not responsible for applying the penalty, it can't
10883 -- guarantee the current context org will match the org at which the penalty
10884 --- was applied. search up the org tree until we hit the configured penalty depth
10885 SELECT INTO tmp_org * FROM actor.org_unit WHERE id = context_org;
10886 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
10888 WHILE tmp_depth >= tmp_penalty.org_depth LOOP
10892 FROM actor.usr_standing_penalty
10893 WHERE usr = match_user
10894 AND org_unit = tmp_org.id
10895 AND (stop_date IS NULL or stop_date > NOW())
10896 AND standing_penalty = 30;
10898 IF tmp_org.parent_ou IS NULL THEN
10902 SELECT * INTO tmp_org FROM actor.org_unit WHERE id = tmp_org.parent_ou;
10903 SELECT INTO tmp_depth depth FROM actor.org_unit_type WHERE id = tmp_org.ou_type;
10908 -- no penalty depth is defined, look for exact matches
10912 FROM actor.usr_standing_penalty
10913 WHERE usr = match_user
10914 AND org_unit = max_fines.org_unit
10915 AND (stop_date IS NULL or stop_date > NOW())
10916 AND standing_penalty = 30;
10925 $func$ LANGUAGE plpgsql;
10929 SELECT evergreen.upgrade_deps_block_check('0832', :eg_version);
10931 ALTER TABLE serial.subscription_note
10932 ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10934 ALTER TABLE serial.distribution_note
10935 ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10937 ALTER TABLE serial.item_note
10938 ADD COLUMN alert BOOL NOT NULL DEFAULT FALSE;
10941 SELECT evergreen.upgrade_deps_block_check('0833', :eg_version);
10943 INSERT INTO config.org_unit_setting_type
10944 (name, grp, datatype, label, description)
10946 'opac.self_register.timeout',
10950 'opac.self_register.timeout',
10951 'Patron Self-Reg. Display Timeout',
10956 'opac.self_register.timeout',
10957 'Number of seconds to wait before reloading the patron self-'||
10958 'registration interface to clear sensitive data',
10965 SELECT evergreen.upgrade_deps_block_check('0834', :eg_version);
10967 INSERT INTO config.org_unit_setting_type
10968 (name, grp, datatype, label, description)
10970 'ui.circ.items_out.longoverdue', 'gui', 'integer',
10972 'ui.circ.items_out.longoverdue',
10973 'Items Out Long-Overdue display setting',
10978 'ui.circ.items_out.longoverdue',
10979 'Value is a numeric code, describing which list the circulation '||
10980 'should appear while checked out and whether the circulation should '||
10981 'continue to appear in the bottom list, when checked in with '||
10982 'oustanding fines. '||
10983 '1 = top list, bottom list. 2 = bottom list, bottom list. ' ||
10984 '5 = top list, do not display. 6 = bottom list, do not display.',
10989 'ui.circ.items_out.lost', 'gui', 'integer',
10991 'ui.circ.items_out.lost',
10992 'Items Out Lost display setting',
10997 'ui.circ.items_out.lost',
10998 'Value is a numeric code, describing which list the circulation '||
10999 'should appear while checked out and whether the circulation should '||
11000 'continue to appear in the bottom list, when checked in with '||
11001 'oustanding fines. '||
11002 '1 = top list, bottom list. 2 = bottom list, bottom list. ' ||
11003 '5 = top list, do not display. 6 = bottom list, do not display.',
11008 'ui.circ.items_out.claimsreturned', 'gui', 'integer',
11010 'ui.circ.items_out.claimsreturned',
11011 'Items Out Claims Returned display setting',
11016 'ui.circ.items_out.claimsreturned',
11017 'Value is a numeric code, describing which list the circulation '||
11018 'should appear while checked out and whether the circulation should '||
11019 'continue to appear in the bottom list, when checked in with '||
11020 'oustanding fines. '||
11021 '1 = top list, bottom list. 2 = bottom list, bottom list. ' ||
11022 '5 = top list, do not display. 6 = bottom list, do not display.',
11029 SELECT evergreen.upgrade_deps_block_check('0835', :eg_version);
11031 INSERT INTO config.org_unit_setting_type
11032 (grp, name, datatype, label, description)
11035 'circ.disable_patron_credit',
11038 'circ.disable_patron_credit',
11039 'Disable Patron Credit',
11044 'circ.disable_patron_credit',
11045 'Do not allow patrons to accrue credit or pay fines/fees with accrued credit',
11052 SELECT evergreen.upgrade_deps_block_check('0836', :eg_version);
11054 CREATE TABLE config.floating_group (
11055 id SERIAL PRIMARY KEY,
11056 name TEXT UNIQUE NOT NULL,
11057 manual BOOL NOT NULL DEFAULT FALSE
11060 CREATE TABLE config.floating_group_member (
11061 id SERIAL PRIMARY KEY,
11062 floating_group INT NOT NULL REFERENCES config.floating_group (id),
11063 org_unit INT NOT NULL REFERENCES actor.org_unit (id),
11064 stop_depth INT NOT NULL DEFAULT 0,
11066 exclude BOOL NOT NULL DEFAULT FALSE
11069 CREATE OR REPLACE FUNCTION evergreen.can_float( copy_floating_group integer, from_ou integer, to_ou integer ) RETURNS BOOL AS $f$
11071 float_member config.floating_group_member%ROWTYPE;
11072 shared_ou_depth INT;
11075 -- Grab the shared OU depth. If this is less than the stop depth later we ignore the entry.
11076 SELECT INTO shared_ou_depth max(depth) FROM actor.org_unit_common_ancestors( from_ou, to_ou ) aou JOIN actor.org_unit_type aout ON aou.ou_type = aout.id;
11077 -- Grab the to ou depth. If this is greater than max depth we ignore the entry.
11078 SELECT INTO to_ou_depth depth FROM actor.org_unit aou JOIN actor.org_unit_type aout ON aou.ou_type = aout.id WHERE aou.id = to_ou;
11079 -- Grab float members that apply. We don't care what we get beyond wanting excluded ones first.
11080 SELECT INTO float_member *
11082 config.floating_group_member cfgm
11083 JOIN actor.org_unit aou ON cfgm.org_unit = aou.id
11084 JOIN actor.org_unit_type aout ON aou.ou_type = aout.id
11086 cfgm.floating_group = copy_floating_group
11087 AND to_ou IN (SELECT id FROM actor.org_unit_descendants(aou.id))
11088 AND cfgm.stop_depth <= shared_ou_depth
11089 AND (cfgm.max_depth IS NULL OR to_ou_depth <= max_depth)
11092 -- If we found something then we want to return the opposite of the exclude flag
11094 RETURN NOT float_member.exclude;
11096 -- Otherwise no floating.
11099 $f$ LANGUAGE PLPGSQL;
11101 INSERT INTO config.floating_group(name) VALUES ('Everywhere');
11102 INSERT INTO config.floating_group_member(floating_group, org_unit) VALUES (1, 1);
11104 -- We need to drop these before we can update asset.copy
11105 DROP VIEW auditor.asset_copy_lifecycle;
11106 DROP VIEW auditor.serial_unit_lifecycle;
11108 -- Update the appropriate auditor tables
11109 ALTER TABLE auditor.asset_copy_history
11110 ALTER COLUMN floating DROP DEFAULT,
11111 ALTER COLUMN floating DROP NOT NULL,
11112 ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11113 ALTER TABLE auditor.serial_unit_history
11114 ALTER COLUMN floating DROP DEFAULT,
11115 ALTER COLUMN floating DROP NOT NULL,
11116 ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11118 -- Update asset.copy itself (does not appear to trigger update triggers!)
11119 ALTER TABLE asset.copy
11120 ALTER COLUMN floating DROP DEFAULT,
11121 ALTER COLUMN floating DROP NOT NULL,
11122 ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11124 ALTER TABLE asset.copy ADD CONSTRAINT asset_copy_floating_fkey FOREIGN KEY (floating) REFERENCES config.floating_group (id) DEFERRABLE INITIALLY DEFERRED;
11126 -- Update asset.copy_template too
11127 ALTER TABLE asset.copy_template
11128 ALTER COLUMN floating TYPE int USING CASE WHEN floating THEN 1 ELSE NULL END;
11129 ALTER TABLE asset.copy_template ADD CONSTRAINT asset_copy_template_floating_fkey FOREIGN KEY (floating) REFERENCES config.floating_group (id) DEFERRABLE INITIALLY DEFERRED;
11131 INSERT INTO permission.perm_list( code, description) VALUES
11132 ('ADMIN_FLOAT_GROUPS', 'Allows administration of floating groups');
11134 -- And lets just update all auditors to re-create those lifecycle views
11135 SELECT auditor.update_auditors();
11137 -- Evergreen DB patch 0837.schema.browse-auth-linking.plus-joiner.sql
11139 -- In this upgrade script we complete inter-subfield joiner support, so that
11140 -- subject components can be separated by " -- ", for instance. That's the
11143 -- We also add the ability to browse by in-use authority main entries and find
11144 -- bibs that use unauthorized versions of the authority's value, by string matching.
11148 -- check whether patch can be applied
11149 SELECT evergreen.upgrade_deps_block_check('0837', :eg_version);
11151 ALTER TABLE config.metabib_field ADD COLUMN joiner TEXT;
11152 UPDATE config.metabib_field SET joiner = ' -- ' WHERE field_class = 'subject' AND name NOT IN ('name', 'complete');
11154 -- To avoid problems with altering a table column after doing an
11156 ALTER TABLE authority.control_set_authority_field DISABLE TRIGGER ALL;
11158 ALTER TABLE authority.control_set_authority_field ADD COLUMN joiner TEXT;
11159 UPDATE authority.control_set_authority_field SET joiner = ' -- ' WHERE tag LIKE ANY (ARRAY['_4_','_5_','_8_']);
11161 ALTER TABLE authority.control_set_authority_field ENABLE TRIGGER ALL;
11163 -- Seed data will be generated from class <-> axis mapping
11164 CREATE TABLE authority.control_set_bib_field_metabib_field_map (
11165 id SERIAL PRIMARY KEY,
11166 bib_field INT NOT NULL REFERENCES authority.control_set_bib_field (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
11167 metabib_field INT NOT NULL REFERENCES config.metabib_field (id) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
11168 CONSTRAINT a_bf_mf_map_once UNIQUE (bib_field, metabib_field)
11171 CREATE VIEW authority.control_set_auth_field_metabib_field_map_main AS
11172 SELECT DISTINCT b.authority_field, m.metabib_field
11173 FROM authority.control_set_bib_field_metabib_field_map m JOIN authority.control_set_bib_field b ON (b.id = m.bib_field);
11174 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_main IS $$metabib fields for main entry auth fields$$;
11176 CREATE VIEW authority.control_set_auth_field_metabib_field_map_refs_only AS
11177 SELECT DISTINCT a.id AS authority_field, m.metabib_field
11178 FROM authority.control_set_authority_field a
11179 JOIN authority.control_set_authority_field ame ON (a.main_entry = ame.id)
11180 JOIN authority.control_set_bib_field b ON (b.authority_field = ame.id)
11181 JOIN authority.control_set_bib_field_metabib_field_map mf ON (mf.bib_field = b.id)
11182 JOIN authority.control_set_auth_field_metabib_field_map_main m ON (ame.id = m.authority_field);
11183 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_refs_only IS $$metabib fields for NON-main entry auth fields$$;
11185 CREATE VIEW authority.control_set_auth_field_metabib_field_map_refs AS
11186 SELECT * FROM authority.control_set_auth_field_metabib_field_map_main
11188 SELECT * FROM authority.control_set_auth_field_metabib_field_map_refs_only;
11189 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_refs IS $$metabib fields for all auth fields$$;
11192 -- blind refs only is probably what we want for lookup in bib/auth browse
11193 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_refs_only AS
11195 FROM authority.control_set_auth_field_metabib_field_map_refs_only r
11196 JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11197 WHERE linking_subfield IS NULL;
11198 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_refs_only IS $$metabib fields for NON-main entry auth fields that can't be linked to other records$$; -- '
11200 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_refs AS
11202 FROM authority.control_set_auth_field_metabib_field_map_refs r
11203 JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11204 WHERE linking_subfield IS NULL;
11205 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_refs IS $$metabib fields for all auth fields that can't be linked to other records$$; -- '
11207 CREATE VIEW authority.control_set_auth_field_metabib_field_map_blind_main AS
11209 FROM authority.control_set_auth_field_metabib_field_map_main r
11210 JOIN authority.control_set_authority_field a ON (r.authority_field = a.id)
11211 WHERE linking_subfield IS NULL;
11212 COMMENT ON VIEW authority.control_set_auth_field_metabib_field_map_blind_main IS $$metabib fields for main entry auth fields that can't be linked to other records$$; -- '
11214 CREATE OR REPLACE FUNCTION authority.normalize_heading( marcxml TEXT, no_thesaurus BOOL ) RETURNS TEXT AS $func$
11216 acsaf authority.control_set_authority_field%ROWTYPE;
11227 auth_id INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
11229 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
11231 IF cset IS NULL THEN
11232 SELECT control_set INTO cset
11233 FROM authority.control_set_authority_field
11234 WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
11238 thes_code := vandelay.marc21_extract_fixed_field(marcxml,'Subj');
11239 IF thes_code IS NULL THEN
11241 ELSIF thes_code = 'z' THEN
11242 thes_code := COALESCE( oils_xpath_string('//*[@tag="040"]/*[@code="f"][1]', marcxml), '' );
11245 heading_text := '';
11246 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset AND main_entry IS NULL LOOP
11247 tag_used := acsaf.tag;
11248 nfi_used := acsaf.nfi;
11251 FOR tag_node IN SELECT unnest(oils_xpath('//*[@tag="'||tag_used||'"]',marcxml)) LOOP
11252 FOR sf_node IN SELECT unnest(oils_xpath('./*[contains("'||acsaf.sf_list||'",@code)]',tag_node)) LOOP
11254 tmp_text := oils_xpath_string('.', sf_node);
11255 sf := oils_xpath_string('./@code', sf_node);
11257 IF first_sf AND tmp_text IS NOT NULL AND nfi_used IS NOT NULL THEN
11259 tmp_text := SUBSTRING(
11264 oils_xpath_string('./@ind'||nfi_used, tag_node),
11279 IF tmp_text IS NOT NULL AND tmp_text <> '' THEN
11280 heading_text := heading_text || E'\u2021' || sf || ' ' || tmp_text;
11284 EXIT WHEN heading_text <> '';
11287 EXIT WHEN heading_text <> '';
11290 IF heading_text <> '' THEN
11291 IF no_thesaurus IS TRUE THEN
11292 heading_text := tag_used || ' ' || public.naco_normalize(heading_text);
11294 heading_text := tag_used || '_' || COALESCE(nfi_used,'-') || '_' || thes_code || ' ' || public.naco_normalize(heading_text);
11297 heading_text := 'NOHEADING_' || thes_code || ' ' || MD5(marcxml);
11300 RETURN heading_text;
11302 $func$ LANGUAGE PLPGSQL IMMUTABLE;
11304 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
11306 res authority.simple_heading%ROWTYPE;
11307 acsaf authority.control_set_authority_field%ROWTYPE;
11318 auth_id INT DEFAULT COALESCE(NULLIF(oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', marcxml), ''), '0')::INT;
11321 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
11323 IF cset IS NULL THEN
11324 SELECT control_set INTO cset
11325 FROM authority.control_set_authority_field
11326 WHERE tag IN ( SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marcxml::XML)::TEXT[]))
11330 res.record := auth_id;
11332 FOR acsaf IN SELECT * FROM authority.control_set_authority_field WHERE control_set = cset LOOP
11334 res.atag := acsaf.id;
11335 tag_used := acsaf.tag;
11336 nfi_used := acsaf.nfi;
11337 joiner_text := COALESCE(acsaf.joiner, ' ');
11339 FOR tmp_xml IN SELECT UNNEST(XPATH('//*[@tag="'||tag_used||'"]', marcxml::XML)) LOOP
11341 heading_text := COALESCE(
11342 oils_xpath_string('./*[contains("'||acsaf.sf_list||'",@code)]', tmp_xml::TEXT, joiner_text),
11346 IF nfi_used IS NOT NULL THEN
11348 sort_text := SUBSTRING(
11353 oils_xpath_string('./@ind'||nfi_used, tmp_xml::TEXT),
11365 sort_text := heading_text;
11368 IF heading_text IS NOT NULL AND heading_text <> '' THEN
11369 res.value := heading_text;
11370 res.sort_value := public.naco_normalize(sort_text);
11371 res.index_vector = to_tsvector('keyword'::regconfig, res.sort_value);
11381 $func$ LANGUAGE PLPGSQL IMMUTABLE;
11383 CREATE TABLE metabib.browse_entry_simple_heading_map (
11384 id BIGSERIAL PRIMARY KEY,
11385 entry BIGINT REFERENCES metabib.browse_entry (id),
11386 simple_heading BIGINT REFERENCES authority.simple_heading (id) ON DELETE CASCADE
11388 CREATE INDEX browse_entry_sh_map_entry_idx ON metabib.browse_entry_simple_heading_map (entry);
11389 CREATE INDEX browse_entry_sh_map_sh_idx ON metabib.browse_entry_simple_heading_map (simple_heading);
11391 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
11393 bib biblio.record_entry%ROWTYPE;
11394 idx config.metabib_field%ROWTYPE;
11395 xfrm config.xml_transform%ROWTYPE;
11397 transformed_xml TEXT;
11399 xml_node_list TEXT[];
11405 joiner TEXT := default_joiner; -- XXX will index defs supply a joiner?
11406 authority_text TEXT;
11407 authority_link BIGINT;
11408 output_row metabib.field_entry_template%ROWTYPE;
11411 -- Start out with no field-use bools set
11412 output_row.browse_field = FALSE;
11413 output_row.facet_field = FALSE;
11414 output_row.search_field = FALSE;
11417 SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
11419 -- Loop over the indexing entries
11420 FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
11422 joiner := COALESCE(idx.joiner, default_joiner);
11424 SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
11426 -- See if we can skip the XSLT ... it's expensive
11427 IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
11428 -- Can't skip the transform
11429 IF xfrm.xslt <> '---' THEN
11430 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
11432 transformed_xml := bib.marc;
11435 prev_xfrm := xfrm.name;
11438 xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11441 FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
11442 CONTINUE WHEN xml_node !~ E'^\\s*<';
11444 -- XXX much of this should be moved into oils_xpath_string...
11445 curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
11446 oils_xpath( '//text()',
11448 REGEXP_REPLACE( -- This escapes all &s not followed by "amp;". Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
11449 REGEXP_REPLACE( -- This escapes embeded <s
11451 $re$(>[^<]+)(<)([^>]+<)$re$,
11467 CONTINUE WHEN curr_text IS NULL OR curr_text = '';
11469 IF raw_text IS NOT NULL THEN
11470 raw_text := raw_text || joiner;
11473 raw_text := COALESCE(raw_text,'') || curr_text;
11475 -- autosuggest/metabib.browse_entry
11476 IF idx.browse_field THEN
11478 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
11479 browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11481 browse_text := curr_text;
11484 IF idx.browse_sort_xpath IS NOT NULL AND
11485 idx.browse_sort_xpath <> '' THEN
11487 sort_value := oils_xpath_string(
11488 idx.browse_sort_xpath, xml_node, joiner,
11489 ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
11492 sort_value := browse_text;
11495 output_row.field_class = idx.field_class;
11496 output_row.field = idx.id;
11497 output_row.source = rid;
11498 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
11499 output_row.sort_value :=
11500 public.naco_normalize(sort_value);
11502 output_row.authority := NULL;
11504 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
11505 authority_text := oils_xpath_string(
11506 idx.authority_xpath, xml_node, joiner,
11508 ARRAY[xfrm.prefix, xfrm.namespace_uri],
11509 ARRAY['xlink','http://www.w3.org/1999/xlink']
11513 IF authority_text ~ '^\d+$' THEN
11514 authority_link := authority_text::BIGINT;
11515 PERFORM * FROM authority.record_entry WHERE id = authority_link;
11517 output_row.authority := authority_link;
11523 output_row.browse_field = TRUE;
11524 RETURN NEXT output_row;
11525 output_row.browse_field = FALSE;
11526 output_row.sort_value := NULL;
11529 -- insert raw node text for faceting
11530 IF idx.facet_field THEN
11532 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
11533 facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
11535 facet_text := curr_text;
11538 output_row.field_class = idx.field_class;
11539 output_row.field = -1 * idx.id;
11540 output_row.source = rid;
11541 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
11543 output_row.facet_field = TRUE;
11544 RETURN NEXT output_row;
11545 output_row.facet_field = FALSE;
11550 CONTINUE WHEN raw_text IS NULL OR raw_text = '';
11552 -- insert combined node text for searching
11553 IF idx.search_field THEN
11554 output_row.field_class = idx.field_class;
11555 output_row.field = idx.id;
11556 output_row.source = rid;
11557 output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
11559 output_row.search_field = TRUE;
11560 RETURN NEXT output_row;
11561 output_row.search_field = FALSE;
11568 $func$ LANGUAGE PLPGSQL;
11571 FUNCTION metabib.autosuggest_prepare_tsquery(orig TEXT) RETURNS TEXT[] AS
11574 orig_ended_in_space BOOLEAN;
11579 orig_ended_in_space := orig ~ E'\\s$';
11581 orig := ARRAY_TO_STRING(
11582 evergreen.regexp_split_to_array(orig, E'\\W+'), ' '
11585 normalized := public.naco_normalize(orig); -- also trim()s
11586 plain := trim(orig);
11588 IF NOT orig_ended_in_space THEN
11589 plain := plain || ':*';
11590 normalized := normalized || ':*';
11593 plain := ARRAY_TO_STRING(
11594 evergreen.regexp_split_to_array(plain, E'\\s+'), ' & '
11596 normalized := ARRAY_TO_STRING(
11597 evergreen.regexp_split_to_array(normalized, E'\\s+'), ' & '
11600 RETURN ARRAY[normalized, plain];
11602 $$ LANGUAGE PLPGSQL;
11604 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE sees TEXT;
11605 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE asources INT;
11606 ALTER TYPE metabib.flat_browse_entry_appearance ADD ATTRIBUTE aaccurate TEXT;
11608 CREATE OR REPLACE FUNCTION metabib.browse_bib_pivot(
11611 ) RETURNS BIGINT AS $p$
11613 FROM metabib.browse_entry mbe
11614 JOIN metabib.browse_entry_def_map mbedm ON (
11615 mbedm.entry = mbe.id
11616 AND mbedm.def = ANY($1)
11618 WHERE mbe.sort_value >= public.naco_normalize($2)
11619 ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11622 CREATE OR REPLACE FUNCTION metabib.browse_authority_pivot(
11625 ) RETURNS BIGINT AS $p$
11627 FROM metabib.browse_entry mbe
11628 JOIN metabib.browse_entry_simple_heading_map mbeshm ON ( mbeshm.entry = mbe.id )
11629 JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11630 JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11631 ash.atag = map.authority_field
11632 AND map.metabib_field = ANY($1)
11634 WHERE mbe.sort_value >= public.naco_normalize($2)
11635 ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11638 CREATE OR REPLACE FUNCTION metabib.browse_authority_refs_pivot(
11641 ) RETURNS BIGINT AS $p$
11643 FROM metabib.browse_entry mbe
11644 JOIN metabib.browse_entry_simple_heading_map mbeshm ON ( mbeshm.entry = mbe.id )
11645 JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11646 JOIN authority.control_set_auth_field_metabib_field_map_refs_only map ON (
11647 ash.atag = map.authority_field
11648 AND map.metabib_field = ANY($1)
11650 WHERE mbe.sort_value >= public.naco_normalize($2)
11651 ORDER BY mbe.sort_value, mbe.value LIMIT 1;
11654 -- The drop is necessary because the language change from PLPGSQL to SQL
11655 -- carries with it name changes to the parameters
11656 DROP FUNCTION metabib.browse_pivot(INT[], TEXT);
11657 CREATE FUNCTION metabib.browse_pivot(
11660 ) RETURNS BIGINT AS $p$
11661 SELECT id FROM metabib.browse_entry
11663 metabib.browse_bib_pivot($1, $2),
11664 metabib.browse_authority_refs_pivot($1,$2) -- only look in 4xx, 5xx, 7xx of authority
11666 ORDER BY sort_value, value LIMIT 1;
11669 CREATE OR REPLACE FUNCTION metabib.staged_browse(
11673 context_locations INT[],
11675 browse_superpage_size INT,
11676 count_up_from_zero BOOL, -- if false, count down from -1
11679 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
11687 result_row metabib.flat_browse_entry_appearance%ROWTYPE;
11688 results_skipped INT := 0;
11689 row_counter INT := 0;
11694 all_records BIGINT[];
11695 all_brecords BIGINT[];
11696 all_arecords BIGINT[];
11697 superpage_of_records BIGINT[];
11698 superpage_size INT;
11700 IF count_up_from_zero THEN
11706 OPEN curs FOR EXECUTE query;
11709 FETCH curs INTO rec;
11711 IF result_row.pivot_point IS NOT NULL THEN
11712 RETURN NEXT result_row;
11718 -- Gather aggregate data based on the MBE row we're looking at now, authority axis
11719 SELECT INTO all_arecords, result_row.sees, afields
11720 ARRAY_AGG(DISTINCT abl.bib), -- bibs to check for visibility
11721 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT aal.source), $$,$$), -- authority record ids
11722 ARRAY_AGG(DISTINCT map.metabib_field) -- authority-tag-linked CMF rows
11724 FROM metabib.browse_entry_simple_heading_map mbeshm
11725 JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11726 JOIN authority.authority_linking aal ON ( ash.record = aal.source )
11727 JOIN authority.bib_linking abl ON ( aal.target = abl.authority )
11728 JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11729 ash.atag = map.authority_field
11730 AND map.metabib_field = ANY(fields)
11732 WHERE mbeshm.entry = rec.id;
11735 -- Gather aggregate data based on the MBE row we're looking at now, bib axis
11736 SELECT INTO all_brecords, result_row.authorities, bfields
11737 ARRAY_AGG(DISTINCT source),
11738 ARRAY_TO_STRING(ARRAY_AGG(DISTINCT authority), $$,$$),
11739 ARRAY_AGG(DISTINCT def)
11740 FROM metabib.browse_entry_def_map
11741 WHERE entry = rec.id
11742 AND def = ANY(fields);
11744 SELECT INTO result_row.fields ARRAY_TO_STRING(ARRAY_AGG(DISTINCT x), $$,$$) FROM UNNEST(afields || bfields) x;
11746 result_row.sources := 0;
11747 result_row.asources := 0;
11749 -- Bib-linked vis checking
11750 IF ARRAY_UPPER(all_brecords,1) IS NOT NULL THEN
11752 full_end := ARRAY_LENGTH(all_brecords, 1);
11753 superpage_size := COALESCE(browse_superpage_size, full_end);
11755 slice_end := superpage_size;
11757 WHILE result_row.sources = 0 AND slice_start <= full_end LOOP
11758 superpage_of_records := all_brecords[slice_start:slice_end];
11760 'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
11761 '1::INT AS rel FROM (SELECT UNNEST(' ||
11762 quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
11764 -- We use search.query_parser_fts() for visibility testing.
11765 -- We're calling it once per browse-superpage worth of records
11766 -- out of the set of records related to a given mbe, until we've
11767 -- either exhausted that set of records or found at least 1
11770 SELECT INTO result_row.sources visible
11771 FROM search.query_parser_fts(
11772 context_org, NULL, qpfts_query, NULL,
11773 context_locations, 0, NULL, NULL, FALSE, staff, FALSE
11775 WHERE qpfts.rel IS NULL;
11777 slice_start := slice_start + superpage_size;
11778 slice_end := slice_end + superpage_size;
11781 -- Accurate? Well, probably.
11782 result_row.accurate := browse_superpage_size IS NULL OR
11783 browse_superpage_size >= full_end;
11787 -- Authority-linked vis checking
11788 IF ARRAY_UPPER(all_arecords,1) IS NOT NULL THEN
11790 full_end := ARRAY_LENGTH(all_arecords, 1);
11791 superpage_size := COALESCE(browse_superpage_size, full_end);
11793 slice_end := superpage_size;
11795 WHILE result_row.asources = 0 AND slice_start <= full_end LOOP
11796 superpage_of_records := all_arecords[slice_start:slice_end];
11798 'SELECT NULL::BIGINT AS id, ARRAY[r] AS records, ' ||
11799 '1::INT AS rel FROM (SELECT UNNEST(' ||
11800 quote_literal(superpage_of_records) || '::BIGINT[]) AS r) rr';
11802 -- We use search.query_parser_fts() for visibility testing.
11803 -- We're calling it once per browse-superpage worth of records
11804 -- out of the set of records related to a given mbe, via
11805 -- authority until we've either exhausted that set of records
11806 -- or found at least 1 visible record.
11808 SELECT INTO result_row.asources visible
11809 FROM search.query_parser_fts(
11810 context_org, NULL, qpfts_query, NULL,
11811 context_locations, 0, NULL, NULL, FALSE, staff, FALSE
11813 WHERE qpfts.rel IS NULL;
11815 slice_start := slice_start + superpage_size;
11816 slice_end := slice_end + superpage_size;
11820 -- Accurate? Well, probably.
11821 result_row.aaccurate := browse_superpage_size IS NULL OR
11822 browse_superpage_size >= full_end;
11826 IF result_row.sources > 0 OR result_row.asources > 0 THEN
11828 -- The function that calls this function needs row_number in order
11829 -- to correctly order results from two different runs of this
11831 result_row.row_number := row_number;
11833 -- Now, if row_counter is still less than limit, return a row. If
11834 -- not, but it is less than next_pivot_pos, continue on without
11835 -- returning actual result rows until we find
11836 -- that next pivot, and return it.
11838 IF row_counter < result_limit THEN
11839 result_row.browse_entry := rec.id;
11840 result_row.value := rec.value;
11842 RETURN NEXT result_row;
11844 result_row.browse_entry := NULL;
11845 result_row.authorities := NULL;
11846 result_row.fields := NULL;
11847 result_row.value := NULL;
11848 result_row.sources := NULL;
11849 result_row.sees := NULL;
11850 result_row.accurate := NULL;
11851 result_row.aaccurate := NULL;
11852 result_row.pivot_point := rec.id;
11854 IF row_counter >= next_pivot_pos THEN
11855 RETURN NEXT result_row;
11860 IF count_up_from_zero THEN
11861 row_number := row_number + 1;
11863 row_number := row_number - 1;
11866 -- row_counter is different from row_number.
11867 -- It simply counts up from zero so that we know when
11868 -- we've reached our limit.
11869 row_counter := row_counter + 1;
11873 $p$ LANGUAGE PLPGSQL;
11875 CREATE OR REPLACE FUNCTION metabib.browse(
11876 search_field INT[],
11878 context_org INT DEFAULT NULL,
11879 context_loc_group INT DEFAULT NULL,
11880 staff BOOL DEFAULT FALSE,
11881 pivot_id BIGINT DEFAULT NULL,
11882 result_limit INT DEFAULT 10
11883 ) RETURNS SETOF metabib.flat_browse_entry_appearance AS $p$
11887 forward_query TEXT;
11888 pivot_sort_value TEXT;
11889 pivot_sort_fallback TEXT;
11890 context_locations INT[];
11891 browse_superpage_size INT;
11892 results_skipped INT := 0;
11896 forward_to_pivot INT;
11898 -- First, find the pivot if we were given a browse term but not a pivot.
11899 IF pivot_id IS NULL THEN
11900 pivot_id := metabib.browse_pivot(search_field, browse_term);
11903 SELECT INTO pivot_sort_value, pivot_sort_fallback
11904 sort_value, value FROM metabib.browse_entry WHERE id = pivot_id;
11906 -- Bail if we couldn't find a pivot.
11907 IF pivot_sort_value IS NULL THEN
11911 -- Transform the context_loc_group argument (if any) (logc at the
11912 -- TPAC layer) into a form we'll be able to use.
11913 IF context_loc_group IS NOT NULL THEN
11914 SELECT INTO context_locations ARRAY_AGG(location)
11915 FROM asset.copy_location_group_map
11916 WHERE lgroup = context_loc_group;
11919 -- Get the configured size of browse superpages.
11920 SELECT INTO browse_superpage_size value -- NULL ok
11921 FROM config.global_flag
11922 WHERE enabled AND name = 'opac.browse.holdings_visibility_test_limit';
11924 -- First we're going to search backward from the pivot, then we're going
11925 -- to search forward. In each direction, we need two limits. At the
11926 -- lesser of the two limits, we delineate the edge of the result set
11927 -- we're going to return. At the greater of the two limits, we find the
11928 -- pivot value that would represent an offset from the current pivot
11929 -- at a distance of one "page" in either direction, where a "page" is a
11930 -- result set of the size specified in the "result_limit" argument.
11932 -- The two limits in each direction make four derived values in total,
11933 -- and we calculate them now.
11934 back_limit := CEIL(result_limit::FLOAT / 2);
11935 back_to_pivot := result_limit;
11936 forward_limit := result_limit / 2;
11937 forward_to_pivot := result_limit - 1;
11939 -- This is the meat of the SQL query that finds browse entries. We'll
11940 -- pass this to a function which uses it with a cursor, so that individual
11941 -- rows may be fetched in a loop until some condition is satisfied, without
11942 -- waiting for a result set of fixed size to be collected all at once.
11947 FROM metabib.browse_entry mbe
11949 EXISTS ( -- are there any bibs using this mbe via the requested fields?
11951 FROM metabib.browse_entry_def_map mbedm
11952 WHERE mbedm.entry = mbe.id AND mbedm.def = ANY(' || quote_literal(search_field) || ')
11954 ) OR EXISTS ( -- are there any authorities using this mbe via the requested fields?
11956 FROM metabib.browse_entry_simple_heading_map mbeshm
11957 JOIN authority.simple_heading ash ON ( mbeshm.simple_heading = ash.id )
11958 JOIN authority.control_set_auth_field_metabib_field_map_refs map ON (
11959 ash.atag = map.authority_field
11960 AND map.metabib_field = ANY(' || quote_literal(search_field) || ')
11962 WHERE mbeshm.entry = mbe.id
11966 -- This is the variant of the query for browsing backward.
11967 back_query := core_query ||
11968 ' mbe.sort_value <= ' || quote_literal(pivot_sort_value) ||
11969 ' ORDER BY mbe.sort_value DESC, mbe.value DESC ';
11971 -- This variant browses forward.
11972 forward_query := core_query ||
11973 ' mbe.sort_value > ' || quote_literal(pivot_sort_value) ||
11974 ' ORDER BY mbe.sort_value, mbe.value ';
11976 -- We now call the function which applies a cursor to the provided
11977 -- queries, stopping at the appropriate limits and also giving us
11978 -- the next page's pivot.
11980 SELECT * FROM metabib.staged_browse(
11981 back_query, search_field, context_org, context_locations,
11982 staff, browse_superpage_size, TRUE, back_limit, back_to_pivot
11984 SELECT * FROM metabib.staged_browse(
11985 forward_query, search_field, context_org, context_locations,
11986 staff, browse_superpage_size, FALSE, forward_limit, forward_to_pivot
11987 ) ORDER BY row_number DESC;
11990 $p$ LANGUAGE PLPGSQL;
11992 -- No 4XX inter-authority linking
11993 UPDATE authority.control_set_authority_field SET linking_subfield = NULL;
11994 UPDATE authority.control_set_authority_field SET linking_subfield = '0' WHERE tag LIKE ANY (ARRAY['5%','7%']);
11996 -- Map between authority controlled bib fields and stock indexing metabib fields
11997 INSERT INTO authority.control_set_bib_field_metabib_field_map (bib_field, metabib_field)
11998 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
11999 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12000 WHERE a.tag = '100' AND m.name = 'personal'
12004 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12005 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12006 WHERE a.tag = '110' AND m.name = 'corporate'
12010 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12011 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12012 WHERE a.tag = '111' AND m.name = 'conference'
12016 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12017 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12018 WHERE a.tag = '130' AND m.name = 'uniform'
12022 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12023 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12024 WHERE a.tag = '148' AND m.name = 'temporal'
12028 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12029 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12030 WHERE a.tag = '150' AND m.name = 'topic'
12034 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12035 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12036 WHERE a.tag = '151' AND m.name = 'geographic'
12040 SELECT DISTINCT b.id AS bib_field, m.id AS metabib_field
12041 FROM authority.control_set_bib_field b JOIN authority.control_set_authority_field a ON (b.authority_field = a.id), config.metabib_field m
12042 WHERE a.tag = '155' AND m.name = 'genre' -- Just in case...
12045 CREATE OR REPLACE FUNCTION authority.indexing_ingest_or_delete () RETURNS TRIGGER AS $func$
12047 ashs authority.simple_heading%ROWTYPE;
12048 mbe_row metabib.browse_entry%ROWTYPE;
12053 IF NEW.deleted IS TRUE THEN -- If this authority is deleted
12054 DELETE FROM authority.bib_linking WHERE authority = NEW.id; -- Avoid updating fields in bibs that are no longer visible
12055 DELETE FROM authority.full_rec WHERE record = NEW.id; -- Avoid validating fields against deleted authority records
12056 DELETE FROM authority.simple_heading WHERE record = NEW.id;
12057 -- Should remove matching $0 from controlled fields at the same time?
12059 -- XXX What do we about the actual linking subfields present in
12060 -- authority records that target this one when this happens?
12061 DELETE FROM authority.authority_linking
12062 WHERE source = NEW.id OR target = NEW.id;
12064 RETURN NEW; -- and we're done
12067 IF TG_OP = 'UPDATE' THEN -- re-ingest?
12068 PERFORM * FROM config.internal_flag WHERE name = 'ingest.reingest.force_on_same_marc' AND enabled;
12070 IF NOT FOUND AND OLD.marc = NEW.marc THEN -- don't do anything if the MARC didn't change
12074 -- Propagate these updates to any linked bib records
12075 PERFORM authority.propagate_changes(NEW.id) FROM authority.record_entry WHERE id = NEW.id;
12077 DELETE FROM authority.simple_heading WHERE record = NEW.id;
12078 DELETE FROM authority.authority_linking WHERE source = NEW.id;
12081 INSERT INTO authority.authority_linking (source, target, field)
12082 SELECT source, target, field FROM authority.calculate_authority_linking(
12083 NEW.id, NEW.control_set, NEW.marc::XML
12086 FOR ashs IN SELECT * FROM authority.simple_heading_set(NEW.marc) LOOP
12088 INSERT INTO authority.simple_heading (record,atag,value,sort_value)
12089 VALUES (ashs.record, ashs.atag, ashs.value, ashs.sort_value);
12090 ash_id := CURRVAL('authority.simple_heading_id_seq'::REGCLASS);
12092 SELECT INTO mbe_row * FROM metabib.browse_entry
12093 WHERE value = ashs.value AND sort_value = ashs.sort_value;
12096 mbe_id := mbe_row.id;
12098 INSERT INTO metabib.browse_entry
12099 ( value, sort_value ) VALUES
12100 ( ashs.value, ashs.sort_value );
12102 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
12105 INSERT INTO metabib.browse_entry_simple_heading_map (entry,simple_heading) VALUES (mbe_id,ash_id);
12109 -- Flatten and insert the afr data
12110 PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;
12112 PERFORM authority.reingest_authority_full_rec(NEW.id);
12113 PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_rec_descriptor' AND enabled;
12115 PERFORM authority.reingest_authority_rec_descriptor(NEW.id);
12121 $func$ LANGUAGE PLPGSQL;
12125 -- check whether patch can be applied
12126 SELECT evergreen.upgrade_deps_block_check('0838', :eg_version);
12128 DELETE FROM config.metabib_field_index_norm_map
12129 WHERE field = 25 AND norm IN (
12131 FROM config.index_normalizer
12132 WHERE func IN ('search_normalize','split_date_range')
12136 -- check whether patch can be applied
12137 SELECT evergreen.upgrade_deps_block_check('0839', :eg_version);
12139 UPDATE config.metabib_field
12141 xpath = $$//mods32:mods/mods32:titleInfo[mods32:title and starts-with(@type,'alternative')]$$,
12142 browse_sort_xpath = $$*[local-name() != "nonSort"]$$,
12143 browse_xpath = NULL
12145 field_class = 'title' AND name = 'alternative' ;
12148 SELECT evergreen.upgrade_deps_block_check('0840', :eg_version);
12150 INSERT INTO config.usr_setting_type (name,grp,opac_visible,label,description,datatype) VALUES (
12151 'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12155 'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12156 'Circulation Policy Configuration',
12161 'ui.grid_columns.conify.config.circ_matrix_matchpoint',
12162 'Circulation Policy Configuration Column Settings',
12170 -- check whether patch can be applied
12171 SELECT evergreen.upgrade_deps_block_check('0844', :eg_version);
12173 -- 953.data.MODS32-xsl.sql
12174 UPDATE config.xml_transform SET xslt=$$<?xml version="1.0" encoding="UTF-8"?>
12175 <xsl:stylesheet xmlns="http://www.loc.gov/mods/v3" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xlink marc" version="1.0">
12176 <xsl:output encoding="UTF-8" indent="yes" method="xml"/>
12178 Revision 1.14 - Fixed template isValid and fields 010, 020, 022, 024, 028, and 037 to output additional identifier elements
12179 with corresponding @type and @invalid eq 'yes' when subfields z or y (in the case of 022) exist in the MARCXML ::: 2007/01/04 17:35:20 cred
12181 Revision 1.13 - Changed order of output under cartographics to reflect schema 2006/11/28 tmee
12183 Revision 1.12 - Updated to reflect MODS 3.2 Mapping 2006/10/11 tmee
12185 Revision 1.11 - The attribute objectPart moved from <languageTerm> to <language>
12188 Revision 1.10 MODS 3.1 revisions to language and classification elements
12189 (plus ability to find marc:collection embedded in wrapper elements such as SRU zs: wrappers)
12192 Revision 1.9 subfield $y was added to field 242 2004/09/02 10:57 jrad
12194 Revision 1.8 Subject chopPunctuation expanded and attribute fixes 2004/08/12 jrad
12196 Revision 1.7 2004/03/25 08:29 jrad
12198 Revision 1.6 various validation fixes 2004/02/20 ntra
12200 Revision 1.5 2003/10/02 16:18:58 ntra
12201 MODS2 to MODS3 updates, language unstacking and
12202 de-duping, chopPunctuation expanded
12204 Revision 1.3 2003/04/03 00:07:19 ntra
12205 Revision 1.3 Additional Changes not related to MODS Version 2.0 by ntra
12207 Revision 1.2 2003/03/24 19:37:42 ckeith
12211 <xsl:template match="/">
12213 <xsl:when test="//marc:collection">
12214 <modsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
12215 <xsl:for-each select="//marc:collection/marc:record">
12216 <mods version="3.2">
12217 <xsl:call-template name="marcRecord"/>
12223 <mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
12224 <xsl:for-each select="//marc:record">
12225 <xsl:call-template name="marcRecord"/>
12231 <xsl:template name="marcRecord">
12232 <xsl:variable name="leader" select="marc:leader"/>
12233 <xsl:variable name="leader6" select="substring($leader,7,1)"/>
12234 <xsl:variable name="leader7" select="substring($leader,8,1)"/>
12235 <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
12236 <xsl:variable name="typeOf008">
12238 <xsl:when test="$leader6='a'">
12240 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">BK</xsl:when>
12241 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">SE</xsl:when>
12244 <xsl:when test="$leader6='t'">BK</xsl:when>
12245 <xsl:when test="$leader6='p'">MM</xsl:when>
12246 <xsl:when test="$leader6='m'">CF</xsl:when>
12247 <xsl:when test="$leader6='e' or $leader6='f'">MP</xsl:when>
12248 <xsl:when test="$leader6='g' or $leader6='k' or $leader6='o' or $leader6='r'">VM</xsl:when>
12249 <xsl:when test="$leader6='c' or $leader6='d' or $leader6='i' or $leader6='j'">MU</xsl:when>
12252 <xsl:for-each select="marc:datafield[@tag='245']">
12254 <xsl:variable name="title">
12256 <xsl:when test="marc:subfield[@code='b']">
12257 <xsl:call-template name="specialSubfieldSelect">
12258 <xsl:with-param name="axis">b</xsl:with-param>
12259 <xsl:with-param name="beforeCodes">afgk</xsl:with-param>
12260 </xsl:call-template>
12263 <xsl:call-template name="subfieldSelect">
12264 <xsl:with-param name="codes">abfgk</xsl:with-param>
12265 </xsl:call-template>
12269 <xsl:variable name="titleChop">
12270 <xsl:call-template name="chopPunctuation">
12271 <xsl:with-param name="chopString">
12272 <xsl:value-of select="$title"/>
12274 </xsl:call-template>
12277 <xsl:when test="@ind2>0">
12279 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
12282 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
12287 <xsl:value-of select="$titleChop"/>
12291 <xsl:if test="marc:subfield[@code='b']">
12293 <xsl:call-template name="chopPunctuation">
12294 <xsl:with-param name="chopString">
12295 <xsl:call-template name="specialSubfieldSelect">
12296 <xsl:with-param name="axis">b</xsl:with-param>
12297 <xsl:with-param name="anyCodes">b</xsl:with-param>
12298 <xsl:with-param name="afterCodes">afgk</xsl:with-param>
12299 </xsl:call-template>
12301 </xsl:call-template>
12304 <xsl:call-template name="part"></xsl:call-template>
12306 <!-- A form of title that ignores non-filing characters; useful
12307 for not converting "L'Oreal" into "L' Oreal" at index time -->
12310 <xsl:call-template name="chopPunctuation">
12311 <xsl:with-param name="chopString">
12312 <xsl:call-template name="subfieldSelect">
12313 <xsl:with-param name="codes">abfgk</xsl:with-param>
12314 </xsl:call-template>
12316 </xsl:call-template>
12318 <xsl:call-template name="part"></xsl:call-template>
12320 <!-- hybrid of titleInfo and titleNonfiling which will give us a preformatted string (for punctuation)
12321 but also keep the nonSort stuff in a separate field (for sorting) -->
12323 <xsl:variable name="titleBrowseChop">
12324 <xsl:call-template name="chopPunctuation">
12325 <xsl:with-param name="chopString">
12326 <xsl:call-template name="subfieldSelect">
12327 <xsl:with-param name="codes">abfgk</xsl:with-param>
12328 </xsl:call-template>
12330 </xsl:call-template>
12333 <xsl:when test="@ind2>0">
12335 <xsl:value-of select="substring($titleBrowseChop,1,@ind2)"/>
12338 <xsl:value-of select="substring($titleBrowseChop,@ind2+1)"/>
12343 <xsl:value-of select="$titleBrowseChop"/>
12347 <xsl:call-template name="part"></xsl:call-template>
12350 <xsl:for-each select="marc:datafield[@tag='210']">
12351 <titleInfo type="abbreviated">
12353 <xsl:call-template name="chopPunctuation">
12354 <xsl:with-param name="chopString">
12355 <xsl:call-template name="subfieldSelect">
12356 <xsl:with-param name="codes">a</xsl:with-param>
12357 </xsl:call-template>
12359 </xsl:call-template>
12361 <xsl:call-template name="subtitle"/>
12364 <xsl:for-each select="marc:datafield[@tag='242']">
12365 <xsl:variable name="titleChop">
12366 <xsl:call-template name="chopPunctuation">
12367 <xsl:with-param name="chopString">
12368 <xsl:call-template name="subfieldSelect">
12369 <!-- 1/04 removed $h, b -->
12370 <xsl:with-param name="codes">a</xsl:with-param>
12371 </xsl:call-template>
12373 </xsl:call-template>
12375 <titleInfo type="translated">
12376 <!--09/01/04 Added subfield $y-->
12377 <xsl:for-each select="marc:subfield[@code='y']">
12378 <xsl:attribute name="lang">
12379 <xsl:value-of select="text()"/>
12383 <xsl:value-of select="$titleChop" />
12386 <xsl:call-template name="subtitle"/>
12387 <xsl:call-template name="part"/>
12389 <titleInfo type="translated-nfi">
12390 <xsl:for-each select="marc:subfield[@code='y']">
12391 <xsl:attribute name="lang">
12392 <xsl:value-of select="text()"/>
12396 <xsl:when test="@ind2>0">
12398 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
12401 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
12406 <xsl:value-of select="$titleChop" />
12410 <xsl:call-template name="subtitle"/>
12411 <xsl:call-template name="part"/>
12414 <xsl:for-each select="marc:datafield[@tag='246']">
12415 <titleInfo type="alternative">
12416 <xsl:for-each select="marc:subfield[@code='i']">
12417 <xsl:attribute name="displayLabel">
12418 <xsl:value-of select="text()"/>
12422 <xsl:call-template name="chopPunctuation">
12423 <xsl:with-param name="chopString">
12424 <xsl:call-template name="subfieldSelect">
12425 <!-- 1/04 removed $h, $b -->
12426 <xsl:with-param name="codes">af</xsl:with-param>
12427 </xsl:call-template>
12429 </xsl:call-template>
12431 <xsl:call-template name="subtitle"/>
12432 <xsl:call-template name="part"/>
12435 <xsl:for-each select="marc:datafield[@tag='130']|marc:datafield[@tag='240']|marc:datafield[@tag='730'][@ind2!='2']">
12436 <xsl:variable name="nfi">
12438 <xsl:when test="@tag='240'">
12439 <xsl:value-of select="@ind2"/>
12442 <xsl:value-of select="@ind1"/>
12446 <xsl:variable name="titleChop">
12447 <xsl:call-template name="uri" />
12448 <xsl:variable name="str">
12449 <xsl:for-each select="marc:subfield">
12450 <xsl:if test="(contains('adfklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))">
12451 <xsl:value-of select="text()"/>
12452 <xsl:text> </xsl:text>
12456 <xsl:call-template name="chopPunctuation">
12457 <xsl:with-param name="chopString">
12458 <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
12460 </xsl:call-template>
12462 <titleInfo type="uniform">
12464 <xsl:value-of select="$titleChop"/>
12466 <xsl:call-template name="part"/>
12468 <titleInfo type="uniform-nfi">
12470 <xsl:when test="$nfi>0">
12472 <xsl:value-of select="substring($titleChop,1,$nfi)"/>
12475 <xsl:value-of select="substring($titleChop,$nfi+1)"/>
12480 <xsl:value-of select="$titleChop"/>
12484 <xsl:call-template name="part"/>
12487 <xsl:for-each select="marc:datafield[@tag='740'][@ind2!='2']">
12488 <xsl:variable name="titleChop">
12489 <xsl:call-template name="chopPunctuation">
12490 <xsl:with-param name="chopString">
12491 <xsl:call-template name="subfieldSelect">
12492 <xsl:with-param name="codes">ah</xsl:with-param>
12493 </xsl:call-template>
12495 </xsl:call-template>
12497 <titleInfo type="alternative">
12499 <xsl:value-of select="$titleChop" />
12501 <xsl:call-template name="part"/>
12503 <titleInfo type="alternative-nfi">
12505 <xsl:when test="@ind1>0">
12507 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
12510 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
12515 <xsl:value-of select="$titleChop" />
12519 <xsl:call-template name="part"/>
12522 <xsl:for-each select="marc:datafield[@tag='100']">
12523 <name type="personal">
12524 <xsl:call-template name="uri" />
12525 <xsl:call-template name="nameABCDQ"/>
12526 <xsl:call-template name="affiliation"/>
12528 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12530 <xsl:call-template name="role"/>
12533 <xsl:for-each select="marc:datafield[@tag='110']">
12534 <name type="corporate">
12535 <xsl:call-template name="uri" />
12536 <xsl:call-template name="nameABCDN"/>
12538 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12540 <xsl:call-template name="role"/>
12543 <xsl:for-each select="marc:datafield[@tag='111']">
12544 <name type="conference">
12545 <xsl:call-template name="uri" />
12546 <xsl:call-template name="nameACDEQ"/>
12548 <roleTerm authority="marcrelator" type="text">creator</roleTerm>
12550 <xsl:call-template name="role"/>
12553 <xsl:for-each select="marc:datafield[@tag='700'][not(marc:subfield[@code='t'])]">
12554 <name type="personal">
12555 <xsl:call-template name="uri" />
12556 <xsl:call-template name="nameABCDQ"/>
12557 <xsl:call-template name="affiliation"/>
12558 <xsl:call-template name="role"/>
12561 <xsl:for-each select="marc:datafield[@tag='710'][not(marc:subfield[@code='t'])]">
12562 <name type="corporate">
12563 <xsl:call-template name="uri" />
12564 <xsl:call-template name="nameABCDN"/>
12565 <xsl:call-template name="role"/>
12568 <xsl:for-each select="marc:datafield[@tag='711'][not(marc:subfield[@code='t'])]">
12569 <name type="conference">
12570 <xsl:call-template name="uri" />
12571 <xsl:call-template name="nameACDEQ"/>
12572 <xsl:call-template name="role"/>
12575 <xsl:for-each select="marc:datafield[@tag='720'][not(marc:subfield[@code='t'])]">
12577 <xsl:if test="@ind1=1">
12578 <xsl:attribute name="type">
12579 <xsl:text>personal</xsl:text>
12583 <xsl:value-of select="marc:subfield[@code='a']"/>
12585 <xsl:call-template name="role"/>
12589 <xsl:if test="$leader7='c'">
12590 <xsl:attribute name="collection">yes</xsl:attribute>
12592 <xsl:if test="$leader6='d' or $leader6='f' or $leader6='p' or $leader6='t'">
12593 <xsl:attribute name="manuscript">yes</xsl:attribute>
12596 <xsl:when test="$leader6='a' or $leader6='t'">text</xsl:when>
12597 <xsl:when test="$leader6='e' or $leader6='f'">cartographic</xsl:when>
12598 <xsl:when test="$leader6='c' or $leader6='d'">notated music</xsl:when>
12599 <xsl:when test="$leader6='i'">sound recording-nonmusical</xsl:when>
12600 <xsl:when test="$leader6='j'">sound recording-musical</xsl:when>
12601 <xsl:when test="$leader6='k'">still image</xsl:when>
12602 <xsl:when test="$leader6='g'">moving image</xsl:when>
12603 <xsl:when test="$leader6='r'">three dimensional object</xsl:when>
12604 <xsl:when test="$leader6='m'">software, multimedia</xsl:when>
12605 <xsl:when test="$leader6='p'">mixed material</xsl:when>
12608 <xsl:if test="substring($controlField008,26,1)='d'">
12609 <genre authority="marc">globe</genre>
12611 <xsl:if test="marc:controlfield[@tag='007'][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
12612 <genre authority="marc">remote sensing image</genre>
12614 <xsl:if test="$typeOf008='MP'">
12615 <xsl:variable name="controlField008-25" select="substring($controlField008,26,1)"></xsl:variable>
12617 <xsl:when test="$controlField008-25='a' or $controlField008-25='b' or $controlField008-25='c' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
12618 <genre authority="marc">map</genre>
12620 <xsl:when test="$controlField008-25='e' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
12621 <genre authority="marc">atlas</genre>
12625 <xsl:if test="$typeOf008='SE'">
12626 <xsl:variable name="controlField008-21" select="substring($controlField008,22,1)"></xsl:variable>
12628 <xsl:when test="$controlField008-21='d'">
12629 <genre authority="marc">database</genre>
12631 <xsl:when test="$controlField008-21='l'">
12632 <genre authority="marc">loose-leaf</genre>
12634 <xsl:when test="$controlField008-21='m'">
12635 <genre authority="marc">series</genre>
12637 <xsl:when test="$controlField008-21='n'">
12638 <genre authority="marc">newspaper</genre>
12640 <xsl:when test="$controlField008-21='p'">
12641 <genre authority="marc">periodical</genre>
12643 <xsl:when test="$controlField008-21='w'">
12644 <genre authority="marc">web site</genre>
12648 <xsl:if test="$typeOf008='BK' or $typeOf008='SE'">
12649 <xsl:variable name="controlField008-24" select="substring($controlField008,25,4)"></xsl:variable>
12651 <xsl:when test="contains($controlField008-24,'a')">
12652 <genre authority="marc">abstract or summary</genre>
12654 <xsl:when test="contains($controlField008-24,'b')">
12655 <genre authority="marc">bibliography</genre>
12657 <xsl:when test="contains($controlField008-24,'c')">
12658 <genre authority="marc">catalog</genre>
12660 <xsl:when test="contains($controlField008-24,'d')">
12661 <genre authority="marc">dictionary</genre>
12663 <xsl:when test="contains($controlField008-24,'e')">
12664 <genre authority="marc">encyclopedia</genre>
12666 <xsl:when test="contains($controlField008-24,'f')">
12667 <genre authority="marc">handbook</genre>
12669 <xsl:when test="contains($controlField008-24,'g')">
12670 <genre authority="marc">legal article</genre>
12672 <xsl:when test="contains($controlField008-24,'i')">
12673 <genre authority="marc">index</genre>
12675 <xsl:when test="contains($controlField008-24,'k')">
12676 <genre authority="marc">discography</genre>
12678 <xsl:when test="contains($controlField008-24,'l')">
12679 <genre authority="marc">legislation</genre>
12681 <xsl:when test="contains($controlField008-24,'m')">
12682 <genre authority="marc">theses</genre>
12684 <xsl:when test="contains($controlField008-24,'n')">
12685 <genre authority="marc">survey of literature</genre>
12687 <xsl:when test="contains($controlField008-24,'o')">
12688 <genre authority="marc">review</genre>
12690 <xsl:when test="contains($controlField008-24,'p')">
12691 <genre authority="marc">programmed text</genre>
12693 <xsl:when test="contains($controlField008-24,'q')">
12694 <genre authority="marc">filmography</genre>
12696 <xsl:when test="contains($controlField008-24,'r')">
12697 <genre authority="marc">directory</genre>
12699 <xsl:when test="contains($controlField008-24,'s')">
12700 <genre authority="marc">statistics</genre>
12702 <xsl:when test="contains($controlField008-24,'t')">
12703 <genre authority="marc">technical report</genre>
12705 <xsl:when test="contains($controlField008-24,'v')">
12706 <genre authority="marc">legal case and case notes</genre>
12708 <xsl:when test="contains($controlField008-24,'w')">
12709 <genre authority="marc">law report or digest</genre>
12711 <xsl:when test="contains($controlField008-24,'z')">
12712 <genre authority="marc">treaty</genre>
12715 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
12717 <xsl:when test="$controlField008-29='1'">
12718 <genre authority="marc">conference publication</genre>
12722 <xsl:if test="$typeOf008='CF'">
12723 <xsl:variable name="controlField008-26" select="substring($controlField008,27,1)"></xsl:variable>
12725 <xsl:when test="$controlField008-26='a'">
12726 <genre authority="marc">numeric data</genre>
12728 <xsl:when test="$controlField008-26='e'">
12729 <genre authority="marc">database</genre>
12731 <xsl:when test="$controlField008-26='f'">
12732 <genre authority="marc">font</genre>
12734 <xsl:when test="$controlField008-26='g'">
12735 <genre authority="marc">game</genre>
12739 <xsl:if test="$typeOf008='BK'">
12740 <xsl:if test="substring($controlField008,25,1)='j'">
12741 <genre authority="marc">patent</genre>
12743 <xsl:if test="substring($controlField008,31,1)='1'">
12744 <genre authority="marc">festschrift</genre>
12746 <xsl:variable name="controlField008-34" select="substring($controlField008,35,1)"></xsl:variable>
12747 <xsl:if test="$controlField008-34='a' or $controlField008-34='b' or $controlField008-34='c' or $controlField008-34='d'">
12748 <genre authority="marc">biography</genre>
12750 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
12752 <xsl:when test="$controlField008-33='e'">
12753 <genre authority="marc">essay</genre>
12755 <xsl:when test="$controlField008-33='d'">
12756 <genre authority="marc">drama</genre>
12758 <xsl:when test="$controlField008-33='c'">
12759 <genre authority="marc">comic strip</genre>
12761 <xsl:when test="$controlField008-33='l'">
12762 <genre authority="marc">fiction</genre>
12764 <xsl:when test="$controlField008-33='h'">
12765 <genre authority="marc">humor, satire</genre>
12767 <xsl:when test="$controlField008-33='i'">
12768 <genre authority="marc">letter</genre>
12770 <xsl:when test="$controlField008-33='f'">
12771 <genre authority="marc">novel</genre>
12773 <xsl:when test="$controlField008-33='j'">
12774 <genre authority="marc">short story</genre>
12776 <xsl:when test="$controlField008-33='s'">
12777 <genre authority="marc">speech</genre>
12781 <xsl:if test="$typeOf008='MU'">
12782 <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"></xsl:variable>
12783 <xsl:if test="contains($controlField008-30-31,'b')">
12784 <genre authority="marc">biography</genre>
12786 <xsl:if test="contains($controlField008-30-31,'c')">
12787 <genre authority="marc">conference publication</genre>
12789 <xsl:if test="contains($controlField008-30-31,'d')">
12790 <genre authority="marc">drama</genre>
12792 <xsl:if test="contains($controlField008-30-31,'e')">
12793 <genre authority="marc">essay</genre>
12795 <xsl:if test="contains($controlField008-30-31,'f')">
12796 <genre authority="marc">fiction</genre>
12798 <xsl:if test="contains($controlField008-30-31,'o')">
12799 <genre authority="marc">folktale</genre>
12801 <xsl:if test="contains($controlField008-30-31,'h')">
12802 <genre authority="marc">history</genre>
12804 <xsl:if test="contains($controlField008-30-31,'k')">
12805 <genre authority="marc">humor, satire</genre>
12807 <xsl:if test="contains($controlField008-30-31,'m')">
12808 <genre authority="marc">memoir</genre>
12810 <xsl:if test="contains($controlField008-30-31,'p')">
12811 <genre authority="marc">poetry</genre>
12813 <xsl:if test="contains($controlField008-30-31,'r')">
12814 <genre authority="marc">rehearsal</genre>
12816 <xsl:if test="contains($controlField008-30-31,'g')">
12817 <genre authority="marc">reporting</genre>
12819 <xsl:if test="contains($controlField008-30-31,'s')">
12820 <genre authority="marc">sound</genre>
12822 <xsl:if test="contains($controlField008-30-31,'l')">
12823 <genre authority="marc">speech</genre>
12826 <xsl:if test="$typeOf008='VM'">
12827 <xsl:variable name="controlField008-33" select="substring($controlField008,34,1)"></xsl:variable>
12829 <xsl:when test="$controlField008-33='a'">
12830 <genre authority="marc">art original</genre>
12832 <xsl:when test="$controlField008-33='b'">
12833 <genre authority="marc">kit</genre>
12835 <xsl:when test="$controlField008-33='c'">
12836 <genre authority="marc">art reproduction</genre>
12838 <xsl:when test="$controlField008-33='d'">
12839 <genre authority="marc">diorama</genre>
12841 <xsl:when test="$controlField008-33='f'">
12842 <genre authority="marc">filmstrip</genre>
12844 <xsl:when test="$controlField008-33='g'">
12845 <genre authority="marc">legal article</genre>
12847 <xsl:when test="$controlField008-33='i'">
12848 <genre authority="marc">picture</genre>
12850 <xsl:when test="$controlField008-33='k'">
12851 <genre authority="marc">graphic</genre>
12853 <xsl:when test="$controlField008-33='l'">
12854 <genre authority="marc">technical drawing</genre>
12856 <xsl:when test="$controlField008-33='m'">
12857 <genre authority="marc">motion picture</genre>
12859 <xsl:when test="$controlField008-33='n'">
12860 <genre authority="marc">chart</genre>
12862 <xsl:when test="$controlField008-33='o'">
12863 <genre authority="marc">flash card</genre>
12865 <xsl:when test="$controlField008-33='p'">
12866 <genre authority="marc">microscope slide</genre>
12868 <xsl:when test="$controlField008-33='q' or marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
12869 <genre authority="marc">model</genre>
12871 <xsl:when test="$controlField008-33='r'">
12872 <genre authority="marc">realia</genre>
12874 <xsl:when test="$controlField008-33='s'">
12875 <genre authority="marc">slide</genre>
12877 <xsl:when test="$controlField008-33='t'">
12878 <genre authority="marc">transparency</genre>
12880 <xsl:when test="$controlField008-33='v'">
12881 <genre authority="marc">videorecording</genre>
12883 <xsl:when test="$controlField008-33='w'">
12884 <genre authority="marc">toy</genre>
12888 <xsl:for-each select="marc:datafield[@tag=655]">
12889 <genre authority="marc">
12890 <xsl:attribute name="authority">
12891 <xsl:value-of select="marc:subfield[@code='2']"/>
12893 <xsl:call-template name="subfieldSelect">
12894 <xsl:with-param name="codes">abvxyz</xsl:with-param>
12895 <xsl:with-param name="delimeter">-</xsl:with-param>
12896 </xsl:call-template>
12900 <xsl:variable name="MARCpublicationCode" select="normalize-space(substring($controlField008,16,3))"></xsl:variable>
12901 <xsl:if test="translate($MARCpublicationCode,'|','')">
12904 <xsl:attribute name="type">code</xsl:attribute>
12905 <xsl:attribute name="authority">marccountry</xsl:attribute>
12906 <xsl:value-of select="$MARCpublicationCode"/>
12910 <xsl:for-each select="marc:datafield[@tag=044]/marc:subfield[@code='c']">
12913 <xsl:attribute name="type">code</xsl:attribute>
12914 <xsl:attribute name="authority">iso3166</xsl:attribute>
12915 <xsl:value-of select="."/>
12919 <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='a']">
12922 <xsl:attribute name="type">text</xsl:attribute>
12923 <xsl:call-template name="chopPunctuationFront">
12924 <xsl:with-param name="chopString">
12925 <xsl:call-template name="chopPunctuation">
12926 <xsl:with-param name="chopString" select="."/>
12927 </xsl:call-template>
12929 </xsl:call-template>
12933 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='m']">
12934 <dateValid point="start">
12935 <xsl:value-of select="."/>
12938 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='n']">
12939 <dateValid point="end">
12940 <xsl:value-of select="."/>
12943 <xsl:for-each select="marc:datafield[@tag=046]/marc:subfield[@code='j']">
12945 <xsl:value-of select="."/>
12948 <xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='b' or @code='c' or @code='g']">
12950 <xsl:when test="@code='b'">
12952 <xsl:call-template name="chopPunctuation">
12953 <xsl:with-param name="chopString" select="."/>
12954 <xsl:with-param name="punctuation">
12955 <xsl:text>:,;/ </xsl:text>
12957 </xsl:call-template>
12960 <xsl:when test="@code='c'">
12962 <xsl:call-template name="chopPunctuation">
12963 <xsl:with-param name="chopString" select="."/>
12964 </xsl:call-template>
12967 <xsl:when test="@code='g'">
12969 <xsl:value-of select="."/>
12974 <xsl:variable name="dataField260c">
12975 <xsl:call-template name="chopPunctuation">
12976 <xsl:with-param name="chopString" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"></xsl:with-param>
12977 </xsl:call-template>
12979 <xsl:variable name="controlField008-7-10" select="normalize-space(substring($controlField008, 8, 4))"></xsl:variable>
12980 <xsl:variable name="controlField008-11-14" select="normalize-space(substring($controlField008, 12, 4))"></xsl:variable>
12981 <xsl:variable name="controlField008-6" select="normalize-space(substring($controlField008, 7, 1))"></xsl:variable>
12982 <xsl:if test="$controlField008-6='e' or $controlField008-6='p' or $controlField008-6='r' or $controlField008-6='t' or $controlField008-6='s'">
12983 <xsl:if test="$controlField008-7-10 and ($controlField008-7-10 != $dataField260c)">
12984 <dateIssued encoding="marc">
12985 <xsl:value-of select="$controlField008-7-10"/>
12989 <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
12990 <xsl:if test="$controlField008-7-10">
12991 <dateIssued encoding="marc" point="start">
12992 <xsl:value-of select="$controlField008-7-10"/>
12996 <xsl:if test="$controlField008-6='c' or $controlField008-6='d' or $controlField008-6='i' or $controlField008-6='k' or $controlField008-6='m' or $controlField008-6='q' or $controlField008-6='u'">
12997 <xsl:if test="$controlField008-11-14">
12998 <dateIssued encoding="marc" point="end">
12999 <xsl:value-of select="$controlField008-11-14"/>
13003 <xsl:if test="$controlField008-6='q'">
13004 <xsl:if test="$controlField008-7-10">
13005 <dateIssued encoding="marc" point="start" qualifier="questionable">
13006 <xsl:value-of select="$controlField008-7-10"/>
13010 <xsl:if test="$controlField008-6='q'">
13011 <xsl:if test="$controlField008-11-14">
13012 <dateIssued encoding="marc" point="end" qualifier="questionable">
13013 <xsl:value-of select="$controlField008-11-14"/>
13017 <xsl:if test="$controlField008-6='t'">
13018 <xsl:if test="$controlField008-11-14">
13019 <copyrightDate encoding="marc">
13020 <xsl:value-of select="$controlField008-11-14"/>
13024 <xsl:for-each select="marc:datafield[@tag=033][@ind1=0 or @ind1=1]/marc:subfield[@code='a']">
13025 <dateCaptured encoding="iso8601">
13026 <xsl:value-of select="."/>
13029 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][1]">
13030 <dateCaptured encoding="iso8601" point="start">
13031 <xsl:value-of select="."/>
13034 <xsl:for-each select="marc:datafield[@tag=033][@ind1=2]/marc:subfield[@code='a'][2]">
13035 <dateCaptured encoding="iso8601" point="end">
13036 <xsl:value-of select="."/>
13039 <xsl:for-each select="marc:datafield[@tag=250]/marc:subfield[@code='a']">
13041 <xsl:value-of select="."/>
13044 <xsl:for-each select="marc:leader">
13047 <xsl:when test="$leader7='a' or $leader7='c' or $leader7='d' or $leader7='m'">monographic</xsl:when>
13048 <xsl:when test="$leader7='b' or $leader7='i' or $leader7='s'">continuing</xsl:when>
13052 <xsl:for-each select="marc:datafield[@tag=310]|marc:datafield[@tag=321]">
13054 <xsl:call-template name="subfieldSelect">
13055 <xsl:with-param name="codes">ab</xsl:with-param>
13056 </xsl:call-template>
13060 <xsl:variable name="controlField008-35-37" select="normalize-space(translate(substring($controlField008,36,3),'|#',''))"></xsl:variable>
13061 <xsl:if test="$controlField008-35-37">
13063 <languageTerm authority="iso639-2b" type="code">
13064 <xsl:value-of select="substring($controlField008,36,3)"/>
13068 <xsl:for-each select="marc:datafield[@tag=041]">
13069 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='d' or @code='e' or @code='f' or @code='g' or @code='h']">
13070 <xsl:variable name="langCodes" select="."/>
13072 <xsl:when test="../marc:subfield[@code='2']='rfc3066'">
13073 <!-- not stacked but could be repeated -->
13074 <xsl:call-template name="rfcLanguages">
13075 <xsl:with-param name="nodeNum">
13076 <xsl:value-of select="1"/>
13078 <xsl:with-param name="usedLanguages">
13079 <xsl:text></xsl:text>
13081 <xsl:with-param name="controlField008-35-37">
13082 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
13084 </xsl:call-template>
13088 <xsl:variable name="allLanguages">
13089 <xsl:copy-of select="$langCodes"></xsl:copy-of>
13091 <xsl:variable name="currentLanguage">
13092 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
13094 <xsl:call-template name="isoLanguage">
13095 <xsl:with-param name="currentLanguage">
13096 <xsl:value-of select="substring($allLanguages,1,3)"></xsl:value-of>
13098 <xsl:with-param name="remainingLanguages">
13099 <xsl:value-of select="substring($allLanguages,4,string-length($allLanguages)-3)"></xsl:value-of>
13101 <xsl:with-param name="usedLanguages">
13102 <xsl:if test="$controlField008-35-37">
13103 <xsl:value-of select="$controlField008-35-37"></xsl:value-of>
13106 </xsl:call-template>
13111 <xsl:variable name="physicalDescription">
13112 <!--3.2 change tmee 007/11 -->
13113 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='a']">
13114 <digitalOrigin>reformatted digital</digitalOrigin>
13116 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='b']">
13117 <digitalOrigin>digitized microfilm</digitalOrigin>
13119 <xsl:if test="$typeOf008='CF' and marc:controlfield[@tag=007][substring(.,12,1)='d']">
13120 <digitalOrigin>digitized other analog</digitalOrigin>
13122 <xsl:variable name="controlField008-23" select="substring($controlField008,24,1)"></xsl:variable>
13123 <xsl:variable name="controlField008-29" select="substring($controlField008,30,1)"></xsl:variable>
13124 <xsl:variable name="check008-23">
13125 <xsl:if test="$typeOf008='BK' or $typeOf008='MU' or $typeOf008='SE' or $typeOf008='MM'">
13126 <xsl:value-of select="true()"></xsl:value-of>
13129 <xsl:variable name="check008-29">
13130 <xsl:if test="$typeOf008='MP' or $typeOf008='VM'">
13131 <xsl:value-of select="true()"></xsl:value-of>
13135 <xsl:when test="($check008-23 and $controlField008-23='f') or ($check008-29 and $controlField008-29='f')">
13136 <form authority="marcform">braille</form>
13138 <xsl:when test="($controlField008-23=' ' and ($leader6='c' or $leader6='d')) or (($typeOf008='BK' or $typeOf008='SE') and ($controlField008-23=' ' or $controlField008='r'))">
13139 <form authority="marcform">print</form>
13141 <xsl:when test="$leader6 = 'm' or ($check008-23 and $controlField008-23='s') or ($check008-29 and $controlField008-29='s')">
13142 <form authority="marcform">electronic</form>
13144 <xsl:when test="($check008-23 and $controlField008-23='b') or ($check008-29 and $controlField008-29='b')">
13145 <form authority="marcform">microfiche</form>
13147 <xsl:when test="($check008-23 and $controlField008-23='a') or ($check008-29 and $controlField008-29='a')">
13148 <form authority="marcform">microfilm</form>
13152 <xsl:if test="marc:datafield[@tag=130]/marc:subfield[@code='h']">
13153 <form authority="gmd">
13154 <xsl:call-template name="chopBrackets">
13155 <xsl:with-param name="chopString">
13156 <xsl:value-of select="marc:datafield[@tag=130]/marc:subfield[@code='h']"></xsl:value-of>
13158 </xsl:call-template>
13161 <xsl:if test="marc:datafield[@tag=240]/marc:subfield[@code='h']">
13162 <form authority="gmd">
13163 <xsl:call-template name="chopBrackets">
13164 <xsl:with-param name="chopString">
13165 <xsl:value-of select="marc:datafield[@tag=240]/marc:subfield[@code='h']"></xsl:value-of>
13167 </xsl:call-template>
13170 <xsl:if test="marc:datafield[@tag=242]/marc:subfield[@code='h']">
13171 <form authority="gmd">
13172 <xsl:call-template name="chopBrackets">
13173 <xsl:with-param name="chopString">
13174 <xsl:value-of select="marc:datafield[@tag=242]/marc:subfield[@code='h']"></xsl:value-of>
13176 </xsl:call-template>
13179 <xsl:if test="marc:datafield[@tag=245]/marc:subfield[@code='h']">
13180 <form authority="gmd">
13181 <xsl:call-template name="chopBrackets">
13182 <xsl:with-param name="chopString">
13183 <xsl:value-of select="marc:datafield[@tag=245]/marc:subfield[@code='h']"></xsl:value-of>
13185 </xsl:call-template>
13188 <xsl:if test="marc:datafield[@tag=246]/marc:subfield[@code='h']">
13189 <form authority="gmd">
13190 <xsl:call-template name="chopBrackets">
13191 <xsl:with-param name="chopString">
13192 <xsl:value-of select="marc:datafield[@tag=246]/marc:subfield[@code='h']"></xsl:value-of>
13194 </xsl:call-template>
13197 <xsl:if test="marc:datafield[@tag=730]/marc:subfield[@code='h']">
13198 <form authority="gmd">
13199 <xsl:call-template name="chopBrackets">
13200 <xsl:with-param name="chopString">
13201 <xsl:value-of select="marc:datafield[@tag=730]/marc:subfield[@code='h']"></xsl:value-of>
13203 </xsl:call-template>
13206 <xsl:for-each select="marc:datafield[@tag=256]/marc:subfield[@code='a']">
13208 <xsl:value-of select="."></xsl:value-of>
13211 <xsl:for-each select="marc:controlfield[@tag=007][substring(text(),1,1)='c']">
13213 <xsl:when test="substring(text(),14,1)='a'">
13214 <reformattingQuality>access</reformattingQuality>
13216 <xsl:when test="substring(text(),14,1)='p'">
13217 <reformattingQuality>preservation</reformattingQuality>
13219 <xsl:when test="substring(text(),14,1)='r'">
13220 <reformattingQuality>replacement</reformattingQuality>
13224 <!--3.2 change tmee 007/01 -->
13225 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='b']">
13226 <form authority="smd">chip cartridge</form>
13228 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='c']">
13229 <form authority="smd">computer optical disc cartridge</form>
13231 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='j']">
13232 <form authority="smd">magnetic disc</form>
13234 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='m']">
13235 <form authority="smd">magneto-optical disc</form>
13237 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='o']">
13238 <form authority="smd">optical disc</form>
13240 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='r']">
13241 <form authority="smd">remote</form>
13243 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='a']">
13244 <form authority="smd">tape cartridge</form>
13246 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='f']">
13247 <form authority="smd">tape cassette</form>
13249 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='c'][substring(text(),2,1)='h']">
13250 <form authority="smd">tape reel</form>
13253 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='a']">
13254 <form authority="smd">celestial globe</form>
13256 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='e']">
13257 <form authority="smd">earth moon globe</form>
13259 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='b']">
13260 <form authority="smd">planetary or lunar globe</form>
13262 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='d'][substring(text(),2,1)='c']">
13263 <form authority="smd">terrestrial globe</form>
13266 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='o'][substring(text(),2,1)='o']">
13267 <form authority="smd">kit</form>
13270 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='d']">
13271 <form authority="smd">atlas</form>
13273 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='g']">
13274 <form authority="smd">diagram</form>
13276 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='j']">
13277 <form authority="smd">map</form>
13279 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='q']">
13280 <form authority="smd">model</form>
13282 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='k']">
13283 <form authority="smd">profile</form>
13285 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='r']">
13286 <form authority="smd">remote-sensing image</form>
13288 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='s']">
13289 <form authority="smd">section</form>
13291 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='a'][substring(text(),2,1)='y']">
13292 <form authority="smd">view</form>
13295 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='a']">
13296 <form authority="smd">aperture card</form>
13298 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='e']">
13299 <form authority="smd">microfiche</form>
13301 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='f']">
13302 <form authority="smd">microfiche cassette</form>
13304 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='b']">
13305 <form authority="smd">microfilm cartridge</form>
13307 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='c']">
13308 <form authority="smd">microfilm cassette</form>
13310 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='d']">
13311 <form authority="smd">microfilm reel</form>
13313 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='h'][substring(text(),2,1)='g']">
13314 <form authority="smd">microopaque</form>
13317 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='c']">
13318 <form authority="smd">film cartridge</form>
13320 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='f']">
13321 <form authority="smd">film cassette</form>
13323 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='m'][substring(text(),2,1)='r']">
13324 <form authority="smd">film reel</form>
13327 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='n']">
13328 <form authority="smd">chart</form>
13330 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='c']">
13331 <form authority="smd">collage</form>
13333 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='d']">
13334 <form authority="smd">drawing</form>
13336 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='o']">
13337 <form authority="smd">flash card</form>
13339 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='e']">
13340 <form authority="smd">painting</form>
13342 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='f']">
13343 <form authority="smd">photomechanical print</form>
13345 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='g']">
13346 <form authority="smd">photonegative</form>
13348 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='h']">
13349 <form authority="smd">photoprint</form>
13351 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='i']">
13352 <form authority="smd">picture</form>
13354 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='j']">
13355 <form authority="smd">print</form>
13357 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='k'][substring(text(),2,1)='l']">
13358 <form authority="smd">technical drawing</form>
13361 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='q'][substring(text(),2,1)='q']">
13362 <form authority="smd">notated music</form>
13365 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='d']">
13366 <form authority="smd">filmslip</form>
13368 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='c']">
13369 <form authority="smd">filmstrip cartridge</form>
13371 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='o']">
13372 <form authority="smd">filmstrip roll</form>
13374 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='f']">
13375 <form authority="smd">other filmstrip type</form>
13377 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='s']">
13378 <form authority="smd">slide</form>
13380 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='g'][substring(text(),2,1)='t']">
13381 <form authority="smd">transparency</form>
13383 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='r'][substring(text(),2,1)='r']">
13384 <form authority="smd">remote-sensing image</form>
13386 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='e']">
13387 <form authority="smd">cylinder</form>
13389 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='q']">
13390 <form authority="smd">roll</form>
13392 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='g']">
13393 <form authority="smd">sound cartridge</form>
13395 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='s']">
13396 <form authority="smd">sound cassette</form>
13398 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='d']">
13399 <form authority="smd">sound disc</form>
13401 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='t']">
13402 <form authority="smd">sound-tape reel</form>
13404 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='i']">
13405 <form authority="smd">sound-track film</form>
13407 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='s'][substring(text(),2,1)='w']">
13408 <form authority="smd">wire recording</form>
13411 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='c']">
13412 <form authority="smd">braille</form>
13414 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='b']">
13415 <form authority="smd">combination</form>
13417 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='a']">
13418 <form authority="smd">moon</form>
13420 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='f'][substring(text(),2,1)='d']">
13421 <form authority="smd">tactile, with no writing system</form>
13424 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='c']">
13425 <form authority="smd">braille</form>
13427 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='b']">
13428 <form authority="smd">large print</form>
13430 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='a']">
13431 <form authority="smd">regular print</form>
13433 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='t'][substring(text(),2,1)='d']">
13434 <form authority="smd">text in looseleaf binder</form>
13437 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='c']">
13438 <form authority="smd">videocartridge</form>
13440 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='f']">
13441 <form authority="smd">videocassette</form>
13443 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='d']">
13444 <form authority="smd">videodisc</form>
13446 <xsl:if test="marc:controlfield[@tag=007][substring(text(),1,1)='v'][substring(text(),2,1)='r']">
13447 <form authority="smd">videoreel</form>
13450 <xsl:for-each select="marc:datafield[@tag=856]/marc:subfield[@code='q'][string-length(.)>1]">
13451 <internetMediaType>
13452 <xsl:value-of select="."></xsl:value-of>
13453 </internetMediaType>
13455 <xsl:for-each select="marc:datafield[@tag=300]">
13457 <xsl:call-template name="subfieldSelect">
13458 <xsl:with-param name="codes">abce</xsl:with-param>
13459 </xsl:call-template>
13463 <xsl:if test="string-length(normalize-space($physicalDescription))">
13464 <physicalDescription>
13465 <xsl:copy-of select="$physicalDescription"></xsl:copy-of>
13466 </physicalDescription>
13468 <xsl:for-each select="marc:datafield[@tag=520]">
13470 <xsl:call-template name="uri"></xsl:call-template>
13471 <xsl:call-template name="subfieldSelect">
13472 <xsl:with-param name="codes">ab</xsl:with-param>
13473 </xsl:call-template>
13476 <xsl:for-each select="marc:datafield[@tag=505]">
13478 <xsl:call-template name="uri"></xsl:call-template>
13479 <xsl:call-template name="subfieldSelect">
13480 <xsl:with-param name="codes">agrt</xsl:with-param>
13481 </xsl:call-template>
13484 <xsl:for-each select="marc:datafield[@tag=521]">
13486 <xsl:call-template name="subfieldSelect">
13487 <xsl:with-param name="codes">ab</xsl:with-param>
13488 </xsl:call-template>
13491 <xsl:if test="$typeOf008='BK' or $typeOf008='CF' or $typeOf008='MU' or $typeOf008='VM'">
13492 <xsl:variable name="controlField008-22" select="substring($controlField008,23,1)"></xsl:variable>
13495 <xsl:when test="$controlField008-22='d'">
13496 <targetAudience authority="marctarget">adolescent</targetAudience>
13498 <xsl:when test="$controlField008-22='e'">
13499 <targetAudience authority="marctarget">adult</targetAudience>
13501 <xsl:when test="$controlField008-22='g'">
13502 <targetAudience authority="marctarget">general</targetAudience>
13504 <xsl:when test="$controlField008-22='b' or $controlField008-22='c' or $controlField008-22='j'">
13505 <targetAudience authority="marctarget">juvenile</targetAudience>
13507 <xsl:when test="$controlField008-22='a'">
13508 <targetAudience authority="marctarget">preschool</targetAudience>
13510 <xsl:when test="$controlField008-22='f'">
13511 <targetAudience authority="marctarget">specialized</targetAudience>
13515 <xsl:for-each select="marc:datafield[@tag=245]/marc:subfield[@code='c']">
13516 <note type="statement of responsibility">
13517 <xsl:value-of select="."></xsl:value-of>
13520 <xsl:for-each select="marc:datafield[@tag=500]">
13522 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13523 <xsl:call-template name="uri"></xsl:call-template>
13527 <!--3.2 change tmee additional note fields-->
13529 <xsl:for-each select="marc:datafield[@tag=506]">
13530 <note type="restrictions">
13531 <xsl:call-template name="uri"></xsl:call-template>
13532 <xsl:variable name="str">
13533 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13534 <xsl:value-of select="."></xsl:value-of>
13535 <xsl:text> </xsl:text>
13538 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13542 <xsl:for-each select="marc:datafield[@tag=510]">
13543 <note type="citation/reference">
13544 <xsl:call-template name="uri"></xsl:call-template>
13545 <xsl:variable name="str">
13546 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13547 <xsl:value-of select="."></xsl:value-of>
13548 <xsl:text> </xsl:text>
13551 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13556 <xsl:for-each select="marc:datafield[@tag=511]">
13557 <note type="performers">
13558 <xsl:call-template name="uri"></xsl:call-template>
13559 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13562 <xsl:for-each select="marc:datafield[@tag=518]">
13563 <note type="venue">
13564 <xsl:call-template name="uri"></xsl:call-template>
13565 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13569 <xsl:for-each select="marc:datafield[@tag=530]">
13570 <note type="additional physical form">
13571 <xsl:call-template name="uri"></xsl:call-template>
13572 <xsl:variable name="str">
13573 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13574 <xsl:value-of select="."></xsl:value-of>
13575 <xsl:text> </xsl:text>
13578 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13582 <xsl:for-each select="marc:datafield[@tag=533]">
13583 <note type="reproduction">
13584 <xsl:call-template name="uri"></xsl:call-template>
13585 <xsl:variable name="str">
13586 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13587 <xsl:value-of select="."></xsl:value-of>
13588 <xsl:text> </xsl:text>
13591 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13595 <xsl:for-each select="marc:datafield[@tag=534]">
13596 <note type="original version">
13597 <xsl:call-template name="uri"></xsl:call-template>
13598 <xsl:variable name="str">
13599 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13600 <xsl:value-of select="."></xsl:value-of>
13601 <xsl:text> </xsl:text>
13604 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13608 <xsl:for-each select="marc:datafield[@tag=538]">
13609 <note type="system details">
13610 <xsl:call-template name="uri"></xsl:call-template>
13611 <xsl:variable name="str">
13612 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13613 <xsl:value-of select="."></xsl:value-of>
13614 <xsl:text> </xsl:text>
13617 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13621 <xsl:for-each select="marc:datafield[@tag=583]">
13622 <note type="action">
13623 <xsl:call-template name="uri"></xsl:call-template>
13624 <xsl:variable name="str">
13625 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13626 <xsl:value-of select="."></xsl:value-of>
13627 <xsl:text> </xsl:text>
13630 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13638 <xsl:for-each select="marc:datafield[@tag=501 or @tag=502 or @tag=504 or @tag=507 or @tag=508 or @tag=513 or @tag=514 or @tag=515 or @tag=516 or @tag=522 or @tag=524 or @tag=525 or @tag=526 or @tag=535 or @tag=536 or @tag=540 or @tag=541 or @tag=544 or @tag=545 or @tag=546 or @tag=547 or @tag=550 or @tag=552 or @tag=555 or @tag=556 or @tag=561 or @tag=562 or @tag=565 or @tag=567 or @tag=580 or @tag=581 or @tag=584 or @tag=585 or @tag=586]">
13640 <xsl:call-template name="uri"></xsl:call-template>
13641 <xsl:variable name="str">
13642 <xsl:for-each select="marc:subfield[@code!='6' or @code!='8']">
13643 <xsl:value-of select="."></xsl:value-of>
13644 <xsl:text> </xsl:text>
13647 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
13650 <xsl:for-each select="marc:datafield[@tag=034][marc:subfield[@code='d' or @code='e' or @code='f' or @code='g']]">
13654 <xsl:call-template name="subfieldSelect">
13655 <xsl:with-param name="codes">defg</xsl:with-param>
13656 </xsl:call-template>
13661 <xsl:for-each select="marc:datafield[@tag=043]">
13663 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
13665 <xsl:attribute name="authority">
13666 <xsl:if test="@code='a'">
13667 <xsl:text>marcgac</xsl:text>
13669 <xsl:if test="@code='b'">
13670 <xsl:value-of select="following-sibling::marc:subfield[@code=2]"></xsl:value-of>
13672 <xsl:if test="@code='c'">
13673 <xsl:text>iso3166</xsl:text>
13676 <xsl:value-of select="self::marc:subfield"></xsl:value-of>
13681 <!-- tmee 2006/11/27 -->
13682 <xsl:for-each select="marc:datafield[@tag=255]">
13684 <xsl:for-each select="marc:subfield[@code='a' or @code='b' or @code='c']">
13686 <xsl:if test="@code='a'">
13688 <xsl:value-of select="."></xsl:value-of>
13691 <xsl:if test="@code='b'">
13693 <xsl:value-of select="."></xsl:value-of>
13696 <xsl:if test="@code='c'">
13698 <xsl:value-of select="."></xsl:value-of>
13706 <xsl:apply-templates select="marc:datafield[653 >= @tag and @tag >= 600]"></xsl:apply-templates>
13707 <xsl:apply-templates select="marc:datafield[@tag=656]"></xsl:apply-templates>
13708 <xsl:for-each select="marc:datafield[@tag=752]">
13710 <hierarchicalGeographic>
13711 <xsl:for-each select="marc:subfield[@code='a']">
13713 <xsl:call-template name="chopPunctuation">
13714 <xsl:with-param name="chopString" select="."></xsl:with-param>
13715 </xsl:call-template>
13718 <xsl:for-each select="marc:subfield[@code='b']">
13720 <xsl:call-template name="chopPunctuation">
13721 <xsl:with-param name="chopString" select="."></xsl:with-param>
13722 </xsl:call-template>
13725 <xsl:for-each select="marc:subfield[@code='c']">
13727 <xsl:call-template name="chopPunctuation">
13728 <xsl:with-param name="chopString" select="."></xsl:with-param>
13729 </xsl:call-template>
13732 <xsl:for-each select="marc:subfield[@code='d']">
13734 <xsl:call-template name="chopPunctuation">
13735 <xsl:with-param name="chopString" select="."></xsl:with-param>
13736 </xsl:call-template>
13739 </hierarchicalGeographic>
13742 <xsl:for-each select="marc:datafield[@tag=045][marc:subfield[@code='b']]">
13745 <xsl:when test="@ind1=2">
13746 <temporal encoding="iso8601" point="start">
13747 <xsl:call-template name="chopPunctuation">
13748 <xsl:with-param name="chopString">
13749 <xsl:value-of select="marc:subfield[@code='b'][1]"></xsl:value-of>
13751 </xsl:call-template>
13753 <temporal encoding="iso8601" point="end">
13754 <xsl:call-template name="chopPunctuation">
13755 <xsl:with-param name="chopString">
13756 <xsl:value-of select="marc:subfield[@code='b'][2]"></xsl:value-of>
13758 </xsl:call-template>
13762 <xsl:for-each select="marc:subfield[@code='b']">
13763 <temporal encoding="iso8601">
13764 <xsl:call-template name="chopPunctuation">
13765 <xsl:with-param name="chopString" select="."></xsl:with-param>
13766 </xsl:call-template>
13773 <xsl:for-each select="marc:datafield[@tag=050]">
13774 <xsl:for-each select="marc:subfield[@code='b']">
13775 <classification authority="lcc">
13776 <xsl:if test="../marc:subfield[@code='3']">
13777 <xsl:attribute name="displayLabel">
13778 <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
13781 <xsl:value-of select="preceding-sibling::marc:subfield[@code='a'][1]"></xsl:value-of>
13782 <xsl:text> </xsl:text>
13783 <xsl:value-of select="text()"></xsl:value-of>
13786 <xsl:for-each select="marc:subfield[@code='a'][not(following-sibling::marc:subfield[@code='b'])]">
13787 <classification authority="lcc">
13788 <xsl:if test="../marc:subfield[@code='3']">
13789 <xsl:attribute name="displayLabel">
13790 <xsl:value-of select="../marc:subfield[@code='3']"></xsl:value-of>
13793 <xsl:value-of select="text()"></xsl:value-of>
13797 <xsl:for-each select="marc:datafield[@tag=082]">
13798 <classification authority="ddc">
13799 <xsl:if test="marc:subfield[@code='2']">
13800 <xsl:attribute name="edition">
13801 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13804 <xsl:call-template name="subfieldSelect">
13805 <xsl:with-param name="codes">ab</xsl:with-param>
13806 </xsl:call-template>
13809 <xsl:for-each select="marc:datafield[@tag=080]">
13810 <classification authority="udc">
13811 <xsl:call-template name="subfieldSelect">
13812 <xsl:with-param name="codes">abx</xsl:with-param>
13813 </xsl:call-template>
13816 <xsl:for-each select="marc:datafield[@tag=060]">
13817 <classification authority="nlm">
13818 <xsl:call-template name="subfieldSelect">
13819 <xsl:with-param name="codes">ab</xsl:with-param>
13820 </xsl:call-template>
13823 <xsl:for-each select="marc:datafield[@tag=086][@ind1=0]">
13824 <classification authority="sudocs">
13825 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13828 <xsl:for-each select="marc:datafield[@tag=086][@ind1=1]">
13829 <classification authority="candoc">
13830 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13833 <xsl:for-each select="marc:datafield[@tag=086]">
13835 <xsl:attribute name="authority">
13836 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13838 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
13841 <xsl:for-each select="marc:datafield[@tag=084]">
13843 <xsl:attribute name="authority">
13844 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
13846 <xsl:call-template name="subfieldSelect">
13847 <xsl:with-param name="codes">ab</xsl:with-param>
13848 </xsl:call-template>
13851 <xsl:for-each select="marc:datafield[@tag=440]">
13852 <relatedItem type="series">
13853 <xsl:variable name="titleChop">
13854 <xsl:call-template name="chopPunctuation">
13855 <xsl:with-param name="chopString">
13856 <xsl:call-template name="subfieldSelect">
13857 <xsl:with-param name="codes">av</xsl:with-param>
13858 </xsl:call-template>
13860 </xsl:call-template>
13864 <xsl:value-of select="$titleChop" />
13866 <xsl:call-template name="part"></xsl:call-template>
13868 <titleInfo type="nfi">
13870 <xsl:when test="@ind2>0">
13872 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
13875 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
13877 <xsl:call-template name="part"/>
13881 <xsl:value-of select="$titleChop" />
13885 <xsl:call-template name="part"></xsl:call-template>
13889 <xsl:for-each select="marc:datafield[@tag=490][@ind1=0]">
13890 <relatedItem type="series">
13893 <xsl:call-template name="chopPunctuation">
13894 <xsl:with-param name="chopString">
13895 <xsl:call-template name="subfieldSelect">
13896 <xsl:with-param name="codes">av</xsl:with-param>
13897 </xsl:call-template>
13899 </xsl:call-template>
13901 <xsl:call-template name="part"></xsl:call-template>
13905 <xsl:for-each select="marc:datafield[@tag=510]">
13906 <relatedItem type="isReferencedBy">
13908 <xsl:call-template name="subfieldSelect">
13909 <xsl:with-param name="codes">abcx3</xsl:with-param>
13910 </xsl:call-template>
13914 <xsl:for-each select="marc:datafield[@tag=534]">
13915 <relatedItem type="original">
13916 <xsl:call-template name="relatedTitle"></xsl:call-template>
13917 <xsl:call-template name="relatedName"></xsl:call-template>
13918 <xsl:if test="marc:subfield[@code='b' or @code='c']">
13920 <xsl:for-each select="marc:subfield[@code='c']">
13922 <xsl:value-of select="."></xsl:value-of>
13925 <xsl:for-each select="marc:subfield[@code='b']">
13927 <xsl:value-of select="."></xsl:value-of>
13932 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
13933 <xsl:for-each select="marc:subfield[@code='z']">
13934 <identifier type="isbn">
13935 <xsl:value-of select="."></xsl:value-of>
13938 <xsl:call-template name="relatedNote"></xsl:call-template>
13941 <xsl:for-each select="marc:datafield[@tag=700][marc:subfield[@code='t']]">
13943 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
13946 <xsl:call-template name="chopPunctuation">
13947 <xsl:with-param name="chopString">
13948 <xsl:call-template name="specialSubfieldSelect">
13949 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
13950 <xsl:with-param name="axis">t</xsl:with-param>
13951 <xsl:with-param name="afterCodes">g</xsl:with-param>
13952 </xsl:call-template>
13954 </xsl:call-template>
13956 <xsl:call-template name="part"></xsl:call-template>
13958 <name type="personal">
13960 <xsl:call-template name="specialSubfieldSelect">
13961 <xsl:with-param name="anyCodes">aq</xsl:with-param>
13962 <xsl:with-param name="axis">t</xsl:with-param>
13963 <xsl:with-param name="beforeCodes">g</xsl:with-param>
13964 </xsl:call-template>
13966 <xsl:call-template name="termsOfAddress"></xsl:call-template>
13967 <xsl:call-template name="nameDate"></xsl:call-template>
13968 <xsl:call-template name="role"></xsl:call-template>
13970 <xsl:call-template name="relatedForm"></xsl:call-template>
13971 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
13974 <xsl:for-each select="marc:datafield[@tag=710][marc:subfield[@code='t']]">
13976 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
13979 <xsl:call-template name="chopPunctuation">
13980 <xsl:with-param name="chopString">
13981 <xsl:call-template name="specialSubfieldSelect">
13982 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
13983 <xsl:with-param name="axis">t</xsl:with-param>
13984 <xsl:with-param name="afterCodes">dg</xsl:with-param>
13985 </xsl:call-template>
13987 </xsl:call-template>
13989 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
13991 <name type="corporate">
13992 <xsl:for-each select="marc:subfield[@code='a']">
13994 <xsl:value-of select="."></xsl:value-of>
13997 <xsl:for-each select="marc:subfield[@code='b']">
13999 <xsl:value-of select="."></xsl:value-of>
14002 <xsl:variable name="tempNamePart">
14003 <xsl:call-template name="specialSubfieldSelect">
14004 <xsl:with-param name="anyCodes">c</xsl:with-param>
14005 <xsl:with-param name="axis">t</xsl:with-param>
14006 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
14007 </xsl:call-template>
14009 <xsl:if test="normalize-space($tempNamePart)">
14011 <xsl:value-of select="$tempNamePart"></xsl:value-of>
14014 <xsl:call-template name="role"></xsl:call-template>
14016 <xsl:call-template name="relatedForm"></xsl:call-template>
14017 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14020 <xsl:for-each select="marc:datafield[@tag=711][marc:subfield[@code='t']]">
14022 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14025 <xsl:call-template name="chopPunctuation">
14026 <xsl:with-param name="chopString">
14027 <xsl:call-template name="specialSubfieldSelect">
14028 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
14029 <xsl:with-param name="axis">t</xsl:with-param>
14030 <xsl:with-param name="afterCodes">g</xsl:with-param>
14031 </xsl:call-template>
14033 </xsl:call-template>
14035 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14037 <name type="conference">
14039 <xsl:call-template name="specialSubfieldSelect">
14040 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
14041 <xsl:with-param name="axis">t</xsl:with-param>
14042 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
14043 </xsl:call-template>
14046 <xsl:call-template name="relatedForm"></xsl:call-template>
14047 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14050 <xsl:for-each select="marc:datafield[@tag=730][@ind2=2]">
14052 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14055 <xsl:call-template name="chopPunctuation">
14056 <xsl:with-param name="chopString">
14057 <xsl:call-template name="subfieldSelect">
14058 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
14059 </xsl:call-template>
14061 </xsl:call-template>
14063 <xsl:call-template name="part"></xsl:call-template>
14065 <xsl:call-template name="relatedForm"></xsl:call-template>
14066 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14069 <xsl:for-each select="marc:datafield[@tag=740][@ind2=2]">
14071 <xsl:call-template name="constituentOrRelatedType"></xsl:call-template>
14072 <xsl:variable name="titleChop">
14073 <xsl:call-template name="chopPunctuation">
14074 <xsl:with-param name="chopString">
14075 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
14077 </xsl:call-template>
14081 <xsl:value-of select="$titleChop" />
14083 <xsl:call-template name="part"></xsl:call-template>
14085 <titleInfo type="nfi">
14087 <xsl:when test="@ind1>0">
14089 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
14092 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
14097 <xsl:value-of select="$titleChop" />
14101 <xsl:call-template name="part"></xsl:call-template>
14103 <xsl:call-template name="relatedForm"></xsl:call-template>
14106 <xsl:for-each select="marc:datafield[@tag=760]|marc:datafield[@tag=762]">
14107 <relatedItem type="series">
14108 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14111 <xsl:for-each select="marc:datafield[@tag=765]|marc:datafield[@tag=767]|marc:datafield[@tag=777]|marc:datafield[@tag=787]">
14113 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14116 <xsl:for-each select="marc:datafield[@tag=775]">
14117 <relatedItem type="otherVersion">
14118 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14121 <xsl:for-each select="marc:datafield[@tag=770]|marc:datafield[@tag=774]">
14122 <relatedItem type="constituent">
14123 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14126 <xsl:for-each select="marc:datafield[@tag=772]|marc:datafield[@tag=773]">
14127 <relatedItem type="host">
14128 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14131 <xsl:for-each select="marc:datafield[@tag=776]">
14132 <relatedItem type="otherFormat">
14133 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14136 <xsl:for-each select="marc:datafield[@tag=780]">
14137 <relatedItem type="preceding">
14138 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14141 <xsl:for-each select="marc:datafield[@tag=785]">
14142 <relatedItem type="succeeding">
14143 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14146 <xsl:for-each select="marc:datafield[@tag=786]">
14147 <relatedItem type="original">
14148 <xsl:call-template name="relatedItem76X-78X"></xsl:call-template>
14151 <xsl:for-each select="marc:datafield[@tag=800]">
14152 <relatedItem type="series">
14155 <xsl:call-template name="chopPunctuation">
14156 <xsl:with-param name="chopString">
14157 <xsl:call-template name="specialSubfieldSelect">
14158 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
14159 <xsl:with-param name="axis">t</xsl:with-param>
14160 <xsl:with-param name="afterCodes">g</xsl:with-param>
14161 </xsl:call-template>
14163 </xsl:call-template>
14165 <xsl:call-template name="part"></xsl:call-template>
14167 <name type="personal">
14169 <xsl:call-template name="chopPunctuation">
14170 <xsl:with-param name="chopString">
14171 <xsl:call-template name="specialSubfieldSelect">
14172 <xsl:with-param name="anyCodes">aq</xsl:with-param>
14173 <xsl:with-param name="axis">t</xsl:with-param>
14174 <xsl:with-param name="beforeCodes">g</xsl:with-param>
14175 </xsl:call-template>
14177 </xsl:call-template>
14179 <xsl:call-template name="termsOfAddress"></xsl:call-template>
14180 <xsl:call-template name="nameDate"></xsl:call-template>
14181 <xsl:call-template name="role"></xsl:call-template>
14183 <xsl:call-template name="relatedForm"></xsl:call-template>
14186 <xsl:for-each select="marc:datafield[@tag=810]">
14187 <relatedItem type="series">
14190 <xsl:call-template name="chopPunctuation">
14191 <xsl:with-param name="chopString">
14192 <xsl:call-template name="specialSubfieldSelect">
14193 <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param>
14194 <xsl:with-param name="axis">t</xsl:with-param>
14195 <xsl:with-param name="afterCodes">dg</xsl:with-param>
14196 </xsl:call-template>
14198 </xsl:call-template>
14200 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14202 <name type="corporate">
14203 <xsl:for-each select="marc:subfield[@code='a']">
14205 <xsl:value-of select="."></xsl:value-of>
14208 <xsl:for-each select="marc:subfield[@code='b']">
14210 <xsl:value-of select="."></xsl:value-of>
14214 <xsl:call-template name="specialSubfieldSelect">
14215 <xsl:with-param name="anyCodes">c</xsl:with-param>
14216 <xsl:with-param name="axis">t</xsl:with-param>
14217 <xsl:with-param name="beforeCodes">dgn</xsl:with-param>
14218 </xsl:call-template>
14220 <xsl:call-template name="role"></xsl:call-template>
14222 <xsl:call-template name="relatedForm"></xsl:call-template>
14225 <xsl:for-each select="marc:datafield[@tag=811]">
14226 <relatedItem type="series">
14229 <xsl:call-template name="chopPunctuation">
14230 <xsl:with-param name="chopString">
14231 <xsl:call-template name="specialSubfieldSelect">
14232 <xsl:with-param name="anyCodes">tfklsv</xsl:with-param>
14233 <xsl:with-param name="axis">t</xsl:with-param>
14234 <xsl:with-param name="afterCodes">g</xsl:with-param>
14235 </xsl:call-template>
14237 </xsl:call-template>
14239 <xsl:call-template name="relatedPartNumName"/>
14241 <name type="conference">
14243 <xsl:call-template name="specialSubfieldSelect">
14244 <xsl:with-param name="anyCodes">aqdc</xsl:with-param>
14245 <xsl:with-param name="axis">t</xsl:with-param>
14246 <xsl:with-param name="beforeCodes">gn</xsl:with-param>
14247 </xsl:call-template>
14249 <xsl:call-template name="role"/>
14251 <xsl:call-template name="relatedForm"/>
14254 <xsl:for-each select="marc:datafield[@tag='830']">
14255 <relatedItem type="series">
14256 <xsl:variable name="titleChop">
14257 <xsl:call-template name="chopPunctuation">
14258 <xsl:with-param name="chopString">
14259 <xsl:call-template name="subfieldSelect">
14260 <xsl:with-param name="codes">adfgklmorsv</xsl:with-param>
14261 </xsl:call-template>
14263 </xsl:call-template>
14267 <xsl:value-of select="$titleChop" />
14269 <xsl:call-template name="part"/>
14271 <titleInfo type="nfi">
14273 <xsl:when test="@ind2>0">
14275 <xsl:value-of select="substring($titleChop,1,@ind2)"/>
14278 <xsl:value-of select="substring($titleChop,@ind2+1)"/>
14283 <xsl:value-of select="$titleChop" />
14287 <xsl:call-template name="part"/>
14289 <xsl:call-template name="relatedForm"/>
14292 <xsl:for-each select="marc:datafield[@tag='856'][@ind2='2']/marc:subfield[@code='q']">
14294 <internetMediaType>
14295 <xsl:value-of select="."/>
14296 </internetMediaType>
14299 <xsl:for-each select="marc:datafield[@tag='020']">
14300 <xsl:call-template name="isInvalid">
14301 <xsl:with-param name="type">isbn</xsl:with-param>
14302 </xsl:call-template>
14303 <xsl:if test="marc:subfield[@code='a']">
14304 <identifier type="isbn">
14305 <xsl:value-of select="marc:subfield[@code='a']"/>
14309 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='0']">
14310 <xsl:call-template name="isInvalid">
14311 <xsl:with-param name="type">isrc</xsl:with-param>
14312 </xsl:call-template>
14313 <xsl:if test="marc:subfield[@code='a']">
14314 <identifier type="isrc">
14315 <xsl:value-of select="marc:subfield[@code='a']"/>
14319 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='2']">
14320 <xsl:call-template name="isInvalid">
14321 <xsl:with-param name="type">ismn</xsl:with-param>
14322 </xsl:call-template>
14323 <xsl:if test="marc:subfield[@code='a']">
14324 <identifier type="ismn">
14325 <xsl:value-of select="marc:subfield[@code='a']"/>
14329 <xsl:for-each select="marc:datafield[@tag='024'][@ind1='4']">
14330 <xsl:call-template name="isInvalid">
14331 <xsl:with-param name="type">sici</xsl:with-param>
14332 </xsl:call-template>
14333 <identifier type="sici">
14334 <xsl:call-template name="subfieldSelect">
14335 <xsl:with-param name="codes">ab</xsl:with-param>
14336 </xsl:call-template>
14339 <xsl:for-each select="marc:datafield[@tag='022']">
14340 <xsl:call-template name="isInvalid">
14341 <xsl:with-param name="type">issn</xsl:with-param>
14342 </xsl:call-template>
14343 <identifier type="issn">
14344 <xsl:value-of select="marc:subfield[@code='a']"/>
14347 <xsl:for-each select="marc:datafield[@tag='010']">
14348 <xsl:call-template name="isInvalid">
14349 <xsl:with-param name="type">lccn</xsl:with-param>
14350 </xsl:call-template>
14351 <identifier type="lccn">
14352 <xsl:value-of select="normalize-space(marc:subfield[@code='a'])"/>
14355 <xsl:for-each select="marc:datafield[@tag='028']">
14357 <xsl:attribute name="type">
14359 <xsl:when test="@ind1='0'">issue number</xsl:when>
14360 <xsl:when test="@ind1='1'">matrix number</xsl:when>
14361 <xsl:when test="@ind1='2'">music plate</xsl:when>
14362 <xsl:when test="@ind1='3'">music publisher</xsl:when>
14363 <xsl:when test="@ind1='4'">videorecording identifier</xsl:when>
14366 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 028 -->
14367 <xsl:call-template name="subfieldSelect">
14368 <xsl:with-param name="codes">
14370 <xsl:when test="@ind1='0'">ba</xsl:when>
14371 <xsl:otherwise>ab</xsl:otherwise>
14374 </xsl:call-template>
14377 <xsl:for-each select="marc:datafield[@tag='037']">
14378 <identifier type="stock number">
14379 <!--<xsl:call-template name="isInvalid"/>--> <!-- no $z in 037 -->
14380 <xsl:call-template name="subfieldSelect">
14381 <xsl:with-param name="codes">ab</xsl:with-param>
14382 </xsl:call-template>
14385 <xsl:for-each select="marc:datafield[@tag='856'][marc:subfield[@code='u']]">
14387 <xsl:attribute name="type">
14389 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:doi') or starts-with(marc:subfield[@code='u'],'doi')">doi</xsl:when>
14390 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov')">hdl</xsl:when>
14391 <xsl:otherwise>uri</xsl:otherwise>
14395 <xsl:when test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl') or starts-with(marc:subfield[@code='u'],'http://hdl.loc.gov') ">
14396 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
14399 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
14403 <xsl:if test="starts-with(marc:subfield[@code='u'],'urn:hdl') or starts-with(marc:subfield[@code='u'],'hdl')">
14404 <identifier type="hdl">
14405 <xsl:if test="marc:subfield[@code='y' or @code='3' or @code='z']">
14406 <xsl:attribute name="displayLabel">
14407 <xsl:call-template name="subfieldSelect">
14408 <xsl:with-param name="codes">y3z</xsl:with-param>
14409 </xsl:call-template>
14412 <xsl:value-of select="concat('hdl:',substring-after(marc:subfield[@code='u'],'http://hdl.loc.gov/'))"></xsl:value-of>
14416 <xsl:for-each select="marc:datafield[@tag=024][@ind1=1]">
14417 <identifier type="upc">
14418 <xsl:call-template name="isInvalid"/>
14419 <xsl:value-of select="marc:subfield[@code='a']"/>
14422 <!-- 1/04 fix added $y -->
14423 <xsl:for-each select="marc:datafield[@tag=856][marc:subfield[@code='u']]">
14426 <xsl:if test="marc:subfield[@code='y' or @code='3']">
14427 <xsl:attribute name="displayLabel">
14428 <xsl:call-template name="subfieldSelect">
14429 <xsl:with-param name="codes">y3</xsl:with-param>
14430 </xsl:call-template>
14433 <xsl:if test="marc:subfield[@code='z' ]">
14434 <xsl:attribute name="note">
14435 <xsl:call-template name="subfieldSelect">
14436 <xsl:with-param name="codes">z</xsl:with-param>
14437 </xsl:call-template>
14440 <xsl:value-of select="marc:subfield[@code='u']"></xsl:value-of>
14446 <!-- 3.2 change tmee 856z -->
14449 <xsl:for-each select="marc:datafield[@tag=852]">
14452 <xsl:call-template name="displayLabel"></xsl:call-template>
14453 <xsl:call-template name="subfieldSelect">
14454 <xsl:with-param name="codes">abje</xsl:with-param>
14455 </xsl:call-template>
14456 </physicalLocation>
14459 <xsl:for-each select="marc:datafield[@tag=506]">
14460 <accessCondition type="restrictionOnAccess">
14461 <xsl:call-template name="subfieldSelect">
14462 <xsl:with-param name="codes">abcd35</xsl:with-param>
14463 </xsl:call-template>
14466 <xsl:for-each select="marc:datafield[@tag=540]">
14467 <accessCondition type="useAndReproduction">
14468 <xsl:call-template name="subfieldSelect">
14469 <xsl:with-param name="codes">abcde35</xsl:with-param>
14470 </xsl:call-template>
14474 <xsl:for-each select="marc:datafield[@tag=040]">
14475 <recordContentSource authority="marcorg">
14476 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
14477 </recordContentSource>
14479 <xsl:for-each select="marc:controlfield[@tag=008]">
14480 <recordCreationDate encoding="marc">
14481 <xsl:value-of select="substring(.,1,6)"></xsl:value-of>
14482 </recordCreationDate>
14484 <xsl:for-each select="marc:controlfield[@tag=005]">
14485 <recordChangeDate encoding="iso8601">
14486 <xsl:value-of select="."></xsl:value-of>
14487 </recordChangeDate>
14489 <xsl:for-each select="marc:controlfield[@tag=001]">
14491 <xsl:if test="../marc:controlfield[@tag=003]">
14492 <xsl:attribute name="source">
14493 <xsl:value-of select="../marc:controlfield[@tag=003]"></xsl:value-of>
14496 <xsl:value-of select="."></xsl:value-of>
14497 </recordIdentifier>
14499 <xsl:for-each select="marc:datafield[@tag=040]/marc:subfield[@code='b']">
14500 <languageOfCataloging>
14501 <languageTerm authority="iso639-2b" type="code">
14502 <xsl:value-of select="."></xsl:value-of>
14504 </languageOfCataloging>
14508 <xsl:template name="displayForm">
14509 <xsl:for-each select="marc:subfield[@code='c']">
14511 <xsl:value-of select="."></xsl:value-of>
14515 <xsl:template name="affiliation">
14516 <xsl:for-each select="marc:subfield[@code='u']">
14518 <xsl:value-of select="."></xsl:value-of>
14522 <xsl:template name="uri">
14523 <xsl:for-each select="marc:subfield[@code='u']">
14524 <xsl:attribute name="xlink:href">
14525 <xsl:value-of select="."></xsl:value-of>
14528 <xsl:for-each select="marc:subfield[@code='0']">
14530 <xsl:when test="contains(text(), ')')">
14531 <xsl:attribute name="xlink:href">
14532 <xsl:value-of select="substring-after(text(), ')')"></xsl:value-of>
14536 <xsl:attribute name="xlink:href">
14537 <xsl:value-of select="."></xsl:value-of>
14543 <xsl:template name="role">
14544 <xsl:for-each select="marc:subfield[@code='e']">
14546 <roleTerm type="text">
14547 <xsl:value-of select="."></xsl:value-of>
14551 <xsl:for-each select="marc:subfield[@code='4']">
14553 <roleTerm authority="marcrelator" type="code">
14554 <xsl:value-of select="."></xsl:value-of>
14559 <xsl:template name="part">
14560 <xsl:variable name="partNumber">
14561 <xsl:call-template name="specialSubfieldSelect">
14562 <xsl:with-param name="axis">n</xsl:with-param>
14563 <xsl:with-param name="anyCodes">n</xsl:with-param>
14564 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14565 </xsl:call-template>
14567 <xsl:variable name="partName">
14568 <xsl:call-template name="specialSubfieldSelect">
14569 <xsl:with-param name="axis">p</xsl:with-param>
14570 <xsl:with-param name="anyCodes">p</xsl:with-param>
14571 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14572 </xsl:call-template>
14574 <xsl:if test="string-length(normalize-space($partNumber))">
14576 <xsl:call-template name="chopPunctuation">
14577 <xsl:with-param name="chopString" select="$partNumber"></xsl:with-param>
14578 </xsl:call-template>
14581 <xsl:if test="string-length(normalize-space($partName))">
14583 <xsl:call-template name="chopPunctuation">
14584 <xsl:with-param name="chopString" select="$partName"></xsl:with-param>
14585 </xsl:call-template>
14589 <xsl:template name="relatedPart">
14590 <xsl:if test="@tag=773">
14591 <xsl:for-each select="marc:subfield[@code='g']">
14594 <xsl:value-of select="."></xsl:value-of>
14598 <xsl:for-each select="marc:subfield[@code='q']">
14600 <xsl:call-template name="parsePart"></xsl:call-template>
14605 <xsl:template name="relatedPartNumName">
14606 <xsl:variable name="partNumber">
14607 <xsl:call-template name="specialSubfieldSelect">
14608 <xsl:with-param name="axis">g</xsl:with-param>
14609 <xsl:with-param name="anyCodes">g</xsl:with-param>
14610 <xsl:with-param name="afterCodes">pst</xsl:with-param>
14611 </xsl:call-template>
14613 <xsl:variable name="partName">
14614 <xsl:call-template name="specialSubfieldSelect">
14615 <xsl:with-param name="axis">p</xsl:with-param>
14616 <xsl:with-param name="anyCodes">p</xsl:with-param>
14617 <xsl:with-param name="afterCodes">fgkdlmor</xsl:with-param>
14618 </xsl:call-template>
14620 <xsl:if test="string-length(normalize-space($partNumber))">
14622 <xsl:value-of select="$partNumber"></xsl:value-of>
14625 <xsl:if test="string-length(normalize-space($partName))">
14627 <xsl:value-of select="$partName"></xsl:value-of>
14631 <xsl:template name="relatedName">
14632 <xsl:for-each select="marc:subfield[@code='a']">
14635 <xsl:value-of select="."></xsl:value-of>
14640 <xsl:template name="relatedForm">
14641 <xsl:for-each select="marc:subfield[@code='h']">
14642 <physicalDescription>
14644 <xsl:value-of select="."></xsl:value-of>
14646 </physicalDescription>
14649 <xsl:template name="relatedExtent">
14650 <xsl:for-each select="marc:subfield[@code='h']">
14651 <physicalDescription>
14653 <xsl:value-of select="."></xsl:value-of>
14655 </physicalDescription>
14658 <xsl:template name="relatedNote">
14659 <xsl:for-each select="marc:subfield[@code='n']">
14661 <xsl:value-of select="."></xsl:value-of>
14665 <xsl:template name="relatedSubject">
14666 <xsl:for-each select="marc:subfield[@code='j']">
14668 <temporal encoding="iso8601">
14669 <xsl:call-template name="chopPunctuation">
14670 <xsl:with-param name="chopString" select="."></xsl:with-param>
14671 </xsl:call-template>
14676 <xsl:template name="relatedIdentifierISSN">
14677 <xsl:for-each select="marc:subfield[@code='x']">
14678 <identifier type="issn">
14679 <xsl:value-of select="."></xsl:value-of>
14683 <xsl:template name="relatedIdentifierLocal">
14684 <xsl:for-each select="marc:subfield[@code='w']">
14685 <identifier type="local">
14686 <xsl:value-of select="."></xsl:value-of>
14690 <xsl:template name="relatedIdentifier">
14691 <xsl:for-each select="marc:subfield[@code='o']">
14693 <xsl:value-of select="."></xsl:value-of>
14697 <xsl:template name="relatedItem76X-78X">
14698 <xsl:call-template name="displayLabel"></xsl:call-template>
14699 <xsl:call-template name="relatedTitle76X-78X"></xsl:call-template>
14700 <xsl:call-template name="relatedName"></xsl:call-template>
14701 <xsl:call-template name="relatedOriginInfo"></xsl:call-template>
14702 <xsl:call-template name="relatedLanguage"></xsl:call-template>
14703 <xsl:call-template name="relatedExtent"></xsl:call-template>
14704 <xsl:call-template name="relatedNote"></xsl:call-template>
14705 <xsl:call-template name="relatedSubject"></xsl:call-template>
14706 <xsl:call-template name="relatedIdentifier"></xsl:call-template>
14707 <xsl:call-template name="relatedIdentifierISSN"></xsl:call-template>
14708 <xsl:call-template name="relatedIdentifierLocal"></xsl:call-template>
14709 <xsl:call-template name="relatedPart"></xsl:call-template>
14711 <xsl:template name="subjectGeographicZ">
14713 <xsl:call-template name="chopPunctuation">
14714 <xsl:with-param name="chopString" select="."></xsl:with-param>
14715 </xsl:call-template>
14718 <xsl:template name="subjectTemporalY">
14720 <xsl:call-template name="chopPunctuation">
14721 <xsl:with-param name="chopString" select="."></xsl:with-param>
14722 </xsl:call-template>
14725 <xsl:template name="subjectTopic">
14727 <xsl:call-template name="chopPunctuation">
14728 <xsl:with-param name="chopString" select="."></xsl:with-param>
14729 </xsl:call-template>
14732 <!-- 3.2 change tmee 6xx $v genre -->
14733 <xsl:template name="subjectGenre">
14735 <xsl:call-template name="chopPunctuation">
14736 <xsl:with-param name="chopString" select="."></xsl:with-param>
14737 </xsl:call-template>
14741 <xsl:template name="nameABCDN">
14742 <xsl:for-each select="marc:subfield[@code='a']">
14744 <xsl:call-template name="chopPunctuation">
14745 <xsl:with-param name="chopString" select="."></xsl:with-param>
14746 </xsl:call-template>
14749 <xsl:for-each select="marc:subfield[@code='b']">
14751 <xsl:value-of select="."></xsl:value-of>
14754 <xsl:if test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
14756 <xsl:call-template name="subfieldSelect">
14757 <xsl:with-param name="codes">cdn</xsl:with-param>
14758 </xsl:call-template>
14762 <xsl:template name="nameABCDQ">
14764 <xsl:call-template name="chopPunctuation">
14765 <xsl:with-param name="chopString">
14766 <xsl:call-template name="subfieldSelect">
14767 <xsl:with-param name="codes">aq</xsl:with-param>
14768 </xsl:call-template>
14770 <xsl:with-param name="punctuation">
14771 <xsl:text>:,;/ </xsl:text>
14773 </xsl:call-template>
14775 <xsl:call-template name="termsOfAddress"></xsl:call-template>
14776 <xsl:call-template name="nameDate"></xsl:call-template>
14778 <xsl:template name="nameACDEQ">
14780 <xsl:call-template name="subfieldSelect">
14781 <xsl:with-param name="codes">acdeq</xsl:with-param>
14782 </xsl:call-template>
14785 <xsl:template name="constituentOrRelatedType">
14786 <xsl:if test="@ind2=2">
14787 <xsl:attribute name="type">constituent</xsl:attribute>
14790 <xsl:template name="relatedTitle">
14791 <xsl:for-each select="marc:subfield[@code='t']">
14794 <xsl:call-template name="chopPunctuation">
14795 <xsl:with-param name="chopString">
14796 <xsl:value-of select="."></xsl:value-of>
14798 </xsl:call-template>
14803 <xsl:template name="relatedTitle76X-78X">
14804 <xsl:for-each select="marc:subfield[@code='t']">
14807 <xsl:call-template name="chopPunctuation">
14808 <xsl:with-param name="chopString">
14809 <xsl:value-of select="."></xsl:value-of>
14811 </xsl:call-template>
14813 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14814 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14818 <xsl:for-each select="marc:subfield[@code='p']">
14819 <titleInfo type="abbreviated">
14821 <xsl:call-template name="chopPunctuation">
14822 <xsl:with-param name="chopString">
14823 <xsl:value-of select="."></xsl:value-of>
14825 </xsl:call-template>
14827 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14828 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14832 <xsl:for-each select="marc:subfield[@code='s']">
14833 <titleInfo type="uniform">
14835 <xsl:call-template name="chopPunctuation">
14836 <xsl:with-param name="chopString">
14837 <xsl:value-of select="."></xsl:value-of>
14839 </xsl:call-template>
14841 <xsl:if test="marc:datafield[@tag!=773]and marc:subfield[@code='g']">
14842 <xsl:call-template name="relatedPartNumName"></xsl:call-template>
14847 <xsl:template name="relatedOriginInfo">
14848 <xsl:if test="marc:subfield[@code='b' or @code='d'] or marc:subfield[@code='f']">
14850 <xsl:if test="@tag=775">
14851 <xsl:for-each select="marc:subfield[@code='f']">
14854 <xsl:attribute name="type">code</xsl:attribute>
14855 <xsl:attribute name="authority">marcgac</xsl:attribute>
14856 <xsl:value-of select="."></xsl:value-of>
14861 <xsl:for-each select="marc:subfield[@code='d']">
14863 <xsl:value-of select="."></xsl:value-of>
14866 <xsl:for-each select="marc:subfield[@code='b']">
14868 <xsl:value-of select="."></xsl:value-of>
14874 <xsl:template name="relatedLanguage">
14875 <xsl:for-each select="marc:subfield[@code='e']">
14876 <xsl:call-template name="getLanguage">
14877 <xsl:with-param name="langString">
14878 <xsl:value-of select="."></xsl:value-of>
14880 </xsl:call-template>
14883 <xsl:template name="nameDate">
14884 <xsl:for-each select="marc:subfield[@code='d']">
14885 <namePart type="date">
14886 <xsl:call-template name="chopPunctuation">
14887 <xsl:with-param name="chopString" select="."></xsl:with-param>
14888 </xsl:call-template>
14892 <xsl:template name="subjectAuthority">
14893 <xsl:if test="@ind2!=4">
14894 <xsl:if test="@ind2!=' '">
14895 <xsl:if test="@ind2!=8">
14896 <xsl:if test="@ind2!=9">
14897 <xsl:attribute name="authority">
14899 <xsl:when test="@ind2=0">lcsh</xsl:when>
14900 <xsl:when test="@ind2=1">lcshac</xsl:when>
14901 <xsl:when test="@ind2=2">mesh</xsl:when>
14903 <xsl:when test="@ind2=3">nal</xsl:when>
14904 <xsl:when test="@ind2=5">csh</xsl:when>
14905 <xsl:when test="@ind2=6">rvm</xsl:when>
14906 <xsl:when test="@ind2=7">
14907 <xsl:value-of select="marc:subfield[@code='2']"></xsl:value-of>
14916 <xsl:template name="subjectAnyOrder">
14917 <xsl:for-each select="marc:subfield[@code='v' or @code='x' or @code='y' or @code='z']">
14919 <xsl:when test="@code='v'">
14920 <xsl:call-template name="subjectGenre"></xsl:call-template>
14922 <xsl:when test="@code='x'">
14923 <xsl:call-template name="subjectTopic"></xsl:call-template>
14925 <xsl:when test="@code='y'">
14926 <xsl:call-template name="subjectTemporalY"></xsl:call-template>
14928 <xsl:when test="@code='z'">
14929 <xsl:call-template name="subjectGeographicZ"></xsl:call-template>
14934 <xsl:template name="specialSubfieldSelect">
14935 <xsl:param name="anyCodes"></xsl:param>
14936 <xsl:param name="axis"></xsl:param>
14937 <xsl:param name="beforeCodes"></xsl:param>
14938 <xsl:param name="afterCodes"></xsl:param>
14939 <xsl:variable name="str">
14940 <xsl:for-each select="marc:subfield">
14941 <xsl:if test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
14942 <xsl:value-of select="text()"></xsl:value-of>
14943 <xsl:text> </xsl:text>
14947 <xsl:value-of select="substring($str,1,string-length($str)-1)"></xsl:value-of>
14950 <!-- 3.2 change tmee 6xx $v genre -->
14951 <xsl:template match="marc:datafield[@tag=600]">
14953 <xsl:call-template name="subjectAuthority"></xsl:call-template>
14954 <name type="personal">
14955 <xsl:call-template name="uri" />
14957 <xsl:call-template name="chopPunctuation">
14958 <xsl:with-param name="chopString">
14959 <xsl:call-template name="subfieldSelect">
14960 <xsl:with-param name="codes">aq</xsl:with-param>
14961 </xsl:call-template>
14963 </xsl:call-template>
14965 <xsl:call-template name="termsOfAddress"></xsl:call-template>
14966 <xsl:call-template name="nameDate"></xsl:call-template>
14967 <xsl:call-template name="affiliation"></xsl:call-template>
14968 <xsl:call-template name="role"></xsl:call-template>
14970 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
14973 <xsl:template match="marc:datafield[@tag=610]">
14975 <xsl:call-template name="subjectAuthority"></xsl:call-template>
14976 <name type="corporate">
14977 <xsl:call-template name="uri" />
14978 <xsl:for-each select="marc:subfield[@code='a']">
14980 <xsl:value-of select="."></xsl:value-of>
14983 <xsl:for-each select="marc:subfield[@code='b']">
14985 <xsl:value-of select="."></xsl:value-of>
14988 <xsl:if test="marc:subfield[@code='c' or @code='d' or @code='n' or @code='p']">
14990 <xsl:call-template name="subfieldSelect">
14991 <xsl:with-param name="codes">cdnp</xsl:with-param>
14992 </xsl:call-template>
14995 <xsl:call-template name="role"></xsl:call-template>
14997 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15000 <xsl:template match="marc:datafield[@tag=611]">
15002 <xsl:call-template name="subjectAuthority"></xsl:call-template>
15003 <name type="conference">
15004 <xsl:call-template name="uri" />
15006 <xsl:call-template name="subfieldSelect">
15007 <xsl:with-param name="codes">abcdeqnp</xsl:with-param>
15008 </xsl:call-template>
15010 <xsl:for-each select="marc:subfield[@code='4']">
15012 <roleTerm authority="marcrelator" type="code">
15013 <xsl:value-of select="."></xsl:value-of>
15018 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15021 <xsl:template match="marc:datafield[@tag=630]">
15023 <xsl:call-template name="subjectAuthority"></xsl:call-template>
15024 <xsl:variable name="titleChop">
15025 <xsl:call-template name="chopPunctuation">
15026 <xsl:with-param name="chopString">
15027 <xsl:call-template name="subfieldSelect">
15028 <xsl:with-param name="codes">adfhklor</xsl:with-param>
15029 </xsl:call-template>
15031 </xsl:call-template>
15035 <xsl:value-of select="$titleChop" />
15037 <xsl:call-template name="part"></xsl:call-template>
15039 <titleInfo type="nfi">
15041 <xsl:when test="@ind1>0">
15043 <xsl:value-of select="substring($titleChop,1,@ind1)"/>
15046 <xsl:value-of select="substring($titleChop,@ind1+1)"/>
15048 <xsl:call-template name="part"/>
15052 <xsl:value-of select="$titleChop" />
15056 <xsl:call-template name="part"></xsl:call-template>
15058 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15061 <xsl:template match="marc:datafield[@tag=650]">
15063 <xsl:call-template name="subjectAuthority"></xsl:call-template>
15065 <xsl:call-template name="uri" />
15066 <xsl:call-template name="chopPunctuation">
15067 <xsl:with-param name="chopString">
15068 <xsl:call-template name="subfieldSelect">
15069 <xsl:with-param name="codes">abcd</xsl:with-param>
15070 </xsl:call-template>
15072 </xsl:call-template>
15074 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15077 <xsl:template match="marc:datafield[@tag=651]">
15079 <xsl:call-template name="subjectAuthority"></xsl:call-template>
15080 <xsl:for-each select="marc:subfield[@code='a']">
15082 <xsl:call-template name="uri" />
15083 <xsl:call-template name="chopPunctuation">
15084 <xsl:with-param name="chopString" select="."></xsl:with-param>
15085 </xsl:call-template>
15088 <xsl:call-template name="subjectAnyOrder"></xsl:call-template>
15091 <xsl:template match="marc:datafield[@tag=653]">
15093 <xsl:for-each select="marc:subfield[@code='a']">
15095 <xsl:call-template name="uri" />
15096 <xsl:value-of select="."></xsl:value-of>
15101 <xsl:template match="marc:datafield[@tag=656]">
15103 <xsl:if test="marc:subfield[@code=2]">
15104 <xsl:attribute name="authority">
15105 <xsl:value-of select="marc:subfield[@code=2]"></xsl:value-of>
15109 <xsl:call-template name="uri" />
15110 <xsl:call-template name="chopPunctuation">
15111 <xsl:with-param name="chopString">
15112 <xsl:value-of select="marc:subfield[@code='a']"></xsl:value-of>
15114 </xsl:call-template>
15118 <xsl:template name="termsOfAddress">
15119 <xsl:if test="marc:subfield[@code='b' or @code='c']">
15120 <namePart type="termsOfAddress">
15121 <xsl:call-template name="chopPunctuation">
15122 <xsl:with-param name="chopString">
15123 <xsl:call-template name="subfieldSelect">
15124 <xsl:with-param name="codes">bc</xsl:with-param>
15125 </xsl:call-template>
15127 </xsl:call-template>
15131 <xsl:template name="displayLabel">
15132 <xsl:if test="marc:subfield[@code='i']">
15133 <xsl:attribute name="displayLabel">
15134 <xsl:value-of select="marc:subfield[@code='i']"></xsl:value-of>
15137 <xsl:if test="marc:subfield[@code='3']">
15138 <xsl:attribute name="displayLabel">
15139 <xsl:value-of select="marc:subfield[@code='3']"></xsl:value-of>
15143 <xsl:template name="isInvalid">
15144 <xsl:param name="type"/>
15145 <xsl:if test="marc:subfield[@code='z'] or marc:subfield[@code='y']">
15147 <xsl:attribute name="type">
15148 <xsl:value-of select="$type"/>
15150 <xsl:attribute name="invalid">
15151 <xsl:text>yes</xsl:text>
15153 <xsl:if test="marc:subfield[@code='z']">
15154 <xsl:value-of select="marc:subfield[@code='z']"/>
15156 <xsl:if test="marc:subfield[@code='y']">
15157 <xsl:value-of select="marc:subfield[@code='y']"/>
15162 <xsl:template name="subtitle">
15163 <xsl:if test="marc:subfield[@code='b']">
15165 <xsl:call-template name="chopPunctuation">
15166 <xsl:with-param name="chopString">
15167 <xsl:value-of select="marc:subfield[@code='b']"/>
15168 <!--<xsl:call-template name="subfieldSelect">
15169 <xsl:with-param name="codes">b</xsl:with-param>
15170 </xsl:call-template>-->
15172 </xsl:call-template>
15176 <xsl:template name="script">
15177 <xsl:param name="scriptCode"></xsl:param>
15178 <xsl:attribute name="script">
15180 <xsl:when test="$scriptCode='(3'">Arabic</xsl:when>
15181 <xsl:when test="$scriptCode='(B'">Latin</xsl:when>
15182 <xsl:when test="$scriptCode='$1'">Chinese, Japanese, Korean</xsl:when>
15183 <xsl:when test="$scriptCode='(N'">Cyrillic</xsl:when>
15184 <xsl:when test="$scriptCode='(2'">Hebrew</xsl:when>
15185 <xsl:when test="$scriptCode='(S'">Greek</xsl:when>
15189 <xsl:template name="parsePart">
15190 <!-- assumes 773$q= 1:2:3<4
15191 with up to 3 levels and one optional start page
15193 <xsl:variable name="level1">
15195 <xsl:when test="contains(text(),':')">
15197 <xsl:value-of select="substring-before(text(),':')"></xsl:value-of>
15199 <xsl:when test="not(contains(text(),':'))">
15201 <xsl:if test="contains(text(),'<')">
15203 <xsl:value-of select="substring-before(text(),'<')"></xsl:value-of>
15205 <xsl:if test="not(contains(text(),'<'))">
15207 <xsl:value-of select="text()"></xsl:value-of>
15212 <xsl:variable name="sici2">
15214 <xsl:when test="starts-with(substring-after(text(),$level1),':')">
15215 <xsl:value-of select="substring(substring-after(text(),$level1),2)"></xsl:value-of>
15218 <xsl:value-of select="substring-after(text(),$level1)"></xsl:value-of>
15222 <xsl:variable name="level2">
15224 <xsl:when test="contains($sici2,':')">
15226 <xsl:value-of select="substring-before($sici2,':')"></xsl:value-of>
15228 <xsl:when test="contains($sici2,'<')">
15230 <xsl:value-of select="substring-before($sici2,'<')"></xsl:value-of>
15233 <xsl:value-of select="$sici2"></xsl:value-of>
15238 <xsl:variable name="sici3">
15240 <xsl:when test="starts-with(substring-after($sici2,$level2),':')">
15241 <xsl:value-of select="substring(substring-after($sici2,$level2),2)"></xsl:value-of>
15244 <xsl:value-of select="substring-after($sici2,$level2)"></xsl:value-of>
15248 <xsl:variable name="level3">
15250 <xsl:when test="contains($sici3,'<')">
15252 <xsl:value-of select="substring-before($sici3,'<')"></xsl:value-of>
15255 <xsl:value-of select="$sici3"></xsl:value-of>
15260 <xsl:variable name="page">
15261 <xsl:if test="contains(text(),'<')">
15262 <xsl:value-of select="substring-after(text(),'<')"></xsl:value-of>
15265 <xsl:if test="$level1">
15268 <xsl:value-of select="$level1"></xsl:value-of>
15272 <xsl:if test="$level2">
15275 <xsl:value-of select="$level2"></xsl:value-of>
15279 <xsl:if test="$level3">
15282 <xsl:value-of select="$level3"></xsl:value-of>
15286 <xsl:if test="$page">
15287 <extent unit="page">
15289 <xsl:value-of select="$page"></xsl:value-of>
15294 <xsl:template name="getLanguage">
15295 <xsl:param name="langString"></xsl:param>
15296 <xsl:param name="controlField008-35-37"></xsl:param>
15297 <xsl:variable name="length" select="string-length($langString)"></xsl:variable>
15299 <xsl:when test="$length=0"></xsl:when>
15300 <xsl:when test="$controlField008-35-37=substring($langString,1,3)">
15301 <xsl:call-template name="getLanguage">
15302 <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
15303 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
15304 </xsl:call-template>
15308 <languageTerm authority="iso639-2b" type="code">
15309 <xsl:value-of select="substring($langString,1,3)"></xsl:value-of>
15312 <xsl:call-template name="getLanguage">
15313 <xsl:with-param name="langString" select="substring($langString,4,$length)"></xsl:with-param>
15314 <xsl:with-param name="controlField008-35-37" select="$controlField008-35-37"></xsl:with-param>
15315 </xsl:call-template>
15319 <xsl:template name="isoLanguage">
15320 <xsl:param name="currentLanguage"></xsl:param>
15321 <xsl:param name="usedLanguages"></xsl:param>
15322 <xsl:param name="remainingLanguages"></xsl:param>
15324 <xsl:when test="string-length($currentLanguage)=0"></xsl:when>
15325 <xsl:when test="not(contains($usedLanguages, $currentLanguage))">
15327 <xsl:if test="@code!='a'">
15328 <xsl:attribute name="objectPart">
15330 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
15331 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
15332 <xsl:when test="@code='e'">libretto</xsl:when>
15333 <xsl:when test="@code='f'">table of contents</xsl:when>
15334 <xsl:when test="@code='g'">accompanying material</xsl:when>
15335 <xsl:when test="@code='h'">translation</xsl:when>
15339 <languageTerm authority="iso639-2b" type="code">
15340 <xsl:value-of select="$currentLanguage"></xsl:value-of>
15343 <xsl:call-template name="isoLanguage">
15344 <xsl:with-param name="currentLanguage">
15345 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
15347 <xsl:with-param name="usedLanguages">
15348 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
15350 <xsl:with-param name="remainingLanguages">
15351 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
15353 </xsl:call-template>
15356 <xsl:call-template name="isoLanguage">
15357 <xsl:with-param name="currentLanguage">
15358 <xsl:value-of select="substring($remainingLanguages,1,3)"></xsl:value-of>
15360 <xsl:with-param name="usedLanguages">
15361 <xsl:value-of select="concat($usedLanguages,$currentLanguage)"></xsl:value-of>
15363 <xsl:with-param name="remainingLanguages">
15364 <xsl:value-of select="substring($remainingLanguages,4,string-length($remainingLanguages))"></xsl:value-of>
15366 </xsl:call-template>
15370 <xsl:template name="chopBrackets">
15371 <xsl:param name="chopString"></xsl:param>
15372 <xsl:variable name="string">
15373 <xsl:call-template name="chopPunctuation">
15374 <xsl:with-param name="chopString" select="$chopString"></xsl:with-param>
15375 </xsl:call-template>
15377 <xsl:if test="substring($string, 1,1)='['">
15378 <xsl:value-of select="substring($string,2, string-length($string)-2)"></xsl:value-of>
15380 <xsl:if test="substring($string, 1,1)!='['">
15381 <xsl:value-of select="$string"></xsl:value-of>
15384 <xsl:template name="rfcLanguages">
15385 <xsl:param name="nodeNum"></xsl:param>
15386 <xsl:param name="usedLanguages"></xsl:param>
15387 <xsl:param name="controlField008-35-37"></xsl:param>
15388 <xsl:variable name="currentLanguage" select="."></xsl:variable>
15390 <xsl:when test="not($currentLanguage)"></xsl:when>
15391 <xsl:when test="$currentLanguage!=$controlField008-35-37 and $currentLanguage!='rfc3066'">
15392 <xsl:if test="not(contains($usedLanguages,$currentLanguage))">
15394 <xsl:if test="@code!='a'">
15395 <xsl:attribute name="objectPart">
15397 <xsl:when test="@code='b'">summary or subtitle</xsl:when>
15398 <xsl:when test="@code='d'">sung or spoken text</xsl:when>
15399 <xsl:when test="@code='e'">libretto</xsl:when>
15400 <xsl:when test="@code='f'">table of contents</xsl:when>
15401 <xsl:when test="@code='g'">accompanying material</xsl:when>
15402 <xsl:when test="@code='h'">translation</xsl:when>
15406 <languageTerm authority="rfc3066" type="code">
15407 <xsl:value-of select="$currentLanguage"/>
15416 <xsl:template name="datafield">
15417 <xsl:param name="tag"/>
15418 <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param>
15419 <xsl:param name="ind2"><xsl:text> </xsl:text></xsl:param>
15420 <xsl:param name="subfields"/>
15421 <xsl:element name="marc:datafield">
15422 <xsl:attribute name="tag">
15423 <xsl:value-of select="$tag"/>
15425 <xsl:attribute name="ind1">
15426 <xsl:value-of select="$ind1"/>
15428 <xsl:attribute name="ind2">
15429 <xsl:value-of select="$ind2"/>
15431 <xsl:copy-of select="$subfields"/>
15435 <xsl:template name="subfieldSelect">
15436 <xsl:param name="codes"/>
15437 <xsl:param name="delimeter"><xsl:text> </xsl:text></xsl:param>
15438 <xsl:variable name="str">
15439 <xsl:for-each select="marc:subfield">
15440 <xsl:if test="contains($codes, @code)">
15441 <xsl:value-of select="text()"/><xsl:value-of select="$delimeter"/>
15445 <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
15448 <xsl:template name="buildSpaces">
15449 <xsl:param name="spaces"/>
15450 <xsl:param name="char"><xsl:text> </xsl:text></xsl:param>
15451 <xsl:if test="$spaces>0">
15452 <xsl:value-of select="$char"/>
15453 <xsl:call-template name="buildSpaces">
15454 <xsl:with-param name="spaces" select="$spaces - 1"/>
15455 <xsl:with-param name="char" select="$char"/>
15456 </xsl:call-template>
15460 <xsl:template name="chopPunctuation">
15461 <xsl:param name="chopString"/>
15462 <xsl:param name="punctuation"><xsl:text>.:,;/ </xsl:text></xsl:param>
15463 <xsl:variable name="length" select="string-length($chopString)"/>
15465 <xsl:when test="$length=0"/>
15466 <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
15467 <xsl:call-template name="chopPunctuation">
15468 <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
15469 <xsl:with-param name="punctuation" select="$punctuation"/>
15470 </xsl:call-template>
15472 <xsl:when test="not($chopString)"/>
15473 <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
15477 <xsl:template name="chopPunctuationFront">
15478 <xsl:param name="chopString"/>
15479 <xsl:variable name="length" select="string-length($chopString)"/>
15481 <xsl:when test="$length=0"/>
15482 <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
15483 <xsl:call-template name="chopPunctuationFront">
15484 <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"/>
15485 </xsl:call-template>
15487 <xsl:when test="not($chopString)"/>
15488 <xsl:otherwise><xsl:value-of select="$chopString"/></xsl:otherwise>
15491 </xsl:stylesheet>$$ WHERE name = 'mods32';
15493 CREATE OR REPLACE FUNCTION biblio.extract_metabib_field_entry ( rid BIGINT, default_joiner TEXT ) RETURNS SETOF metabib.field_entry_template AS $func$
15495 bib biblio.record_entry%ROWTYPE;
15496 idx config.metabib_field%ROWTYPE;
15497 xfrm config.xml_transform%ROWTYPE;
15499 transformed_xml TEXT;
15501 xml_node_list TEXT[];
15507 joiner TEXT := default_joiner; -- XXX will index defs supply a joiner?
15508 authority_text TEXT;
15509 authority_link BIGINT;
15510 output_row metabib.field_entry_template%ROWTYPE;
15513 -- Start out with no field-use bools set
15514 output_row.browse_field = FALSE;
15515 output_row.facet_field = FALSE;
15516 output_row.search_field = FALSE;
15519 SELECT INTO bib * FROM biblio.record_entry WHERE id = rid;
15521 -- Loop over the indexing entries
15522 FOR idx IN SELECT * FROM config.metabib_field ORDER BY format LOOP
15524 joiner := COALESCE(idx.joiner, default_joiner);
15526 SELECT INTO xfrm * from config.xml_transform WHERE name = idx.format;
15528 -- See if we can skip the XSLT ... it's expensive
15529 IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
15530 -- Can't skip the transform
15531 IF xfrm.xslt <> '---' THEN
15532 transformed_xml := oils_xslt_process(bib.marc,xfrm.xslt);
15534 transformed_xml := bib.marc;
15537 prev_xfrm := xfrm.name;
15540 xml_node_list := oils_xpath( idx.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15543 FOR xml_node IN SELECT x FROM unnest(xml_node_list) AS x LOOP
15544 CONTINUE WHEN xml_node !~ E'^\\s*<';
15546 -- XXX much of this should be moved into oils_xpath_string...
15547 curr_text := ARRAY_TO_STRING(evergreen.array_remove_item_by_value(evergreen.array_remove_item_by_value(
15548 oils_xpath( '//text()',
15550 REGEXP_REPLACE( -- This escapes all &s not followed by "amp;". Data ise returned from oils_xpath (above) in UTF-8, not entity encoded
15551 REGEXP_REPLACE( -- This escapes embeded <s
15553 $re$(>[^<]+)(<)([^>]+<)$re$,
15569 CONTINUE WHEN curr_text IS NULL OR curr_text = '';
15571 IF raw_text IS NOT NULL THEN
15572 raw_text := raw_text || joiner;
15575 raw_text := COALESCE(raw_text,'') || curr_text;
15577 -- autosuggest/metabib.browse_entry
15578 IF idx.browse_field THEN
15580 IF idx.browse_xpath IS NOT NULL AND idx.browse_xpath <> '' THEN
15581 browse_text := oils_xpath_string( idx.browse_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15583 browse_text := curr_text;
15586 IF idx.browse_sort_xpath IS NOT NULL AND
15587 idx.browse_sort_xpath <> '' THEN
15589 sort_value := oils_xpath_string(
15590 idx.browse_sort_xpath, xml_node, joiner,
15591 ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
15594 sort_value := browse_text;
15597 output_row.field_class = idx.field_class;
15598 output_row.field = idx.id;
15599 output_row.source = rid;
15600 output_row.value = BTRIM(REGEXP_REPLACE(browse_text, E'\\s+', ' ', 'g'));
15601 output_row.sort_value :=
15602 public.naco_normalize(sort_value);
15604 output_row.authority := NULL;
15606 IF idx.authority_xpath IS NOT NULL AND idx.authority_xpath <> '' THEN
15607 authority_text := oils_xpath_string(
15608 idx.authority_xpath, xml_node, joiner,
15610 ARRAY[xfrm.prefix, xfrm.namespace_uri],
15611 ARRAY['xlink','http://www.w3.org/1999/xlink']
15615 IF authority_text ~ '^\d+$' THEN
15616 authority_link := authority_text::BIGINT;
15617 PERFORM * FROM authority.record_entry WHERE id = authority_link;
15619 output_row.authority := authority_link;
15625 output_row.browse_field = TRUE;
15626 -- Returning browse rows with search_field = true for search+browse
15627 -- configs allows us to retain granularity of being able to search
15628 -- browse fields with "starts with" type operators (for example, for
15629 -- titles of songs in music albums)
15630 IF idx.search_field THEN
15631 output_row.search_field = TRUE;
15633 RETURN NEXT output_row;
15634 output_row.browse_field = FALSE;
15635 output_row.search_field = FALSE;
15636 output_row.sort_value := NULL;
15639 -- insert raw node text for faceting
15640 IF idx.facet_field THEN
15642 IF idx.facet_xpath IS NOT NULL AND idx.facet_xpath <> '' THEN
15643 facet_text := oils_xpath_string( idx.facet_xpath, xml_node, joiner, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]] );
15645 facet_text := curr_text;
15648 output_row.field_class = idx.field_class;
15649 output_row.field = -1 * idx.id;
15650 output_row.source = rid;
15651 output_row.value = BTRIM(REGEXP_REPLACE(facet_text, E'\\s+', ' ', 'g'));
15653 output_row.facet_field = TRUE;
15654 RETURN NEXT output_row;
15655 output_row.facet_field = FALSE;
15660 CONTINUE WHEN raw_text IS NULL OR raw_text = '';
15662 -- insert combined node text for searching
15663 IF idx.search_field THEN
15664 output_row.field_class = idx.field_class;
15665 output_row.field = idx.id;
15666 output_row.source = rid;
15667 output_row.value = BTRIM(REGEXP_REPLACE(raw_text, E'\\s+', ' ', 'g'));
15669 output_row.search_field = TRUE;
15670 RETURN NEXT output_row;
15671 output_row.search_field = FALSE;
15678 $func$ LANGUAGE PLPGSQL;
15681 CREATE OR REPLACE FUNCTION metabib.reingest_metabib_field_entries( bib_id BIGINT, skip_facet BOOL DEFAULT FALSE, skip_browse BOOL DEFAULT FALSE, skip_search BOOL DEFAULT FALSE ) RETURNS VOID AS $func$
15684 ind_data metabib.field_entry_template%ROWTYPE;
15685 mbe_row metabib.browse_entry%ROWTYPE;
15688 b_skip_browse BOOL;
15689 b_skip_search BOOL;
15690 value_prepped TEXT;
15693 SELECT COALESCE(NULLIF(skip_facet, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_facet_indexing' AND enabled)) INTO b_skip_facet;
15694 SELECT COALESCE(NULLIF(skip_browse, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_browse_indexing' AND enabled)) INTO b_skip_browse;
15695 SELECT COALESCE(NULLIF(skip_search, FALSE), EXISTS (SELECT enabled FROM config.internal_flag WHERE name = 'ingest.skip_search_indexing' AND enabled)) INTO b_skip_search;
15697 PERFORM * FROM config.internal_flag WHERE name = 'ingest.assume_inserts_only' AND enabled;
15699 IF NOT b_skip_search THEN
15700 FOR fclass IN SELECT * FROM config.metabib_class LOOP
15701 -- RAISE NOTICE 'Emptying out %', fclass.name;
15702 EXECUTE $$DELETE FROM metabib.$$ || fclass.name || $$_field_entry WHERE source = $$ || bib_id;
15705 IF NOT b_skip_facet THEN
15706 DELETE FROM metabib.facet_entry WHERE source = bib_id;
15708 IF NOT b_skip_browse THEN
15709 DELETE FROM metabib.browse_entry_def_map WHERE source = bib_id;
15713 FOR ind_data IN SELECT * FROM biblio.extract_metabib_field_entry( bib_id ) LOOP
15714 IF ind_data.field < 0 THEN
15715 ind_data.field = -1 * ind_data.field;
15718 IF ind_data.facet_field AND NOT b_skip_facet THEN
15719 INSERT INTO metabib.facet_entry (field, source, value)
15720 VALUES (ind_data.field, ind_data.source, ind_data.value);
15723 IF ind_data.browse_field AND NOT b_skip_browse THEN
15724 -- A caveat about this SELECT: this should take care of replacing
15725 -- old mbe rows when data changes, but not if normalization (by
15726 -- which I mean specifically the output of
15727 -- evergreen.oils_tsearch2()) changes. It may or may not be
15728 -- expensive to add a comparison of index_vector to index_vector
15729 -- to the WHERE clause below.
15731 value_prepped := metabib.browse_normalize(ind_data.value, ind_data.field);
15732 SELECT INTO mbe_row * FROM metabib.browse_entry
15733 WHERE value = value_prepped AND sort_value = ind_data.sort_value;
15736 mbe_id := mbe_row.id;
15738 INSERT INTO metabib.browse_entry
15739 ( value, sort_value ) VALUES
15740 ( value_prepped, ind_data.sort_value );
15742 mbe_id := CURRVAL('metabib.browse_entry_id_seq'::REGCLASS);
15745 INSERT INTO metabib.browse_entry_def_map (entry, def, source, authority)
15746 VALUES (mbe_id, ind_data.field, ind_data.source, ind_data.authority);
15749 IF ind_data.search_field AND NOT b_skip_search THEN
15750 -- Avoid inserting duplicate rows
15751 EXECUTE 'SELECT 1 FROM metabib.' || ind_data.field_class ||
15752 '_field_entry WHERE field = $1 AND source = $2 AND value = $3'
15753 INTO mbe_id USING ind_data.field, ind_data.source, ind_data.value;
15754 -- RAISE NOTICE 'Search for an already matching row returned %', mbe_id;
15755 IF mbe_id IS NULL THEN
15757 INSERT INTO metabib.$$ || ind_data.field_class || $$_field_entry (field, source, value)
15759 quote_literal(ind_data.field) || $$, $$ ||
15760 quote_literal(ind_data.source) || $$, $$ ||
15761 quote_literal(ind_data.value) ||
15768 IF NOT b_skip_search THEN
15769 PERFORM metabib.update_combined_index_vectors(bib_id);
15774 $func$ LANGUAGE PLPGSQL;
15776 -- Don't use Title Proper search field as the browse field
15777 UPDATE config.metabib_field SET browse_field = FALSE, browse_xpath = NULL, browse_sort_xpath = NULL WHERE id = 6;
15779 -- Create a new Title Proper browse config
15780 INSERT INTO config.metabib_field ( id, field_class, name, label, format, xpath, search_field, authority_xpath, browse_field, browse_sort_xpath ) VALUES
15781 (31, 'title', 'browse', oils_i18n_gettext(31, 'Title Proper (Browse)', 'cmf', 'label'), 'mods32', $$//mods32:mods/mods32:titleBrowse$$, FALSE, '//@xlink:href', TRUE, $$*[local-name() != "nonSort"]$$ );
15783 SELECT evergreen.upgrade_deps_block_check('0845', :eg_version);
15785 ALTER FUNCTION metabib.browse_pivot (integer[], text) STABLE;
15786 ALTER FUNCTION metabib.browse_bib_pivot (integer[], text) STABLE;
15787 ALTER FUNCTION metabib.browse_authority_pivot (integer[], text) STABLE;
15788 ALTER FUNCTION metabib.browse_authority_refs_pivot (integer[], text) STABLE;
15791 SELECT evergreen.upgrade_deps_block_check('0846', :eg_version);
15793 CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT, force_add INT ) RETURNS TEXT AS $_$
15796 use MARC::File::XML (BinaryEncoding => 'UTF-8');
15800 MARC::Charset->assume_unicode(1);
15802 my $target_xml = shift;
15803 my $source_xml = shift;
15804 my $field_spec = shift;
15805 my $force_add = shift || 0;
15807 my $target_r = MARC::Record->new_from_xml( $target_xml );
15808 my $source_r = MARC::Record->new_from_xml( $source_xml );
15810 return $target_xml unless ($target_r && $source_r);
15812 my @field_list = split(',', $field_spec);
15815 for my $f (@field_list) {
15816 $f =~ s/^\s*//; $f =~ s/\s*$//;
15817 if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
15823 $match =~ s/^\s*//; $match =~ s/\s*$//;
15824 $fields{$field} = { sf => [ split('', $sf) ] };
15826 my ($msf,$mre) = split('~', $match);
15827 if (length($msf) > 0 and length($mre) > 0) {
15828 $msf =~ s/^\s*//; $msf =~ s/\s*$//;
15829 $mre =~ s/^\s*//; $mre =~ s/\s*$//;
15830 $fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
15836 for my $f ( keys %fields) {
15837 if ( @{$fields{$f}{sf}} ) {
15838 for my $from_field ($source_r->field( $f )) {
15839 my @tos = $target_r->field( $f );
15841 next if (exists($fields{$f}{match}) and !$force_add);
15842 my @new_fields = map { $_->clone } $source_r->field( $f );
15843 $target_r->insert_fields_ordered( @new_fields );
15845 for my $to_field (@tos) {
15846 if (exists($fields{$f}{match})) {
15847 next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
15849 for my $old_sf ($from_field->subfields) {
15850 $to_field->add_subfields( @$old_sf ) if grep(/$$old_sf[0]/,@{$fields{$f}{sf}});
15856 my @new_fields = map { $_->clone } $source_r->field( $f );
15857 $target_r->insert_fields_ordered( @new_fields );
15861 $target_xml = $target_r->as_xml_record;
15862 $target_xml =~ s/^<\?.+?\?>$//mo;
15863 $target_xml =~ s/\n//sgo;
15864 $target_xml =~ s/>\s+</></sgo;
15866 return $target_xml;
15868 $_$ LANGUAGE PLPERLU;
15872 SELECT evergreen.upgrade_deps_block_check('0847', :eg_version);
15874 CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$
15877 main_entry authority.control_set_authority_field%ROWTYPE;
15878 bib_field authority.control_set_bib_field%ROWTYPE;
15879 auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
15881 replace_data XML[] DEFAULT '{}'::XML[];
15882 replace_rules TEXT[] DEFAULT '{}'::TEXT[];
15887 IF auth_id IS NULL THEN
15891 -- Default to the LoC controll set
15892 SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
15894 -- if none, make a best guess
15895 IF cset IS NULL THEN
15896 SELECT control_set INTO cset
15897 FROM authority.control_set_authority_field
15899 SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
15900 FROM authority.record_entry
15906 -- if STILL none, no-op change
15907 IF cset IS NULL THEN
15910 XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
15911 XMLELEMENT( name leader, '00881nam a2200193 4500'),
15914 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
15917 XMLATTRIBUTES('d' AS code),
15924 FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP
15925 auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML);
15926 auth_i1 = (XPATH('@ind1',auth_field[1]))[1];
15927 auth_i2 = (XPATH('@ind2',auth_field[1]))[1];
15928 IF ARRAY_LENGTH(auth_field,1) > 0 THEN
15929 FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
15930 SELECT XMLELEMENT( -- XMLAGG avoids magical <element> creation, but requires unnest subquery
15932 XMLATTRIBUTES(bib_field.tag AS tag, auth_i1 AS ind1, auth_i2 AS ind2),
15934 ) INTO tmp_data FROM UNNEST(XPATH('//*[local-name()="subfield"]', auth_field[1]));
15935 replace_data := replace_data || tmp_data;
15936 replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
15943 SELECT XMLAGG(UNNEST) INTO tmp_data FROM UNNEST(replace_data);
15947 XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
15948 XMLELEMENT( name leader, '00881nam a2200193 4500'),
15952 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
15955 XMLATTRIBUTES('r' AS code),
15956 ARRAY_TO_STRING(replace_rules,',')
15961 $f$ STABLE LANGUAGE PLPGSQL;
15963 SELECT evergreen.upgrade_deps_block_check('0827', :eg_version);
15964 SET CONSTRAINTS ALL IMMEDIATE;
15965 -- otherwise, the ALTER TABLE statement below
15966 -- will fail with pending trigger events.
15967 ALTER TABLE action_trigger.event_definition ADD COLUMN repeat_delay INTERVAL;
15973 \qecho **** Certain improvements in 2.5, particularly browse, require a reingest
15974 \qecho **** of all records. In order to allow this to continue without locking
15975 \qecho **** your entire bibliographic data set, consider generating SQL scripts
15976 \qecho **** with the following queries, then running those via psql:
15978 \qecho **** If you require a more responsive catalog/database while reingesting,
15979 \qecho **** consider adding 'pg_sleep()' calls between each reingest select or
15980 \qecho **** update.
15983 \qecho '\\o /tmp/reingest_2.5_bib_recs.sql'
15984 \qecho 'SELECT ''select metabib.reingest_metabib_field_entries('' || id || '');'' FROM biblio.record_entry WHERE NOT DELETED AND id > 0;'
15986 \qecho '\\o /tmp/reingest_2.5_auth_recs.sql'
15987 \qecho 'SELECT ''-- Grab current setting'';'
15988 \qecho 'SELECT ''\\set force_reingest '' || enabled FROM config.internal_flag WHERE name = ''ingest.reingest.force_on_same_marc'';'
15989 \qecho 'SELECT ''update config.internal_flag set enabled = true where name = ''''ingest.reingest.force_on_same_marc'''';'';'
15990 \qecho 'SELECT ''update authority.record_entry set id = id where id = '' || id || '';'' FROM authority.record_entry WHERE NOT DELETED;'
15991 \qecho 'SELECT ''-- Restore previous setting'';'
15992 \qecho 'SELECT ''update config.internal_flag set enabled = :force_reingest where name = \'\'ingest.reingest.force_on_same_marc\'\';'';'