bplmodels 0.0.91

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