mods 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +24 -0
  3. data/.gitignore +1 -0
  4. data/Gemfile +0 -4
  5. data/README.md +1 -3
  6. data/lib/mods/date.rb +51 -17
  7. data/lib/mods/marc_country_codes.rb +12 -10
  8. data/lib/mods/nom_terminology.rb +110 -849
  9. data/lib/mods/reader.rb +9 -39
  10. data/lib/mods/record.rb +13 -28
  11. data/lib/mods/version.rb +1 -1
  12. data/mods.gemspec +3 -3
  13. data/spec/fixture_data/hp566jq8781.xml +334 -0
  14. data/spec/integration/parker_spec.rb +217 -0
  15. data/spec/{date_spec.rb → lib/date_spec.rb} +8 -1
  16. data/spec/lib/language_spec.rb +123 -0
  17. data/spec/lib/location_spec.rb +175 -0
  18. data/spec/lib/name_spec.rb +368 -0
  19. data/spec/lib/origin_info_spec.rb +134 -0
  20. data/spec/lib/part_spec.rb +162 -0
  21. data/spec/lib/physical_description_spec.rb +72 -0
  22. data/spec/{reader_spec.rb → lib/reader_spec.rb} +1 -41
  23. data/spec/lib/record_info_spec.rb +114 -0
  24. data/spec/lib/record_spec.rb +287 -0
  25. data/spec/lib/related_item_spec.rb +124 -0
  26. data/spec/lib/subject_spec.rb +427 -0
  27. data/spec/lib/title_spec.rb +108 -0
  28. data/spec/lib/top_level_elmnts_simple_spec.rb +169 -0
  29. data/spec/spec_helper.rb +87 -6
  30. data/spec/support/fixtures.rb +9 -0
  31. metadata +61 -43
  32. data/.coveralls.yml +0 -1
  33. data/.travis.yml +0 -6
  34. data/spec/language_spec.rb +0 -118
  35. data/spec/location_spec.rb +0 -295
  36. data/spec/name_spec.rb +0 -759
  37. data/spec/origin_info_spec.rb +0 -447
  38. data/spec/part_spec.rb +0 -471
  39. data/spec/physical_description_spec.rb +0 -144
  40. data/spec/record_info_spec.rb +0 -493
  41. data/spec/record_spec.rb +0 -356
  42. data/spec/related_item_spec.rb +0 -305
  43. data/spec/subject_spec.rb +0 -809
  44. data/spec/title_spec.rb +0 -226
  45. data/spec/top_level_elmnts_simple_spec.rb +0 -369
@@ -3,10 +3,7 @@ module Mods
3
3
  # from: http://www.loc.gov/standards/mods/v3/mods-userguide-generalapp.html
4
4
 
5
5
  # Nokogiri 1.6.6 introduced lang as a built-in attribute
6
- LANG_ATTRIBS = (Nokogiri::VERSION < "1.6.6") ?
7
- ['script', 'transliteration', 'lang'] :
8
- ['script', 'transliteration']
9
-
6
+ LANG_ATTRIBS = ['script', 'transliteration']
10
7
  LINKING_ATTRIBS = ['xlink', 'ID']
11
8
 
12
9
  DATE_ATTRIBS = ['encoding', 'point', 'keyDate', 'qualifier']
@@ -19,6 +16,13 @@ module Mods
19
16
 
20
17
  class Record
21
18
 
19
+ def with_attributes(element, attributes = [], method_mappings: { 'type' => 'type_at', 'ID' => 'id_at' })
20
+ attributes.each do |attr_name|
21
+ attr_method = method_mappings.fetch(attr_name, attr_name)
22
+ element.send attr_method, path: "@#{attr_name}", accessor: lambda { |a| a.text }
23
+ end
24
+ end
25
+
22
26
  # set the NOM terminology; WITH namespaces
23
27
  # NOTES:
24
28
  # 1. certain words, such as 'type' 'name' 'description' are reserved words in jruby or nokogiri
@@ -30,80 +34,47 @@ module Mods
30
34
  def set_terminology_ns(mods_ng_xml)
31
35
  mods_ng_xml.set_terminology(:namespaces => { 'm' => Mods::MODS_NS }) do |t|
32
36
 
33
- # FIXME: may want to deal with camelcase vs. underscore in method_missing
34
-
35
37
  # ABSTRACT -------------------------------------------------------------------------------
36
38
  t.abstract :path => '/m:mods/m:abstract'
37
39
  t._abstract :path => '//m:abstract' do |n|
38
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
39
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
40
- Mods::LANG_ATTRIBS.each { |attr_name|
41
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
42
- }
40
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel type])
43
41
  end
44
42
 
45
43
  # ACCESS_CONDITION -----------------------------------------------------------------------
46
44
  t.accessCondition :path => '/m:mods/m:accessCondition'
47
45
  t._accessCondition :path => '//m:accessCondition' do |n|
48
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
49
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
50
- Mods::LANG_ATTRIBS.each { |attr_name|
51
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
52
- }
46
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel type])
53
47
  end
54
48
 
55
49
  # CLASSIFICATION -------------------------------------------------------------------------
56
50
  t.classification :path => '/m:mods/m:classification'
57
51
  t._classification :path => '//m:classification' do |n|
58
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
59
- n.edition :path => '@edition', :accessor => lambda { |a| a.text }
60
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
61
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
62
- }
63
- Mods::LANG_ATTRIBS.each { |attr_name|
64
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
65
- }
52
+ with_attributes(n, Mods::AUTHORITY_ATTRIBS | Mods::LANG_ATTRIBS | %w[displayLabel edition])
66
53
  end
67
54
 
68
55
  # EXTENSION ------------------------------------------------------------------------------
69
56
  t.extension :path => '/m:mods/m:extension'
70
57
  t._extension :path => '//m:extension' do |n|
71
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
58
+ with_attributes(n, %w[displayLabel])
72
59
  end
73
60
 
74
61
  # GENRE ----------------------------------------------------------------------------------
75
62
  t.genre :path => '/m:mods/m:genre'
76
63
  t._genre :path => '//m:genre' do |n|
77
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
78
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
79
- n.usage :path => '@usage', :accessor => lambda { |a| a.text }
80
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
81
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
82
- }
83
- Mods::LANG_ATTRIBS.each { |attr_name|
84
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
85
- }
64
+ with_attributes(n, Mods::AUTHORITY_ATTRIBS | Mods::LANG_ATTRIBS | %w[displayLabel type usage])
86
65
  end
87
66
 
88
67
  # IDENTIIER ------------------------------------------------------------------------------
89
68
  t.identifier :path => '/m:mods/m:identifier'
90
69
  t._identifier :path => '//m:identifier' do |n|
91
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
92
- n.invalid :path => '@invalid', :accessor => lambda { |a| a.text }
93
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
94
- Mods::LANG_ATTRIBS.each { |attr_name|
95
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
96
- }
70
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel type invalid])
97
71
  end
98
72
 
99
73
  # LANGUAGE -------------------------------------------------------------------------------
100
74
  t.language :path => '/m:mods/m:language'
101
75
  t._language :path => '//m:language' do |n|
102
76
  # attributes
103
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
104
- Mods::LANG_ATTRIBS.each { |attr_name|
105
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
106
- }
77
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel])
107
78
  # child elements
108
79
  n.languageTerm :path => 'm:languageTerm'
109
80
  n.code_term :path => 'm:languageTerm[@type="code"]'
@@ -111,102 +82,97 @@ module Mods
111
82
  n.scriptTerm :path => 'm:scriptTerm'
112
83
  end
113
84
  t._languageTerm :path => '//m:languageTerm' do |lt|
114
- lt.type_at :path => '@type', :accessor => lambda { |a| a.text }
115
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
116
- lt.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
117
- }
85
+ with_attributes(lt, Mods::AUTHORITY_ATTRIBS | %w[type])
118
86
  end # t.language
119
87
 
120
88
  # LOCATION -------------------------------------------------------------------------------
121
89
  t.location :path => '/m:mods/m:location'
122
90
  t._location :path => '//m:location' do |n|
123
91
  # attributes
124
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
125
- Mods::LANG_ATTRIBS.each { |attr_name|
126
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
127
- }
92
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel])
128
93
  # child elements
129
94
  n.physicalLocation :path => 'm:physicalLocation' do |e|
130
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
131
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
132
- e.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
133
- }
95
+ with_attributes(e, Mods::AUTHORITY_ATTRIBS | %w[displayLabel type])
134
96
  end
135
97
  n.shelfLocator :path => 'm:shelfLocator'
136
98
  n.url :path => 'm:url' do |e|
137
- e.dateLastAccessed :path => '@dateLastAccessed', :accessor => lambda { |a| a.text }
138
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
139
- e.note :path => '@note', :accessor => lambda { |a| a.text }
140
- e.access :path => '@access', :accessor => lambda { |a| a.text }
141
- e.usage :path => '@usage', :accessor => lambda { |a| a.text }
99
+ with_attributes(e, %w[dateLastAccessed displayLabel note access usage])
100
+ end
101
+ n.holdingSimple :path => 'm:holdingSimple' do |h|
102
+ h.copyInformation path: 'm:copyInformation' do |c|
103
+ c.form path: 'm:form' do |f|
104
+ with_attributes(f, Mods::LANG_ATTRIBS | %w[type])
105
+ end
106
+ c.sub_location path: 'm:subLocation' do |s|
107
+ with_attributes(s, Mods::LANG_ATTRIBS)
108
+ end
109
+
110
+ c.shelf_locator path: 'm:shelfLocator' do |s|
111
+ with_attributes(s, Mods::LANG_ATTRIBS)
112
+ end
113
+ c.electronic_locator path: 'm:electronicLocator'
114
+ c.note path: 'm:note' do |note|
115
+ with_attributes(note, Mods::LANG_ATTRIBS | %w[displayLabel type])
116
+ end
117
+ c.enumeration_and_chronology path: 'm:enumerationAndChronology' do |e|
118
+ with_attributes(e, Mods::LANG_ATTRIBS | %w[unitType])
119
+ end
120
+ c.item_identifier path: 'm:itemIdentifier' do |i|
121
+ with_attributes(i, %w[type])
122
+ end
123
+ end
142
124
  end
143
- n.holdingSimple :path => 'm:holdingSimple'
144
125
  n.holdingExternal :path => 'm:holdingExternal'
145
126
  end # t.location
146
127
 
147
128
  # NAME ------------------------------------------------------------------------------------
148
129
  t.plain_name :path => '/m:mods/m:name'
149
- t._plain_name :path => '//m:name' do |n|
150
- Mods::Name::ATTRIBUTES.each { |attr_name|
151
- if attr_name != 'type'
152
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
153
- else
154
- n.type_at :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
155
- end
156
- }
130
+ t._plain_name :path => '(//m:name|//m:alternativeName)' do |n|
131
+ with_attributes(n, Mods::Name::ATTRIBUTES)
157
132
  # elements
158
133
  n.namePart :path => 'm:namePart' do |np|
159
- np.type_at :path => '@type', :accessor => lambda { |a| a.text }
134
+ with_attributes(np, %w[type])
160
135
  end
161
136
  n.family_name :path => 'm:namePart[@type="family"]'
162
137
  n.given_name :path => 'm:namePart[@type="given"]'
163
138
  n.termsOfAddress :path => 'm:namePart[@type="termsOfAddress"]'
164
139
  n.date :path => 'm:namePart[@type="date"]'
165
140
 
141
+ n.alternative_name :path => 'm:alternativeName' do |alt|
142
+ with_attributes(alt, %w[altType])
143
+ end
166
144
  n.displayForm :path => 'm:displayForm'
167
145
  n.affiliation :path => 'm:affiliation'
168
146
  n.description_el :path => 'm:description' # description is used by Nokogiri
169
147
  n.role :path => 'm:role' do |r|
170
148
  r.roleTerm :path => 'm:roleTerm' do |rt|
171
- rt.type_at :path => "@type", :accessor => lambda { |a| a.text }
172
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
173
- rt.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
174
- }
149
+ with_attributes(rt, Mods::AUTHORITY_ATTRIBS | %w[type])
150
+
151
+ rt.value path: '.', single: true, accessor: (lambda do |roleTerm|
152
+ text = roleTerm.text.strip
153
+
154
+ if roleTerm.type_at == 'code' && roleTerm.authority == 'marcrelator'
155
+ MARC_RELATOR.fetch(text, text)
156
+ else
157
+ text
158
+ end
159
+ end)
175
160
  end
161
+
176
162
  # role convenience method
177
163
  r.authority :path => '.', :accessor => lambda { |role_node|
178
- a = nil
179
- role_node.roleTerm.each { |role_t|
180
- # role_t.authority will be [] if it is missing from an earlier roleTerm
181
- if role_t.authority && (!a || a.size == 0)
182
- a = role_t.authority
183
- end
184
- }
185
- a
164
+ role_node.roleTerm.authority.first
186
165
  }
166
+
187
167
  # role convenience method
188
168
  r.code :path => '.', :accessor => lambda { |role_node|
189
- c = nil
190
- role_node.roleTerm.each { |role_t|
191
- if role_t.type_at == 'code'
192
- c ||= role_t.text
193
- end
194
- }
195
- c
169
+ role_node.roleTerm.select { |role_t| role_t.type_at == 'code' }.first&.text
196
170
  }
171
+
197
172
  # role convenience method
198
173
  r.value :path => '.', :accessor => lambda { |role_node|
199
- val = nil
200
- role_node.roleTerm.each { |role_t|
201
- if role_t.type_at == 'text'
202
- val ||= role_t.text
203
- end
204
- }
205
- # FIXME: this is broken if there are multiple role codes and some of them are not marcrelator
206
- if !val && role_node.code && role_node.authority.first =~ /marcrelator/
207
- val = MARC_RELATOR[role_node.code.first]
208
- end
209
- val
174
+ val = role_node.roleTerm.select { |role_t| role_t.type_at == 'text' }.first&.text
175
+ val || role_node.roleTerm.select { |role_t| role_t.type_at == 'code' && role_t.authority.match?(/marcrelator/) }.first&.value
210
176
  }
211
177
  end # role node
212
178
 
@@ -274,12 +240,7 @@ module Mods
274
240
  # NOTE ---------------------------------------------------------------------------------
275
241
  t.note :path => '/m:mods/m:note'
276
242
  t._note :path => '//m:note' do |n|
277
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
278
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
279
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
280
- Mods::LANG_ATTRIBS.each { |attr_name|
281
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
282
- }
243
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[ID displayLabel type])
283
244
  end
284
245
 
285
246
  # ORIGIN_INFO --------------------------------------------------------------------------
@@ -287,38 +248,27 @@ module Mods
287
248
  t._origin_info :path => '//m:originInfo' do |n|
288
249
  n.as_object :path => '.', :accessor => lambda { |a| Mods::OriginInfo.new(a) }
289
250
  # attributes
290
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
291
- Mods::LANG_ATTRIBS.each { |attr_name|
292
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
293
- }
251
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel])
294
252
  # child elements
295
253
  n.place :path => 'm:place' do |e|
296
254
  e.placeTerm :path => 'm:placeTerm' do |ee|
297
- ee.type_at :path => '@type', :accessor => lambda { |a| a.text }
298
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
299
- ee.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
300
- }
255
+ with_attributes(ee, Mods::AUTHORITY_ATTRIBS | %w[type])
301
256
  end
302
257
  end
303
258
  n.publisher :path => 'm:publisher'
304
259
  Mods::OriginInfo::DATE_ELEMENTS.each { |date_el|
305
260
  n.send date_el, :path => "m:#{date_el}" do |d|
306
- d.as_object :path => '.', :accessor => lambda { |a| Mods::Date.from_element(a) }
261
+ d.as_object :path => '.', :single => true, :accessor => lambda { |a| Mods::Date.from_element(a) }
307
262
 
308
- Mods::DATE_ATTRIBS.each { |attr_name|
309
- d.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
310
- }
311
- if date_el == 'dateOther'
312
- d.type_at :path => '@type', :accessor => lambda { |a| a.text }
313
- end
263
+ with_attributes(d, Mods::DATE_ATTRIBS)
264
+
265
+ with_attributes(d, %w[type]) if date_el == 'dateOther'
314
266
  end
315
267
  }
316
268
  n.edition :path => 'm:edition'
317
269
  n.issuance :path => 'm:issuance'
318
270
  n.frequency :path => 'm:frequency' do |f|
319
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
320
- f.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
321
- }
271
+ with_attributes(f, Mods::AUTHORITY_ATTRIBS)
322
272
  end
323
273
  end # t.origin_info
324
274
 
@@ -326,18 +276,11 @@ module Mods
326
276
  t.part :path => '/m:mods/m:part'
327
277
  t._part :path => '//m:part' do |n|
328
278
  # attributes
329
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
330
- n.order :path => '@order', :accessor => lambda { |a| a.text }
331
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
332
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
333
- Mods::LANG_ATTRIBS.each { |attr_name|
334
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
335
- }
279
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[ID order type displayLabel])
336
280
  # child elements
337
281
  n.detail :path => 'm:detail' do |e|
338
282
  # attributes
339
- e.level :path => '@level', :accessor => lambda { |a| a.text }
340
- e.type_at :path => '@type', :accessor => lambda { |a| a.text }
283
+ with_attributes(e, %w[level type])
341
284
  # elements
342
285
  e.number :path => 'm:number'
343
286
  e.caption :path => 'm:caption'
@@ -345,7 +288,7 @@ module Mods
345
288
  end
346
289
  n.extent :path => 'm:extent' do |e| # TODO: extent is ordered in xml schema
347
290
  # attributes
348
- e.unit :path => '@unit', :accessor => lambda { |a| a.text }
291
+ with_attributes(e, %w[unit])
349
292
  # elements
350
293
  e.start :path => 'm:start'
351
294
  e.end :path => 'm:end'
@@ -353,13 +296,10 @@ module Mods
353
296
  e.list :path => 'm:list'
354
297
  end
355
298
  n.date :path => 'm:date' do |e|
356
- Mods::DATE_ATTRIBS.reject { |a| a == 'keyDate' }.each { |attr_name|
357
- e.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
358
- }
299
+ with_attributes(e, Mods::DATE_ATTRIBS - ['keyDate'])
359
300
  end
360
301
  n.text_el :path => 'm:text' do |e|
361
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
362
- e.type_at :path => '@type', :accessor => lambda { |a| a.text }
302
+ with_attributes(e, %w[displayLabel type])
363
303
  end
364
304
  end # t._part
365
305
 
@@ -367,23 +307,16 @@ module Mods
367
307
  t.physical_description :path => '/m:mods/m:physicalDescription'
368
308
  t._physical_description :path => '//m:physicalDescription' do |n|
369
309
  # attributes
370
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
371
- Mods::LANG_ATTRIBS.each { |attr_name|
372
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
373
- }
310
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel])
374
311
  # child elements
375
312
  n.digitalOrigin :path => 'm:digitalOrigin'
376
313
  n.extent :path => 'm:extent'
377
314
  n.form :path => 'm:form' do |f|
378
- f.type_at :path => '@type', :accessor => lambda { |a| a.text }
379
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
380
- f.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
381
- }
315
+ with_attributes(f, Mods::AUTHORITY_ATTRIBS | %w[type])
382
316
  end
383
317
  n.internetMediaType :path => 'm:internetMediaType'
384
318
  n.note :path => 'm:note' do |nn|
385
- nn.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
386
- nn.type_at :path => '@type', :accessor => lambda { |a| a.text }
319
+ with_attributes(nn, %w[displayLabel type])
387
320
  end
388
321
  n.reformattingQuality :path => 'm:reformattingQuality'
389
322
  end
@@ -392,52 +325,37 @@ module Mods
392
325
  t.record_info :path => '/m:mods/m:recordInfo'
393
326
  t._record_info :path => '//m:recordInfo' do |n|
394
327
  # attributes
395
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
396
- Mods::LANG_ATTRIBS.each { |attr_name|
397
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
398
- }
328
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel])
399
329
  # child elements
400
330
  n.recordContentSource :path => 'm:recordContentSource' do |r|
401
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
402
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
403
- }
331
+ with_attributes(r, Mods::AUTHORITY_ATTRIBS)
404
332
  end
405
333
  n.recordCreationDate :path => 'm:recordCreationDate' do |r|
406
- Mods::DATE_ATTRIBS.each { |attr_name|
407
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
408
- }
334
+ with_attributes(r, Mods::DATE_ATTRIBS)
409
335
  end
410
336
  n.recordChangeDate :path => 'm:recordChangeDate' do |r|
411
- Mods::DATE_ATTRIBS.each { |attr_name|
412
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
413
- }
337
+ with_attributes(r, Mods::DATE_ATTRIBS)
414
338
  end
415
339
  n.recordIdentifier :path => 'm:recordIdentifier' do |r|
416
- r.source :path => '@source', :accessor => lambda { |a| a.text }
340
+ with_attributes(r, ['source'])
417
341
  end
418
342
  n.recordOrigin :path => 'm:recordOrigin'
419
343
  n.languageOfCataloging :path => 'm:languageOfCataloging' do |r|
420
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
421
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
422
- }
344
+ with_attributes(r, Mods::AUTHORITY_ATTRIBS)
423
345
  r.languageTerm :path => 'm:languageTerm'
424
346
  r.scriptTerm :path => 'm:scriptTerm'
425
347
  end
426
348
  n.descriptionStandard :path => 'm:descriptionStandard' do |r|
427
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
428
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
429
- }
349
+ with_attributes(r, Mods::AUTHORITY_ATTRIBS)
430
350
  end
431
351
  end # t._record_info
432
352
 
433
353
  # RELATED_ITEM-------------------------------------------------------------------------
434
354
  t.related_item :path => '/m:mods/m:relatedItem' do |n|
435
355
  # attributes
436
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
437
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
438
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
356
+ with_attributes(n, %w[ID displayLabel type])
439
357
  # elements
440
- n.abstract :path => 'abstract'
358
+ n.abstract :path => 'm:abstract'
441
359
  n.accessCondition :path => 'm:accessCondition'
442
360
  n.classification :path => 'm:classification'
443
361
  n.extension :path => 'm:extension'
@@ -465,13 +383,7 @@ module Mods
465
383
  t.subject :path => '/m:mods/m:subject'
466
384
  t._subject :path => '//m:subject' do |n|
467
385
  # attributes
468
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
469
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
470
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
471
- }
472
- Mods::LANG_ATTRIBS.each { |attr_name|
473
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
474
- }
386
+ with_attributes(n, Mods::AUTHORITY_ATTRIBS | Mods::LANG_ATTRIBS | %w[displayLabel])
475
387
  # child elements
476
388
  n.cartographics :path => 'm:cartographics' do |n1|
477
389
  n1.scale :path => 'm:scale'
@@ -482,19 +394,13 @@ module Mods
482
394
  }
483
395
  end
484
396
  n.genre :path => 'm:genre' do |n1|
485
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
486
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
487
- }
397
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS)
488
398
  end
489
399
  n.geographic :path => 'm:geographic' do |n1|
490
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
491
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
492
- }
400
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS)
493
401
  end
494
402
  n.geographicCode :path => 'm:geographicCode' do |gc|
495
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
496
- gc.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
497
- }
403
+ with_attributes(gc, Mods::AUTHORITY_ATTRIBS)
498
404
  # convenience method
499
405
  gc.translated_value :path => '.', :accessor => lambda { |gc_node|
500
406
  code_val ||= gc_node.text
@@ -514,78 +420,45 @@ module Mods
514
420
  Mods::Subject::HIER_GEO_CHILD_ELEMENTS.each { |elname|
515
421
  n1.send elname, :path => "m:#{elname}"
516
422
  }
517
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
518
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
519
- }
423
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS)
520
424
  end
521
425
  # Note: 'name' is used by Nokogiri
522
426
  n.name_el :path => 'm:name' do |t1|
523
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
524
- t1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
525
- }
427
+ with_attributes(t1, Mods::AUTHORITY_ATTRIBS)
526
428
  end
527
429
  n.personal_name :path => 'm:name[@type="personal"]'
528
430
  n.corporate_name :path => 'm:name[@type="corporate"]'
529
431
  n.conference_name :path => 'm:name[@type="conference"]'
530
432
  n.occupation :path => 'm:occupation' do |n1|
531
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
532
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
533
- }
433
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS)
534
434
  end
535
435
  n.temporal :path => 'm:temporal' do |n1|
536
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
537
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
538
- }
539
- # date attributes as attributes
540
- Mods::DATE_ATTRIBS.each { |attr_name|
541
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
542
- }
436
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS | Mods::DATE_ATTRIBS)
543
437
  end
544
438
  n.titleInfo :path => 'm:titleInfo' do |t1|
545
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
546
- t1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
547
- }
439
+ with_attributes(t1, Mods::AUTHORITY_ATTRIBS)
548
440
  end
549
441
  n.topic :path => 'm:topic' do |n1|
550
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
551
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
552
- }
442
+ with_attributes(n1, Mods::AUTHORITY_ATTRIBS)
553
443
  end
554
444
  end # t.subject
555
445
 
556
446
  # TABLE_OF_CONTENTS ---------------------------------------------------------------------
557
447
  t.tableOfContents :path => '/m:mods/m:tableOfContents'
558
448
  t._tableOfContents :path => '//m:tableOfContents' do |n|
559
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
560
- n.shareable :path => '@shareable', :accessor => lambda { |a| a.text }
561
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
562
- Mods::LANG_ATTRIBS.each { |attr_name|
563
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
564
- }
449
+ with_attributes(n, Mods::LANG_ATTRIBS | %w[displayLabel shareable type])
565
450
  end
566
451
 
567
452
  # TARGET_AUDIENCE -----------------------------------------------------------------------
568
453
  t.targetAudience :path => '/m:mods/m:targetAudience'
569
454
  t._targetAudience :path => '//m:targetAudience' do |n|
570
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
571
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
572
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
573
- }
574
- Mods::LANG_ATTRIBS.each { |attr_name|
575
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
576
- }
455
+ with_attributes(n, Mods::AUTHORITY_ATTRIBS | Mods::LANG_ATTRIBS | %w[displayLabel])
577
456
  end
578
457
 
579
458
  # TITLE_INFO ----------------------------------------------------------------------------
580
459
  t.title_info :path => '/m:mods/m:titleInfo'
581
460
  t._title_info :path => '//m:titleInfo' do |n|
582
- Mods::TitleInfo::ATTRIBUTES.each { |attr_name|
583
- if attr_name != 'type'
584
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
585
- else
586
- n.type_at :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
587
- end
588
- }
461
+ with_attributes(n, Mods::TitleInfo::ATTRIBUTES)
589
462
  n.title :path => 'm:title'
590
463
  n.subTitle :path => 'm:subTitle'
591
464
  n.nonSort :path => 'm:nonSort'
@@ -623,624 +496,12 @@ module Mods
623
496
  # TYPE_OF_RESOURCE --------------------------------------------------------------------
624
497
  t.typeOfResource :path => '/m:mods/m:typeOfResource'
625
498
  t._typeOfResource :path => '//m:typeOfResource' do |n|
626
- n.collection :path => '@collection', :accessor => lambda { |a| a.text }
627
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
628
- n.manuscript :path => '@manuscript', :accessor => lambda { |a| a.text }
629
- n.usage :path => '@usage', :accessor => lambda { |a| a.text }
499
+ with_attributes(n, %w[collection displayLabel manuscript usage])
630
500
  end
631
-
632
- end # terminology
501
+ end
633
502
 
634
503
  mods_ng_xml.nom!
635
504
  mods_ng_xml
636
- end # set_terminology_ns
637
-
638
- # set the NOM terminology; do NOT use namespaces
639
- # NOTES:
640
- # 1. certain words, such as 'type' 'name' 'description' are reserved words in jruby or nokogiri
641
- # when the terminology would use these words, a suffix of '_at' is added if it is an attribute,
642
- # (e.g. 'type_at' for @type) and a suffix of '_el' is added if it is an element.
643
- # 2. the underscore prefix variant terms are a way of making subterms for a node available
644
- # to any instance of said node and are not intended to be used externally
645
- # @param mods_ng_xml a Nokogiri::Xml::Document object containing MODS (without namespaces)
646
- def set_terminology_no_ns(mods_ng_xml)
647
- mods_ng_xml.set_terminology() do |t|
648
-
649
- # FIXME: may want to deal with camelcase vs. underscore in method_missing
650
-
651
- # ABSTRACT -------------------------------------------------------------------------------
652
- t.abstract :path => '/mods/abstract'
653
- t._abstract :path => '//abstract' do |n|
654
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
655
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
656
- Mods::LANG_ATTRIBS.each { |attr_name|
657
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
658
- }
659
- end
660
-
661
- # ACCESS_CONDITION -----------------------------------------------------------------------
662
- t.accessCondition :path => '/mods/accessCondition'
663
- t._accessCondition :path => '//accessCondition' do |n|
664
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
665
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
666
- Mods::LANG_ATTRIBS.each { |attr_name|
667
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
668
- }
669
- end
670
-
671
- # CLASSIFICATION -------------------------------------------------------------------------
672
- t.classification :path => '/mods/classification'
673
- t._classification :path => '//classification' do |n|
674
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
675
- n.edition :path => '@edition', :accessor => lambda { |a| a.text }
676
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
677
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
678
- }
679
- Mods::LANG_ATTRIBS.each { |attr_name|
680
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
681
- }
682
- end
683
-
684
- # EXTENSION ------------------------------------------------------------------------------
685
- t.extension :path => '/mods/extension'
686
- t._extension :path => '//extension' do |n|
687
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
688
- end
689
-
690
- # GENRE ----------------------------------------------------------------------------------
691
- t.genre :path => '/mods/genre'
692
- t._genre :path => '//genre' do |n|
693
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
694
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
695
- n.usage :path => '@usage', :accessor => lambda { |a| a.text }
696
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
697
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
698
- }
699
- Mods::LANG_ATTRIBS.each { |attr_name|
700
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
701
- }
702
- end
703
-
704
- # IDENTIIER ------------------------------------------------------------------------------
705
- t.identifier :path => '/mods/identifier'
706
- t._identifier :path => '//identifier' do |n|
707
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
708
- n.invalid :path => '@invalid', :accessor => lambda { |a| a.text }
709
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
710
- Mods::LANG_ATTRIBS.each { |attr_name|
711
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
712
- }
713
- end
714
-
715
- # LANGUAGE -------------------------------------------------------------------------------
716
- t.language :path => '/mods/language'
717
- t._language :path => '//language' do |n|
718
- # attributes
719
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
720
- Mods::LANG_ATTRIBS.each { |attr_name|
721
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
722
- }
723
- # child elements
724
- n.languageTerm :path => 'languageTerm'
725
- n.code_term :path => 'languageTerm[@type="code"]'
726
- n.text_term :path => 'languageTerm[@type="text"]'
727
- n.scriptTerm :path => 'scriptTerm'
728
- end
729
- t._languageTerm :path => '//languageTerm' do |lt|
730
- lt.type_at :path => '@type', :accessor => lambda { |a| a.text }
731
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
732
- lt.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
733
- }
734
- end # t.language
735
-
736
- # LOCATION -------------------------------------------------------------------------------
737
- t.location :path => '/mods/location'
738
- t._location :path => '//location' do |n|
739
- # attributes
740
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
741
- Mods::LANG_ATTRIBS.each { |attr_name|
742
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
743
- }
744
- # child elements
745
- n.physicalLocation :path => 'physicalLocation' do |e|
746
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
747
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
748
- e.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
749
- }
750
- end
751
- n.shelfLocator :path => 'shelfLocator'
752
- n.url :path => 'url' do |e|
753
- e.dateLastAccessed :path => '@dateLastAccessed', :accessor => lambda { |a| a.text }
754
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
755
- e.note :path => '@note', :accessor => lambda { |a| a.text }
756
- e.access :path => '@access', :accessor => lambda { |a| a.text }
757
- e.usage :path => '@usage', :accessor => lambda { |a| a.text }
758
- end
759
- n.holdingSimple :path => 'holdingSimple'
760
- n.holdingExternal :path => 'holdingExternal'
761
- end # t.location
762
-
763
- # NAME ------------------------------------------------------------------------------------
764
- t.plain_name :path => '/mods/name'
765
- t._plain_name :path => '//name' do |n|
766
- Mods::Name::ATTRIBUTES.each { |attr_name|
767
- if attr_name != 'type'
768
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
769
- else
770
- n.type_at :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
771
- end
772
- }
773
- # elements
774
- n.namePart :path => 'namePart' do |np|
775
- np.type_at :path => '@type', :accessor => lambda { |a| a.text }
776
- end
777
- n.family_name :path => 'namePart[@type="family"]'
778
- n.given_name :path => 'namePart[@type="given"]'
779
- n.termsOfAddress :path => 'namePart[@type="termsOfAddress"]'
780
- n.date :path => 'namePart[@type="date"]'
781
-
782
- n.displayForm :path => 'displayForm'
783
- n.affiliation :path => 'affiliation'
784
- n.description_el :path => 'description' # description is used by Nokogiri
785
- n.role :path => 'role' do |r|
786
- r.roleTerm :path => 'roleTerm' do |rt|
787
- rt.type_at :path => "@type", :accessor => lambda { |a| a.text }
788
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
789
- rt.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
790
- }
791
- end
792
- # convenience method
793
- r.authority :path => '.', :accessor => lambda { |role_node|
794
- a = nil
795
- role_node.roleTerm.each { |role_t|
796
- # role_t.authority will be [] if it is missing from an earlier roleTerm
797
- if role_t.authority && (!a || a.size == 0)
798
- a = role_t.authority
799
- end
800
- }
801
- a
802
- }
803
- # convenience method
804
- r.code :path => '.', :accessor => lambda { |role_node|
805
- c = nil
806
- role_node.roleTerm.each { |role_t|
807
- if role_t.type_at == 'code'
808
- c ||= role_t.text
809
- end
810
- }
811
- c
812
- }
813
- # convenience method
814
- r.value :path => '.', :accessor => lambda { |role_node|
815
- val = nil
816
- role_node.roleTerm.each { |role_t|
817
- if role_t.type_at == 'text'
818
- val ||= role_t.text
819
- end
820
- }
821
- # FIXME: this is broken if there are multiple role codes and some of them are not marcrelator
822
- if !val && role_node.code && role_node.authority.first =~ /marcrelator/
823
- val = MARC_RELATOR[role_node.code.first]
824
- end
825
- val
826
- }
827
- end # role node
828
-
829
- # name convenience method
830
- # uses the displayForm of a name if present
831
- # if no displayForm, try to make a string from family, given and terms of address
832
- # otherwise, return all non-date nameParts concatenated together
833
- n.display_value :path => '.', :single => true, :accessor => lambda {|name_node|
834
- dv = ''
835
- if name_node.displayForm && name_node.displayForm.text.size > 0
836
- dv = name_node.displayForm.text
837
- end
838
- if dv.empty?
839
- if name_node.type_at == 'personal'
840
- if name_node.family_name.size > 0
841
- dv = name_node.given_name.size > 0 ? "#{name_node.family_name.text}, #{name_node.given_name.text}" : name_node.family_name.text
842
- elsif name_node.given_name.size > 0
843
- dv = name_node.given_name.text
844
- end
845
- if !dv.empty?
846
- first = true
847
- name_node.namePart.each { |np|
848
- if np.type_at == 'termsOfAddress' && !np.text.empty?
849
- if first
850
- dv = dv + " " + np.text
851
- first = false
852
- else
853
- dv = dv + ", " + np.text
854
- end
855
- end
856
- }
857
- else # no family or given name
858
- dv = name_node.namePart.select {|np| np.type_at != 'date' && !np.text.empty?}.join(" ")
859
- end
860
- else # not a personal name
861
- dv = name_node.namePart.select {|np| np.type_at != 'date' && !np.text.empty?}.join(" ")
862
- end
863
- end
864
- dv.strip.empty? ? nil : dv.strip
865
- }
866
-
867
- # name convenience method
868
- n.display_value_w_date :path => '.', :single => true, :accessor => lambda {|name_node|
869
- dv = '' + name_node.display_value
870
- name_node.namePart.each { |np|
871
- if np.type_at == 'date' && !np.text.empty? && !dv.end_with?(np.text)
872
- dv = dv + ", #{np.text}"
873
- end
874
- }
875
- if dv.start_with?(', ')
876
- dv.sub(', ', '')
877
- end
878
- dv.strip.empty? ? nil : dv.strip
879
- }
880
- end # t._plain_name
881
-
882
- t.personal_name :path => '/mods/name[@type="personal"]'
883
- t._personal_name :path => '//name[@type="personal"]'
884
- t.corporate_name :path => '/mods/name[@type="corporate"]'
885
- t._corporate_name :path => '//name[@type="corporate"]'
886
- t.conference_name :path => '/mods/name[@type="conference"]'
887
- t._conference_name :path => '//name[@type="conference"]'
888
-
889
- # NOTE ---------------------------------------------------------------------------------
890
- t.note :path => '/mods/note'
891
- t._note :path => '//note' do |n|
892
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
893
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
894
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
895
- Mods::LANG_ATTRIBS.each { |attr_name|
896
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
897
- }
898
- end
899
-
900
- # ORIGIN_INFO --------------------------------------------------------------------------
901
- t.origin_info :path => '/mods/originInfo'
902
- t._origin_info :path => '//originInfo' do |n|
903
- # attributes
904
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
905
- Mods::LANG_ATTRIBS.each { |attr_name|
906
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
907
- }
908
- # child elements
909
- n.place :path => 'place' do |e|
910
- e.placeTerm :path => 'placeTerm' do |ee|
911
- ee.type_at :path => '@type', :accessor => lambda { |a| a.text }
912
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
913
- ee.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
914
- }
915
- end
916
- end
917
- n.publisher :path => 'publisher'
918
- Mods::OriginInfo::DATE_ELEMENTS.each { |date_el|
919
- n.send date_el, :path => "#{date_el}" do |d|
920
- Mods::DATE_ATTRIBS.each { |attr_name|
921
- d.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
922
- }
923
- if date_el == 'dateOther'
924
- d.type_at :path => '@type', :accessor => lambda { |a| a.text }
925
- end
926
- end
927
- }
928
- n.edition :path => 'edition'
929
- n.issuance :path => 'issuance'
930
- n.frequency :path => 'frequency' do |f|
931
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
932
- f.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
933
- }
934
- end
935
- end # t.origin_info
936
-
937
- # PART -----------------------------------------------------------------------------------
938
- t.part :path => '/mods/part'
939
- t._part :path => '//part' do |n|
940
- # attributes
941
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
942
- n.order :path => '@order', :accessor => lambda { |a| a.text }
943
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
944
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
945
- Mods::LANG_ATTRIBS.each { |attr_name|
946
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
947
- }
948
- # child elements
949
- n.detail :path => 'detail' do |e|
950
- # attributes
951
- e.level :path => '@level', :accessor => lambda { |a| a.text }
952
- e.type_at :path => '@type', :accessor => lambda { |a| a.text }
953
- # elements
954
- e.number :path => 'number'
955
- e.caption :path => 'caption'
956
- e.title :path => 'title'
957
- end
958
- n.extent :path => 'extent' do |e| # TODO: extent is ordered in xml schema
959
- # attributes
960
- e.unit :path => '@unit', :accessor => lambda { |a| a.text }
961
- # elements
962
- e.start :path => 'start'
963
- e.end :path => 'end'
964
- e.total :path => 'total'
965
- e.list :path => 'list'
966
- end
967
- n.date :path => 'date' do |e|
968
- Mods::DATE_ATTRIBS.reject { |a| a == 'keyDate' }.each { |attr_name|
969
- e.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
970
- }
971
- end
972
- n.text_el :path => 'text' do |e|
973
- e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
974
- e.type_at :path => '@type', :accessor => lambda { |a| a.text }
975
- end
976
- end # t._part
977
-
978
- # PHYSICAL_DESCRIPTION -------------------------------------------------------------------
979
- t.physical_description :path => '/mods/physicalDescription'
980
- t._physical_description :path => '//physicalDescription' do |n|
981
- # attributes
982
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
983
- Mods::LANG_ATTRIBS.each { |attr_name|
984
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
985
- }
986
- # child elements
987
- n.digitalOrigin :path => 'digitalOrigin'
988
- n.extent :path => 'extent'
989
- n.form :path => 'form' do |f|
990
- f.type_at :path => '@type', :accessor => lambda { |a| a.text }
991
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
992
- f.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
993
- }
994
- end
995
- n.internetMediaType :path => 'internetMediaType'
996
- n.note :path => 'note' do |nn|
997
- nn.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
998
- nn.type_at :path => '@type', :accessor => lambda { |a| a.text }
999
- end
1000
- n.reformattingQuality :path => 'reformattingQuality'
1001
- end
1002
-
1003
- # RECORD_INFO --------------------------------------------------------------------------
1004
- t.record_info :path => '/mods/recordInfo'
1005
- t._record_info :path => '//recordInfo' do |n|
1006
- # attributes
1007
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1008
- Mods::LANG_ATTRIBS.each { |attr_name|
1009
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1010
- }
1011
- # child elements
1012
- n.recordContentSource :path => 'recordContentSource' do |r|
1013
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1014
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1015
- }
1016
- end
1017
- n.recordCreationDate :path => 'recordCreationDate' do |r|
1018
- Mods::DATE_ATTRIBS.each { |attr_name|
1019
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1020
- }
1021
- end
1022
- n.recordChangeDate :path => 'recordChangeDate' do |r|
1023
- Mods::DATE_ATTRIBS.each { |attr_name|
1024
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1025
- }
1026
- end
1027
- n.recordIdentifier :path => 'recordIdentifier' do |r|
1028
- r.source :path => '@source', :accessor => lambda { |a| a.text }
1029
- end
1030
- n.recordOrigin :path => 'recordOrigin'
1031
- n.languageOfCataloging :path => 'languageOfCataloging' do |r|
1032
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1033
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1034
- }
1035
- r.languageTerm :path => 'languageTerm'
1036
- r.scriptTerm :path => 'scriptTerm'
1037
- end
1038
- n.descriptionStandard :path => 'descriptionStandard' do |r|
1039
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1040
- r.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1041
- }
1042
- end
1043
- end # t._record_info
1044
-
1045
- # RELATED_ITEM-------------------------------------------------------------------------
1046
- t.related_item :path => '/mods/relatedItem' do |n|
1047
- # attributes
1048
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1049
- n.id_at :path => '@ID', :accessor => lambda { |a| a.text }
1050
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
1051
- # elements
1052
- n.abstract :path => 'abstract'
1053
- n.accessCondition :path => 'accessCondition'
1054
- n.classification :path => 'classification'
1055
- n.extension :path => 'extension'
1056
- n.genre :path => 'genre'
1057
- n.identifier :path => 'identifier'
1058
- n.language :path => 'language'
1059
- n.location :path => 'location'
1060
- n.name_el :path => 'name' # Note: 'name' is used by Nokogiri
1061
- n.personal_name :path => 'name[@type="personal"]'
1062
- n.corporate_name :path => 'name[@type="corporate"]'
1063
- n.conference_name :path => 'name[@type="conference"]'
1064
- n.note :path => 'note'
1065
- n.originInfo :path => 'originInfo'
1066
- n.part :path => 'part'
1067
- n.physicalDescription :path => 'physicalDescription'
1068
- n.recordInfo :path => 'recordInfo'
1069
- n.subject :path => 'subject'
1070
- n.tableOfContents :path => 'tableOfContents'
1071
- n.targetAudience :path => 'targetAudience'
1072
- n.titleInfo :path => 'titleInfo'
1073
- n.typeOfResource :path => 'typeOfResource'
1074
- end
1075
-
1076
- # SUBJECT -----------------------------------------------------------------------------
1077
- t.subject :path => '/mods/subject'
1078
- t._subject :path => '//subject' do |n|
1079
- # attributes
1080
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1081
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1082
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1083
- }
1084
- Mods::LANG_ATTRIBS.each { |attr_name|
1085
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1086
- }
1087
- # child elements
1088
- n.cartographics :path => 'cartographics' do |n1|
1089
- n1.scale :path => 'scale'
1090
- n1.projection :path => 'projection'
1091
- n1.coordinates :path => 'coordinates'
1092
- Mods::Subject::CARTOGRAPHICS_CHILD_ELEMENTS.each { |elname|
1093
- n1.send elname, :path => "#{elname}"
1094
- }
1095
- end
1096
- n.geographic :path => 'geographic' do |n1|
1097
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1098
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1099
- }
1100
- end
1101
- n.genre :path => 'genre' do |n1|
1102
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1103
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1104
- }
1105
- end
1106
- n.geographicCode :path => 'geographicCode' do |gc|
1107
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1108
- gc.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1109
- }
1110
- # convenience method
1111
- gc.translated_value :path => '.', :accessor => lambda { |gc_node|
1112
- code_val ||= gc_node.text
1113
- xval = nil
1114
- if code_val
1115
- case gc_node.authority
1116
- when 'marcgac'
1117
- xval = MARC_GEOGRAPHIC_AREA[code_val]
1118
- when 'marccountry'
1119
- xval = MARC_COUNTRY[code_val]
1120
- end
1121
- end
1122
- xval
1123
- }
1124
- end
1125
- n.hierarchicalGeographic :path => 'hierarchicalGeographic' do |n1|
1126
- Mods::Subject::HIER_GEO_CHILD_ELEMENTS.each { |elname|
1127
- n1.send elname, :path => "#{elname}"
1128
- }
1129
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1130
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1131
- }
1132
- end
1133
- # Note: 'name' is used by Nokogiri
1134
- n.name_el :path => 'name' do |t1|
1135
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1136
- t1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1137
- }
1138
- end
1139
- n.personal_name :path => 'name[@type="personal"]'
1140
- n.corporate_name :path => 'name[@type="corporate"]'
1141
- n.conference_name :path => 'name[@type="conference"]'
1142
- n.occupation :path => 'occupation' do |n1|
1143
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1144
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1145
- }
1146
- end
1147
- n.temporal :path => 'temporal' do |n1|
1148
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1149
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1150
- }
1151
- # date attributes as attributes
1152
- Mods::DATE_ATTRIBS.each { |attr_name|
1153
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1154
- }
1155
- end
1156
- n.titleInfo :path => 'titleInfo' do |t1|
1157
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1158
- t1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1159
- }
1160
- end
1161
- n.topic :path => 'topic' do |n1|
1162
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1163
- n1.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1164
- }
1165
- end
1166
- end # t.subject
1167
-
1168
- # TABLE_OF_CONTENTS ---------------------------------------------------------------------
1169
- t.tableOfContents :path => '/mods/tableOfContents'
1170
- t._tableOfContents :path => '//tableOfContents' do |n|
1171
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1172
- n.shareable :path => '@shareable', :accessor => lambda { |a| a.text }
1173
- n.type_at :path => '@type', :accessor => lambda { |a| a.text }
1174
- Mods::LANG_ATTRIBS.each { |attr_name|
1175
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1176
- }
1177
- end
1178
-
1179
- # TARGET_AUDIENCE -----------------------------------------------------------------------
1180
- t.targetAudience :path => '/mods/targetAudience'
1181
- t._targetAudience :path => '//targetAudience' do |n|
1182
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1183
- Mods::AUTHORITY_ATTRIBS.each { |attr_name|
1184
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1185
- }
1186
- Mods::LANG_ATTRIBS.each { |attr_name|
1187
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1188
- }
1189
- end
1190
-
1191
- # TITLE_INFO ----------------------------------------------------------------------------
1192
- t.title_info :path => '/mods/titleInfo'
1193
- t._title_info :path => '//titleInfo' do |n|
1194
- Mods::TitleInfo::ATTRIBUTES.each { |attr_name|
1195
- if attr_name != 'type'
1196
- n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1197
- else
1198
- n.type_at :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
1199
- end
1200
- }
1201
- n.title :path => 'title'
1202
- n.subTitle :path => 'subTitle'
1203
- n.nonSort :path => 'nonSort'
1204
- n.partNumber :path => 'partNumber'
1205
- n.partName :path => 'partName'
1206
- n.sort_title :path => '.', :accessor => lambda { |node|
1207
- if node.type_at != "alternative" || (node.type_at == "alternative" && mods_ng_xml.xpath('/mods/titleInfo').size == 1)
1208
- node.title.text + (!node.subTitle.text.empty? ? "#{@title_delimiter}#{node.subTitle.text}" : "" )
1209
- end
1210
- }
1211
- n.full_title :path => '.', :accessor => lambda { |node|
1212
- (!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
1213
- node.title.text +
1214
- (!node.subTitle.text.empty? ? "#{@title_delimiter}#{node.subTitle.text}" : "" )
1215
- }
1216
- n.short_title :path => '.', :accessor => lambda { |node|
1217
- if node.type_at != "alternative"
1218
- (!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
1219
- node.title.text
1220
- end
1221
- }
1222
- n.alternative_title :path => '.', :accessor => lambda { |node|
1223
- if node.type_at == "alternative"
1224
- (!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
1225
- node.title.text
1226
- end
1227
- }
1228
- end # t._title_info
1229
-
1230
- # TYPE_OF_RESOURCE --------------------------------------------------------------------
1231
- t.typeOfResource :path => '/mods/typeOfResource'
1232
- t._typeOfResource :path => '//typeOfResource' do |n|
1233
- n.collection :path => '@collection', :accessor => lambda { |a| a.text }
1234
- n.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
1235
- n.manuscript :path => '@manuscript', :accessor => lambda { |a| a.text }
1236
- n.usage :path => '@usage', :accessor => lambda { |a| a.text }
1237
- end
1238
-
1239
- end # terminology
1240
-
1241
- mods_ng_xml.nom!
1242
- mods_ng_xml
1243
- end # set_terminology_no_ns
1244
-
1245
- end # Record class
1246
- end # Mods module
505
+ end
506
+ end
507
+ end