mods 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -2
- data/lib/mods.rb +12 -2
- data/lib/mods/constants.rb +60 -0
- data/lib/mods/marc_relator_codes.rb +228 -0
- data/lib/mods/name.rb +18 -0
- data/lib/mods/nom_terminology.rb +221 -0
- data/lib/mods/reader.rb +41 -0
- data/lib/mods/record.rb +145 -0
- data/lib/mods/title_info.rb +24 -0
- data/lib/mods/version.rb +2 -1
- data/mods.gemspec +12 -6
- data/spec/language_spec.rb +69 -0
- data/spec/location_spec.rb +148 -0
- data/spec/name_spec.rb +257 -0
- data/spec/origin_info_spec.rb +311 -0
- data/spec/physical_description_spec.rb +79 -0
- data/spec/reader_spec.rb +50 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/title_spec.rb +111 -0
- data/spec/top_level_elmnts_simple_spec.rb +32 -0
- metadata +69 -10
data/README.rdoc
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
= Mods
|
2
2
|
|
3
|
-
|
3
|
+
{<img src="https://secure.travis-ci.org/sul-dlss/mods.png?branch=master" alt="Build Status" />}[http://travis-ci.org/sul-dlss/mods]
|
4
|
+
|
5
|
+
A Gem to parse MODS (Metadata Object Description Schema) records. More information about MODS can be found at http://www.loc.gov/standards/mods/registry.php.
|
4
6
|
|
5
7
|
Source code at https://github.com/sul-dlss/mods/
|
6
8
|
|
7
|
-
Generated API docs at http://rubydoc.info/
|
9
|
+
Generated API docs at http://rubydoc.info/github/sul-dlss/mods/
|
8
10
|
|
9
11
|
== Installation
|
10
12
|
|
@@ -35,5 +37,7 @@ TODO: Write usage instructions here
|
|
35
37
|
|
36
38
|
== Releases
|
37
39
|
|
40
|
+
0.0.4 implement language, location, origin_info, physical_description
|
41
|
+
0.0.3 use nom-xml gem and make this more nokogiri-ish; implement name, title, and simple top level elements with no subelements
|
38
42
|
0.0.2 Set up rake tasks, publishing rdoc, and continuous integration.
|
39
43
|
0.0.1 Grab the name
|
data/lib/mods.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
require
|
1
|
+
require 'mods/constants'
|
2
|
+
require 'mods/marc_relator_codes'
|
3
|
+
require 'mods/name'
|
4
|
+
require 'mods/nom_terminology'
|
5
|
+
require 'mods/reader'
|
6
|
+
require 'mods/record'
|
7
|
+
require 'mods/title_info'
|
8
|
+
require 'mods/version'
|
9
|
+
|
10
|
+
require 'nokogiri'
|
11
|
+
require 'nom/xml'
|
2
12
|
|
3
13
|
module Mods
|
4
|
-
|
14
|
+
|
5
15
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Mods
|
2
|
+
# the version of MODS supported by this gem
|
3
|
+
MODS_VERSION = '3.4'
|
4
|
+
|
5
|
+
MODS_NS_V3 = "http://www.loc.gov/mods/v3"
|
6
|
+
MODS_NS = MODS_NS_V3
|
7
|
+
MODS_XSD = "http://www.loc.gov/standards/mods/mods.xsd"
|
8
|
+
|
9
|
+
DOC_URL = "http://www.loc.gov/standards/mods/"
|
10
|
+
|
11
|
+
# top level elements that cannot have subelement children
|
12
|
+
TOP_LEVEL_ELEMENTS_SIMPLE = [
|
13
|
+
'abstract',
|
14
|
+
'accessCondition',
|
15
|
+
'classification',
|
16
|
+
'extension',
|
17
|
+
'genre',
|
18
|
+
'identifier',
|
19
|
+
'note',
|
20
|
+
'tableOfContents',
|
21
|
+
'targetAudience',
|
22
|
+
'typeOfResource',
|
23
|
+
]
|
24
|
+
|
25
|
+
# top level elements that can have subelement children
|
26
|
+
TOP_LEVEL_ELEMENTS_COMPLEX = [
|
27
|
+
'language',
|
28
|
+
'location',
|
29
|
+
'name',
|
30
|
+
'originInfo',
|
31
|
+
'part',
|
32
|
+
'physicalDescription',
|
33
|
+
'recordInfo',
|
34
|
+
'relatedItem',
|
35
|
+
'subject',
|
36
|
+
'titleInfo' ]
|
37
|
+
|
38
|
+
TOP_LEVEL_ELEMENTS = Array.new(TOP_LEVEL_ELEMENTS_SIMPLE).concat(TOP_LEVEL_ELEMENTS_COMPLEX)
|
39
|
+
|
40
|
+
# enumerated attribute values
|
41
|
+
TITLE_INFO_TYPES = ['abbreviated', 'translated', 'alternative', 'uniform']
|
42
|
+
RELATED_ITEM_TYPES = [
|
43
|
+
'preceding', 'succeeding', 'original', 'host', 'constituent', 'series',
|
44
|
+
'otherVersion', 'otherFormat', 'isReferencedBy', 'references', 'reviewOf'
|
45
|
+
]
|
46
|
+
|
47
|
+
# enumerated values
|
48
|
+
TYPE_OF_RESOURCE_VALUES = [
|
49
|
+
'text', 'cartographic', 'notated music', 'sound recording-musical', 'sound recording-nonmusical',
|
50
|
+
'sound recording',
|
51
|
+
'still image',
|
52
|
+
'moving image',
|
53
|
+
'three dimensional object',
|
54
|
+
'software',
|
55
|
+
'multimedia',
|
56
|
+
'mixed material']
|
57
|
+
|
58
|
+
ORIGIN_INFO_DATE_ELEMENTS = ['dateIssued', 'dateCreated', 'dateCaptured', 'dateValid', 'dateModified', 'copyrightDate', 'dateOther']
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
# Represents the Marc Relator Codes mapped to Relators, from http://www.loc.gov/marc/relators/relacode.html
|
2
|
+
# key - Marc Relator code
|
3
|
+
# value - Marc Relator term
|
4
|
+
MARC_RELATOR = {
|
5
|
+
'acp' => 'Art copyist',
|
6
|
+
'act' => 'Actor',
|
7
|
+
'adp' => 'Adapter',
|
8
|
+
'aft' => 'Author of afterword, colophon, etc.',
|
9
|
+
'anl' => 'Analyst',
|
10
|
+
'anm' => 'Animator',
|
11
|
+
'ann' => 'Annotator',
|
12
|
+
'ant' => 'Bibliographic antecedent',
|
13
|
+
'app' => 'Applicant',
|
14
|
+
'aqt' => 'Author in quotations or text abstracts',
|
15
|
+
'arc' => 'Architect',
|
16
|
+
'ard' => 'Artistic director',
|
17
|
+
'arr' => 'Arranger',
|
18
|
+
'art' => 'Artist',
|
19
|
+
'asg' => 'Assignee',
|
20
|
+
'asn' => 'Associated name',
|
21
|
+
'att' => 'Attributed name',
|
22
|
+
'auc' => 'Auctioneer',
|
23
|
+
'aud' => 'Author of dialog',
|
24
|
+
'aui' => 'Author of introduction',
|
25
|
+
'aus' => 'Author of screenplay',
|
26
|
+
'aut' => 'Author',
|
27
|
+
'bdd' => 'Binding designer',
|
28
|
+
'bjd' => 'Bookjacket designer',
|
29
|
+
'bkd' => 'Book designer',
|
30
|
+
'bkp' => 'Book producer',
|
31
|
+
'blw' => 'Blurb writer',
|
32
|
+
'bnd' => 'Binder',
|
33
|
+
'bpd' => 'Bookplate designer',
|
34
|
+
'bsl' => 'Bookseller',
|
35
|
+
'ccp' => 'Conceptor',
|
36
|
+
'chr' => 'Choreographer',
|
37
|
+
'clb' => 'Collaborator',
|
38
|
+
'cli' => 'Client',
|
39
|
+
'cll' => 'Calligrapher',
|
40
|
+
'clr' => 'Colorist',
|
41
|
+
'clt' => 'Collotyper',
|
42
|
+
'cmm' => 'Commentator',
|
43
|
+
'cmp' => 'Composer',
|
44
|
+
'cmt' => 'Compositor',
|
45
|
+
'cng' => 'Cinematographer',
|
46
|
+
'cnd' => 'Conductor',
|
47
|
+
'cns' => 'Censor',
|
48
|
+
'coe' => 'Contestant -appellee',
|
49
|
+
'col' => 'Collector',
|
50
|
+
'com' => 'Compiler',
|
51
|
+
'con' => 'Conservator',
|
52
|
+
'cos' => 'Contestant',
|
53
|
+
'cot' => 'Contestant -appellant',
|
54
|
+
'cov' => 'Cover designer',
|
55
|
+
'cpc' => 'Copyright claimant',
|
56
|
+
'cpe' => 'Complainant-appellee',
|
57
|
+
'cph' => 'Copyright holder',
|
58
|
+
'cpl' => 'Complainant',
|
59
|
+
'cpt' => 'Complainant-appellant',
|
60
|
+
'cre' => 'Creator',
|
61
|
+
'crp' => 'Correspondent',
|
62
|
+
'crr' => 'Corrector',
|
63
|
+
'csl' => 'Consultant',
|
64
|
+
'csp' => 'Consultant to a project',
|
65
|
+
'cst' => 'Costume designer',
|
66
|
+
'ctb' => 'Contributor',
|
67
|
+
'cte' => 'Contestee-appellee',
|
68
|
+
'ctg' => 'Cartographer',
|
69
|
+
'ctr' => 'Contractor',
|
70
|
+
'cts' => 'Contestee',
|
71
|
+
'ctt' => 'Contestee-appellant',
|
72
|
+
'cur' => 'Curator',
|
73
|
+
'cwt' => 'Commentator for written text',
|
74
|
+
'dfd' => 'Defendant',
|
75
|
+
'dfe' => 'Defendant-appellee',
|
76
|
+
'dft' => 'Defendant-appellant',
|
77
|
+
'dgg' => 'Degree grantor',
|
78
|
+
'dis' => 'Dissertant',
|
79
|
+
'dln' => 'Delineator',
|
80
|
+
'dnc' => 'Dancer',
|
81
|
+
'dnr' => 'Donor',
|
82
|
+
'dpb' => 'Distribution place',
|
83
|
+
'dpc' => 'Depicted',
|
84
|
+
'dpt' => 'Depositor',
|
85
|
+
'drm' => 'Draftsman',
|
86
|
+
'drt' => 'Director',
|
87
|
+
'dsr' => 'Designer',
|
88
|
+
'dst' => 'Distributor',
|
89
|
+
'dtc' => 'Data contributor',
|
90
|
+
'dte' => 'Dedicatee',
|
91
|
+
'dtm' => 'Data manager',
|
92
|
+
'dto' => 'Dedicator',
|
93
|
+
'dub' => 'Dubious author',
|
94
|
+
'edt' => 'Editor',
|
95
|
+
'egr' => 'Engraver',
|
96
|
+
'elg' => 'Electrician',
|
97
|
+
'elt' => 'Electrotyper',
|
98
|
+
'eng' => 'Engineer',
|
99
|
+
'etr' => 'Etcher',
|
100
|
+
'evp' => 'Event place',
|
101
|
+
'exp' => 'Expert',
|
102
|
+
'fac' => 'Facsimilist',
|
103
|
+
'fld' => 'Field director',
|
104
|
+
'flm' => 'Film editor',
|
105
|
+
'fmo' => 'Former owner',
|
106
|
+
'fpy' => 'First party',
|
107
|
+
'fnd' => 'Funder',
|
108
|
+
'frg' => 'Forger',
|
109
|
+
'gis' => 'Geographic information specialist',
|
110
|
+
'grt' => 'Graphic technician',
|
111
|
+
'hnr' => 'Honoree',
|
112
|
+
'hst' => 'Host',
|
113
|
+
'ill' => 'Illustrator',
|
114
|
+
'ilu' => 'Illuminator',
|
115
|
+
'ins' => 'Inscriber',
|
116
|
+
'inv' => 'Inventor',
|
117
|
+
'itr' => 'Instrumentalist',
|
118
|
+
'ive' => 'Interviewee',
|
119
|
+
'ivr' => 'Interviewer',
|
120
|
+
'lbr' => 'Laboratory',
|
121
|
+
'lbt' => 'Librettist',
|
122
|
+
'ldr' => 'Laboratory director',
|
123
|
+
'led' => 'Lead',
|
124
|
+
'lee' => 'Libelee-appellee',
|
125
|
+
'lel' => 'Libelee',
|
126
|
+
'len' => 'Lender',
|
127
|
+
'let' => 'Libelee-appellant',
|
128
|
+
'lgd' => 'Lighting designer',
|
129
|
+
'lie' => 'Libelant-appellee',
|
130
|
+
'lil' => 'Libelant',
|
131
|
+
'lit' => 'Libelant-appellant',
|
132
|
+
'lsa' => 'Landscape architect',
|
133
|
+
'lse' => 'Licensee',
|
134
|
+
'lso' => 'Licensor',
|
135
|
+
'ltg' => 'Lithographer',
|
136
|
+
'lyr' => 'Lyricist',
|
137
|
+
'mcp' => 'Music copyist',
|
138
|
+
'mfp' => 'Manufacture place',
|
139
|
+
'mfr' => 'Manufacturer',
|
140
|
+
'mdc' => 'Metadata contact',
|
141
|
+
'mod' => 'Moderator',
|
142
|
+
'mon' => 'Monitor',
|
143
|
+
'mrb' => 'Marbler',
|
144
|
+
'mrk' => 'Markup editor',
|
145
|
+
'msd' => 'Musical director',
|
146
|
+
'mte' => 'Metal-engraver',
|
147
|
+
'mus' => 'Musician',
|
148
|
+
'nrt' => 'Narrator',
|
149
|
+
'opn' => 'Opponent',
|
150
|
+
'org' => 'Originator',
|
151
|
+
'orm' => 'Organizer of meeting',
|
152
|
+
'oth' => 'Other',
|
153
|
+
'own' => 'Owner',
|
154
|
+
'pat' => 'Patron',
|
155
|
+
'pbd' => 'Publishing director',
|
156
|
+
'pbl' => 'Publisher',
|
157
|
+
'pdr' => 'Project director',
|
158
|
+
'pfr' => 'Proofreader',
|
159
|
+
'pht' => 'Photographer',
|
160
|
+
'plt' => 'Platemaker',
|
161
|
+
'pma' => 'Permitting agency',
|
162
|
+
'pmn' => 'Production manager',
|
163
|
+
'pop' => 'Printer of plates',
|
164
|
+
'ppm' => 'Papermaker',
|
165
|
+
'ppt' => 'Puppeteer',
|
166
|
+
'prc' => 'Process contact',
|
167
|
+
'prd' => 'Production personnel',
|
168
|
+
'prf' => 'Performer',
|
169
|
+
'prg' => 'Programmer',
|
170
|
+
'prm' => 'Printmaker',
|
171
|
+
'pro' => 'Producer',
|
172
|
+
'prp' => 'Production place',
|
173
|
+
'prt' => 'Printer',
|
174
|
+
'pta' => 'Patent applicant',
|
175
|
+
'pte' => 'Plaintiff -appellee',
|
176
|
+
'ptf' => 'Plaintiff',
|
177
|
+
'pth' => 'Patent holder',
|
178
|
+
'ptt' => 'Plaintiff-appellant',
|
179
|
+
'pup' => 'Publication place',
|
180
|
+
'rbr' => 'Rubricator',
|
181
|
+
'rce' => 'Recording engineer',
|
182
|
+
'rcp' => 'Recipient',
|
183
|
+
'red' => 'Redactor',
|
184
|
+
'ren' => 'Renderer',
|
185
|
+
'res' => 'Researcher',
|
186
|
+
'rev' => 'Reviewer',
|
187
|
+
'rps' => 'Repository',
|
188
|
+
'rpt' => 'Reporter',
|
189
|
+
'rpy' => 'Responsible party',
|
190
|
+
'rse' => 'Respondent-appellee',
|
191
|
+
'rsg' => 'Restager',
|
192
|
+
'rsp' => 'Respondent',
|
193
|
+
'rst' => 'Respondent-appellant',
|
194
|
+
'rth' => 'Research team head',
|
195
|
+
'rtm' => 'Research team member',
|
196
|
+
'sad' => 'Scientific advisor',
|
197
|
+
'sce' => 'Scenarist',
|
198
|
+
'scl' => 'Sculptor',
|
199
|
+
'scr' => 'Scribe',
|
200
|
+
'sds' => 'Sound designer',
|
201
|
+
'sec' => 'Secretary',
|
202
|
+
'sgn' => 'Signer',
|
203
|
+
'sht' => 'Supporting host',
|
204
|
+
'sng' => 'Singer',
|
205
|
+
'spk' => 'Speaker',
|
206
|
+
'spn' => 'Sponsor',
|
207
|
+
'spy' => 'Second party',
|
208
|
+
'srv' => 'Surveyor',
|
209
|
+
'std' => 'Set designer',
|
210
|
+
'stl' => 'Storyteller',
|
211
|
+
'stm' => 'Stage manager',
|
212
|
+
'stn' => 'Standards body',
|
213
|
+
'str' => 'Stereotyper',
|
214
|
+
'tcd' => 'Technical director',
|
215
|
+
'tch' => 'Teacher',
|
216
|
+
'ths' => 'Thesis advisor',
|
217
|
+
'trc' => 'Transcriber',
|
218
|
+
'trl' => 'Translator',
|
219
|
+
'tyd' => 'Type designer',
|
220
|
+
'tyg' => 'Typographer',
|
221
|
+
'uvp' => 'University place',
|
222
|
+
'vdg' => 'Videographer',
|
223
|
+
'voc' => 'Vocalist',
|
224
|
+
'wam' => 'Writer of accompanying material',
|
225
|
+
'wdc' => 'Woodcutter',
|
226
|
+
'wde' => 'Wood-engraver',
|
227
|
+
'wit' => 'Witness'
|
228
|
+
}
|
data/lib/mods/name.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Mods
|
2
|
+
|
3
|
+
class Name
|
4
|
+
|
5
|
+
NS_HASH = {'m' => MODS_NS_V3}
|
6
|
+
SUBELEMENTS = ['namePart', 'displayForm', 'affiliation', 'role', 'description']
|
7
|
+
|
8
|
+
# attributes on name node
|
9
|
+
ATTRIBUTES = ['type', 'authority', 'authorityURI', 'valueURI', 'displayLabel', 'usage', 'altRepGroup', 'nameTitleGroup']
|
10
|
+
|
11
|
+
# valid values for type attribute on name node <name type="val"/>
|
12
|
+
TYPES = ['personal', 'corporate', 'conference', 'family']
|
13
|
+
# valid values for type attribute on namePart node <name><namePart type="val"/></name>
|
14
|
+
NAME_PART_TYPES = ['date', 'family', 'given', 'termsOfAddress']
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
module Mods
|
2
|
+
|
3
|
+
class Record
|
4
|
+
|
5
|
+
# set the NOM terminology; do NOT use namespaces
|
6
|
+
# @param mods_ng_xml a Nokogiri::Xml::Document object containing MODS (without namespaces)
|
7
|
+
def set_terminology_no_ns(mods_ng_xml)
|
8
|
+
mods_ng_xml.set_terminology() do |t|
|
9
|
+
|
10
|
+
# FIXME: may want to deal with camelcase vs. underscore in method_missing
|
11
|
+
|
12
|
+
# These elements have no subelements - w00t!
|
13
|
+
Mods::TOP_LEVEL_ELEMENTS_SIMPLE.each { |elname|
|
14
|
+
t.send elname, :path => "/mods/#{elname}"
|
15
|
+
}
|
16
|
+
|
17
|
+
# TITLE_INFO ----------------------------------------------------------------------------
|
18
|
+
# note - titleInfo can be a top level element or a sub-element of relatedItem
|
19
|
+
# (<titleInfo> as subelement of <subject> is not part of the MODS namespace)
|
20
|
+
|
21
|
+
t.title_info :path => '/mods/titleInfo' do |n|
|
22
|
+
n.type_at :path => '@type'
|
23
|
+
n.title :path => 'title'
|
24
|
+
n.subTitle :path => 'subTitle'
|
25
|
+
n.nonSort :path => 'nonSort'
|
26
|
+
n.partNumber :path => 'partNumber'
|
27
|
+
n.partName :path => 'partName'
|
28
|
+
n.sort_title :path => '.', :accessor => lambda { |node|
|
29
|
+
if node.type_at.text != "alternative" || (node.type_at.text == "alternative" && mods_ng_xml.xpath('/mods/titleInfo').size == 1)
|
30
|
+
node.title.text + (!node.subTitle.text.empty? ? "#{@title_delimiter}#{node.subTitle.text}" : "" )
|
31
|
+
end
|
32
|
+
}
|
33
|
+
n.full_title :path => '.', :accessor => lambda { |node|
|
34
|
+
(!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
|
35
|
+
node.title.text +
|
36
|
+
(!node.subTitle.text.empty? ? "#{@title_delimiter}#{node.subTitle.text}" : "" )
|
37
|
+
}
|
38
|
+
n.short_title :path => '.', :accessor => lambda { |node|
|
39
|
+
if node.type_at.text != "alternative"
|
40
|
+
(!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
|
41
|
+
node.title.text
|
42
|
+
end
|
43
|
+
}
|
44
|
+
n.alternative_title :path => '.', :accessor => lambda { |node|
|
45
|
+
if node.type_at.text == "alternative"
|
46
|
+
(!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
|
47
|
+
node.title.text
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# current way to do short_title correctly
|
53
|
+
# t.short_title :path => '/mods/titleInfo[not(@type=alternative)]', :accessor => lambda { |node|
|
54
|
+
# (!node.nonSort.text.empty? ? "#{node.nonSort.text} " : "" ) +
|
55
|
+
# node.title.text
|
56
|
+
# }
|
57
|
+
|
58
|
+
|
59
|
+
# NAME ------------------------------------------------------------------------------------
|
60
|
+
|
61
|
+
t.plain_name :path => '/mods/name' do |n|
|
62
|
+
|
63
|
+
Mods::Name::ATTRIBUTES.each { |attr_name|
|
64
|
+
if attr_name != 'type'
|
65
|
+
n.send attr_name, :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
|
66
|
+
else
|
67
|
+
n.type_at :path => "@#{attr_name}", :accessor => lambda { |a| a.text }
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
n.namePart :path => 'namePart' do |np|
|
72
|
+
np.type_at :path => '@type'
|
73
|
+
end
|
74
|
+
n.displayForm :path => 'displayForm'
|
75
|
+
n.affiliation :path => 'affiliation'
|
76
|
+
n.description_el :path => 'description' # description is used by Nokogiri
|
77
|
+
n.role :path => 'role/roleTerm' do |r|
|
78
|
+
r.type_at :path => "@type", :accessor => lambda { |a| a.text }
|
79
|
+
r.authority :path => "@authority", :accessor => lambda { |a| a.text }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
t.personal_name :path => '/mods/name[@type="personal"]' do |n|
|
84
|
+
n.family_name :path => 'namePart[@type="family"]'
|
85
|
+
n.given_name :path => 'namePart[@type="given"]'
|
86
|
+
n.termsOfAddress :path => 'namePart[@type="termsOfAddress"]'
|
87
|
+
n.date :path => 'namePart[@type="date"]'
|
88
|
+
end
|
89
|
+
|
90
|
+
t.corporate_name :path => '/mods/name[@type="corporate"]'
|
91
|
+
t.conference_name :path => '/mods/name[@type="conference"]'
|
92
|
+
|
93
|
+
# LANGUAGE -------------------------------------------------------------------------------
|
94
|
+
|
95
|
+
t.language :path => '/mods/language' do |n|
|
96
|
+
n.languageTerm :path => 'languageTerm' do |lt|
|
97
|
+
lt.type_at :path => '@type', :accessor => lambda { |a| a.text }
|
98
|
+
lt.authority :path => '@authority', :accessor => lambda { |a| a.text }
|
99
|
+
end
|
100
|
+
n.code_term :path => 'languageTerm[@type="code"]'
|
101
|
+
n.text_term :path => 'languageTerm[@type="text"]'
|
102
|
+
n.scriptTerm :path => 'scriptTerm'
|
103
|
+
end
|
104
|
+
|
105
|
+
# PHYSICAL_DESCRIPTION -------------------------------------------------------------------
|
106
|
+
t.physical_description :path => '/mods/physicalDescription' do |n|
|
107
|
+
n.digitalOrigin :path => 'digitalOrigin'
|
108
|
+
n.extent :path => 'extent'
|
109
|
+
n.form :path => 'form' do |f|
|
110
|
+
f.authority :path => '@authority', :accessor => lambda { |a| a.text }
|
111
|
+
f.type_at :path => '@type', :accessor => lambda { |a| a.text }
|
112
|
+
end
|
113
|
+
n.internetMediaType :path => 'internetMediaType'
|
114
|
+
n.note :path => 'note' do |nn|
|
115
|
+
nn.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
|
116
|
+
nn.type_at :path => '@type', :accessor => lambda { |a| a.text }
|
117
|
+
end
|
118
|
+
n.reformattingQuality :path => 'reformattingQuality'
|
119
|
+
end
|
120
|
+
|
121
|
+
# LOCATION -------------------------------------------------------------------------------
|
122
|
+
t.location :path => '/mods/location' do |n|
|
123
|
+
n.physicalLocation :path => 'physicalLocation' do |e|
|
124
|
+
e.authority :path => '@authority', :accessor => lambda { |a| a.text }
|
125
|
+
e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
|
126
|
+
end
|
127
|
+
n.shelfLocator :path => 'shelfLocator'
|
128
|
+
n.url :path => 'url' do |e|
|
129
|
+
e.dateLastAccessed :path => '@dateLastAccessed', :accessor => lambda { |a| a.text }
|
130
|
+
e.displayLabel :path => '@displayLabel', :accessor => lambda { |a| a.text }
|
131
|
+
e.note :path => '@note', :accessor => lambda { |a| a.text }
|
132
|
+
e.access :path => '@access', :accessor => lambda { |a| a.text }
|
133
|
+
e.usage :path => '@usage', :accessor => lambda { |a| a.text }
|
134
|
+
end
|
135
|
+
n.holdingSimple :path => 'holdingSimple'
|
136
|
+
n.holdingExternal :path => 'holdingExternal'
|
137
|
+
end
|
138
|
+
|
139
|
+
# ORIGIN_INFO --------------------------------------------------------------------------
|
140
|
+
t.origin_info :path => '/mods/originInfo' do |n|
|
141
|
+
n.place :path => 'place' do |e|
|
142
|
+
e.placeTerm :path => 'placeTerm' do |ee|
|
143
|
+
ee.type_at :path => '@type', :accessor => lambda { |a| a.text }
|
144
|
+
ee.authority :path => '@authority', :accessor => lambda { |a| a.text }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
n.publisher :path => 'publisher'
|
148
|
+
Mods::ORIGIN_INFO_DATE_ELEMENTS.each { |date_el|
|
149
|
+
n.send date_el, :path => "#{date_el}" do |d|
|
150
|
+
d.encoding :path => '@encoding', :accessor => lambda { |a| a.text }
|
151
|
+
d.point :path => '@point', :accessor => lambda { |a| a.text }
|
152
|
+
d.keyDate :path => '@keyDate', :accessor => lambda { |a| a.text }
|
153
|
+
d.qualifier :path => '@qualifier', :accessor => lambda { |a| a.text }
|
154
|
+
if date_el == 'dateOther'
|
155
|
+
d.type_at :path => '@type', :accessor => lambda { |a| a.text }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
}
|
159
|
+
n.edition :path => 'edition'
|
160
|
+
n.issuance :path => 'issuance'
|
161
|
+
n.frequency :path => 'frequency' do |f|
|
162
|
+
f.authority :path => '@authority', :accessor => lambda { |a| a.text }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end # terminology
|
167
|
+
|
168
|
+
mods_ng_xml.nom!
|
169
|
+
|
170
|
+
mods_ng_xml
|
171
|
+
end # set_terminology_no_ns
|
172
|
+
|
173
|
+
# TODO: common top level element attributes: ID; xlink; lang; xml:lang; script; transliteration
|
174
|
+
# authority, authorityURI, valueURI
|
175
|
+
# displayLabel, usage altRepGroup
|
176
|
+
# type
|
177
|
+
# TODO: common subelement attributes: lang, xml:lang, script, transliteration
|
178
|
+
# TODO: other common attribute: supplied
|
179
|
+
|
180
|
+
|
181
|
+
# set the NOM terminology, with namespaces
|
182
|
+
# @param mods_ng_xml a Nokogiri::Xml::Document object containing MODS (with namespaces)
|
183
|
+
def set_terminology_ns(mods_ng_xml)
|
184
|
+
mods_ng_xml.set_terminology(:namespaces => { 'm' => Mods::MODS_NS}) do |t|
|
185
|
+
|
186
|
+
# note - titleInfo can be a top level element or a sub-element of subject and relatedItem
|
187
|
+
t.title_info :path => '//m:titleInfo' do |n|
|
188
|
+
n.title :path => 'm:title'
|
189
|
+
n.subTitle :path => 'm:subTitle'
|
190
|
+
n.nonSort :path => 'm:nonSort'
|
191
|
+
n.partNumber :path => 'm:partNumber'
|
192
|
+
n.partName :path => 'm:partName'
|
193
|
+
n.type_at :path => '@type'
|
194
|
+
end
|
195
|
+
|
196
|
+
t.author :path => '//m:name' do |n|
|
197
|
+
n.valueURI :path => '@valueURI'
|
198
|
+
n.namePart :path => 'm:namePart', :single => true
|
199
|
+
end
|
200
|
+
|
201
|
+
t.corporate_authors :path => '//m:name[@type="corporate"]'
|
202
|
+
t.personal_authors :path => 'm:name[@type="personal"]' do |n|
|
203
|
+
n.roleTerm :path => 'm:role/m:roleTerm'
|
204
|
+
n.name_role_pair :path => '.', :accessor => lambda { |node| node.roleTerm.text + ": " + node.namePart.text }
|
205
|
+
end
|
206
|
+
|
207
|
+
t.language :path => 'm:language' do |n|
|
208
|
+
n.value :path => 'm:languageTerm', :accessor => :text
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
mods_ng_xml.nom!
|
214
|
+
|
215
|
+
mods_ng_xml
|
216
|
+
end # set_terminology_ns
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|