2 # Extract MARC fields from XML
3 # get_marc_attrs( { marc_xml => doc } )
7 FOR isbn IN xml.findnodes('//*[@tag="020"]/*[@code="a"]');
8 args.isbns.push(isbn.textContent);
11 FOR upc IN xml.findnodes('//*[@tag="024"]/*[@code="a"]');
12 args.upcs.push(upc.textContent);
14 args.upc = args.upcs.0; # use first UPC as the default
15 args.issn = xml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
16 args.title = xml.findnodes('//*[@tag="245"]/*[@code="a"]').textContent;
17 args.title_extended = xml.findnodes('//*[@tag="245"]').textContent;
18 args.author = xml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
19 args.publisher = xml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
20 args.pubdate = xml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
21 args.summary = xml.findnodes('//*[@tag="520"]/*[@code="a"]').textContent;
22 args.edition = xml.findnodes('//*[@tag="250"]/*[@code="a"]').textContent ||
23 xml.findnodes('//*[@tag="534"]/*[@code="b"]').textContent ||
24 xml.findnodes('//*[@tag="775"]/*[@code="b"]').textContent;
26 '//*[@tag="300"]/*[@code="a" or @code="b" or @code="c" or @code="e"]'
29 FOR p IN phys; phys_content.push(p.textContent); END;
30 args.phys_desc = phys_content.join("");
32 args.contents = xml.findnodes('//*[@tag="505"]').textContent;
35 args.marc_cn = xml.findnodes('//*[@tag="092" or @tag="099"]/*').textContent;
38 args.isbn_clean = args.isbns.0.replace('\ .*', '');
40 # Extract the 856 URLs that are not otherwise represented by asset.uri's
42 FOR node IN xml.findnodes('//*[@tag="856" and @ind1="4" and (@ind2="0" or @ind2="1")]');
43 IF node.findnodes('./*[@code="9" or @code="w" or @code="n"]'); NEXT; END; # asset.uri's
44 label = node.findnodes('./*[@code="y"]');
45 notes = node.findnodes('./*[@code="z" or @code="3"]');
46 FOR href IN node.findnodes('./*[@code="u"]');
48 # it's possible for multiple $u's to exist within 1 856 tag.
49 # in that case, honor the label/notes data for the first $u, but
50 # leave any subsequent $u's as unadorned href's.
51 # use href/link/note keys to be consistent with args.uri's
52 args.online_res.push({
53 href => href.textContent,
54 link => (loop.first AND label) ? label.textContent : href.textContent,
55 note => (loop.first) ? notes.textContent : ''
64 # we use $9 of ISBN and ISSN as a flag for e-version
65 sfx_isbn = xml.findnodes('//*[@tag="020"]/*[@code="9"]');
67 IF sfx_isbn.textContent == "SFX";
68 my_parent = sfx_isbn.parentNode();
69 sfx_isbn = my_parent.findnodes('./*[@code="a"]').textContent;
70 sfx_isbn = sfx_isbn.replace('-', '');
71 args.resolver_isbn = sfx_isbn.replace('\ .*', '');
75 sfx_issn = xml.findnodes('//*[@tag="022"]/*[@code="9"]');
77 IF sfx_issn.textContent == "SFX";
78 my_parent = sfx_issn.parentNode();
79 sfx_issn = my_parent.findnodes('./*[@code="a"]');
81 sfx_issn.textContent.replace('[^\d\-X]', '')
86 # we snag all issns if no SFX available
87 IF args.issns.size == 0;
88 FOR rawissn IN xml.findnodes('//*[@tag="022"]/*[@code="a"]');
90 rawissn.textContent.replace('[^\d\-X]', '')
95 FOR volume IN xml.findnodes('//*[local-name()="volumes"]/*[local-name()="volume"]');
97 # Check volume visibility - could push this into XPath
98 vol.label = volume.getAttribute('label');
100 # Prepend prefix, if any
101 prefix = volume.findnodes('./*[local-name()="call_number_prefix"][@ident!="-1"]');
102 IF prefix.getAttribute('label') != '';
103 vol.label = prefix.getAttribute('label') _ " " _ vol.label;
106 # Append prefix, if any
107 suffix = volume.findnodes('./*[local-name()="call_number_suffix"][@ident!="-1"]');
108 IF suffix.getAttribute('label') != '';
109 vol.label = vol.label _ " " _ suffix.getAttribute('label');
112 vol.id = volume.getAttribute('id');
113 NEXT IF volume.getAttribute('opac_visible') == 'false';
114 NEXT IF volume.getAttribute('deleted') == 'true';
116 IF vol.label == '##URI##';
117 FOR uri IN volume.findnodes('./*[local-name()="uris"]/*[local-name()="uri"]');
118 res.href = uri.getAttribute('href');
119 res.link = uri.getAttribute('label');
120 res.note = uri.getAttribute('use_restriction');
125 copies = volume.findnodes('./*[local-name()="copies"]/*[local-name()="copy"]');
127 # Check copy visibility
128 cp.deleted = copy.getAttribute('deleted');
129 cp.visible = copy.getAttribute('opac_visible');
130 NEXT IF (cp.deleted == 'true' OR cp.visible == 'false');
132 # Iterate through all of the children to determine visibility
133 FOR node IN cp.childNodes;
134 NEXT IF cp.visible == 'false';
135 vis = node.getAttribute('opac_visible');
136 del = node.getAttribute('deleted');
137 IF vis == 'false' or del == 'true';
138 cp.visible = 'false';
142 NEXT IF cp.visible == 'false';
144 loc = copy.findnodes('./*[local-name()="location"]');
145 circlib = copy.findnodes('./*[local-name()="circlib"]');
146 status = copy.findnodes('./*[local-name()="status"]');
150 location => loc.textContent,
151 library => circlib.textContent,
152 status => status.textContent
153 barcode => copy.getAttribute('barcode')
155 args.holdings.push(holding);
160 # Extract the copy count summary
161 count_type = (ctx.is_staff) ? 'staff' : 'public';
162 xpath = '//*[local-name()="counts"]/*[local-name()="count"][@type="' _ count_type _ '"]';
163 FOR node IN xml.findnodes(xpath);
164 args.copy_counts = {};
165 FOR attr IN ['count', 'available', 'unshadow', 'transcendant'];
166 args.copy_counts.$attr = node.getAttribute(attr);
170 # "mattype" == "custom marc format specifier"
171 FOR icon_style IN ['mattype', 'item_type'];
172 node = xml.findnodes(
173 '//*[local-name()="attributes"]/*[local-name()="field"][@name="' _ icon_style _ '"]');
174 IF node AND node.textContent;
175 args.format_label = node.getAttribute('coded-value')
176 args.format_icon = ctx.media_prefix _ '/images/format_icons/' _ icon_style _ '/' _ node.textContent _ '.png';